var Matrix = {};

(function()
{
   var $ctx = null,
      HEIGHT = 0,
      WIDTH = 0,
      CHARACTER_X = 50,
      CHARACTER_Y = 58;
   
   Matrix.Main = function()
   {
      this.MAX_LINES = 40;
      this.MIN_LINE_LENGTH = 8;
      this.MAX_LINE_LENGTH = 32;
      this.images = {};
      this.arrImages = [];
      this.lines = [];
   };
   
   Matrix.Main.prototype =
   {
      init: function()
      {
         var scope = this;
         document.addEventListener("DOMContentLoaded", function()
         {
            scope.onReady.apply(scope, arguments)
         }, false);
      },
      
      onReady: function()
      {
         document.removeEventListener("DOMContentLoaded", this.onReady, false);
         
         var canvas = document.getElementById("canvas");
         $ctx = canvas.getContext("2d");
         HEIGHT = canvas.height;
         WIDTH = canvas.width = document.width;

         this.images =
         {
            green: document.getElementById("imgGreen"),
            white: document.getElementById("imgWhite")
         };
         
         this.arrImages = [this.images.green, this.images.white];
         
         Util.startTick(30, this, this.onTick);
      },
      
      onTick: function()
      {
         var i, ii, j, jj,
            line, chr, chrLen, y,
            xScale, yScale, ySpacing,
            arrImageLen = this.arrImages.length - 1;
         
         if (this.lines.length < this.MAX_LINES)
         {
            this.lines.push(this.newLine());
         }
         
         $ctx.fillStyle = "rgba(0,0,0,0.5)";
         $ctx.fillRect(0, -50, WIDTH, HEIGHT + 50);

         for (var i = 0, ii = this.lines.length; i < ii; i++)
         {
            line = this.lines[i];
            xScale = CHARACTER_X * line.scale;
            yScale = CHARACTER_Y * line.scale;
            ySpacing = 0;
            chrLen = line.characters.length;
            line.yOffset += line.ySpeed;

            if (chrLen < Math.floor(line.yOffset / yScale) && chrLen < line.len)
            {
               line.characters.push(this.newCharacter());
            }

            // $ctx.save();
            
            for (j = 0, jj = chrLen; j < jj; j++)
            {
               chr = line.characters[j];
               y = line.yStart + line.yOffset - ySpacing;
               ySpacing += yScale;
               
               $ctx.drawImage(this.arrImages[chr.image], chr.x, chr.y, CHARACTER_X, CHARACTER_Y, line.xStart, y, xScale, yScale);
               
               if (chr.dynamic || j == 0)
               {
                  if (chr.dynamicWait++ > 10)
                  {
                     line.characters[j] = this.newCharacter();
                     line.characters[j].image = 1;
                     line.characters[j].dynamic = true;
                     line.characters[j].dynamicWait = 0;
                  }
               }
               
               if (j == line.len - 1 && y > HEIGHT)
               {
                  this.lines[i] = this.newLine();
               }
            }
            
            // $ctx.restore();
         }
      },
      
      newLine: function()
      {
         var line =
         {
            xStart: Util.randomInt(0, WIDTH),
            yStart: Util.randomInt(0, HEIGHT / 8) - 200,
            yOffset: 0,
            scale: Util.randomInt(2, 10) / 10.0,
            len: Util.randomInt(this.MIN_LINE_LENGTH, this.MAX_LINE_LENGTH),
            characters: []
         };
         line.ySpeed = line.scale * 10 + Util.randomInt(0, 5);
         return line;
      },
      
      newCharacter: function()
      {
         var chr = Util.randomInt(0, 55);
         return (
         {
            image: 0,
            x: (chr % 10) * CHARACTER_X,
            y: (Math.floor(chr / 10) * CHARACTER_Y),
            dynamic: Util.randomInt(0, 10) == 0,
            dynamicWait: 0
         });
      }
   };
})();