package game
{
   import interf.ISteper;
   import flash.display.BitmapData;
   import flash.geom.Rectangle;
   import flash.display.Bitmap;
   import flash.display.DisplayObjectContainer;
   import flash.geom.Point;
   
   public class Board extends Object implements ISteper
   {
      
      public function Board(max:uint = 1, frist:Boolean = true)
      {
         var p:Board = null;
         super();
         this._max = max;
         if(frist)
         {
            p = this;
            while(--max > 0)
            {
               p._next = new Board(max,false);
               p = p._next;
            }
            p._next = this;
         }
      }
      
      private static var BoardBmp:Class = Board_BoardBmp;
      
      public static const src:BitmapData = new BoardBmp().bitmapData;
      
      public static const y_base:int = 280;
      
      public static const y_unit:int = 40;
      
      public static const y_limit:int = 4;
      
      public static const img_height:int = 75;
      
      public static const marginal:int = 15;
      
      public static const unit:int = 150;
      
      public static const limit:int = 13;
      
      public static const space_unit:int = 50;
      
      public static const space_min:int = 3;
      
      public static const space_max:int = 14;
      
      public static const max:int = marginal * 2 + unit * limit;
      
      private static const _bitmapData:Vector.<BitmapData> = new Vector.<BitmapData>();
      
      public static function init() : void
      {
         var i:int = 0;
         while(i < limit)
         {
            _bitmapData.push(new BitmapData(marginal * 2 + unit * i,img_height));
            i++;
         }
      }
      
      private var _next:Board;
      
      public function get next() : Board
      {
         return this._next;
      }
      
      public const rect:Rectangle = new Rectangle();
      
      private var _max:int;
      
      public function get max() : int
      {
         return this._max;
      }
      
      private var _space:int;
      
      public function get right() : int
      {
         return this._space + this.rect.right;
      }
      
      public const dpo:Bitmap = new Bitmap();
      
      public function showAs(dpoc:DisplayObjectContainer) : void
      {
         dpoc.addChild(this.dpo);
      }
      
      private var shakePre:Number;
      
      private var shakeY:Number;
      
      public var shaking:Boolean;
      
      public function step() : void
      {
         var board:Board = this;
         var i:int = 0;
         while(i < this._max)
         {
            board.shakeEffect();
            board = board.next;
            i++;
         }
      }
      
      public var enemy:Enemy;
      
      private function shakeEffect() : void
      {
         if(this.shaking)
         {
            if(this.shakePre < Math.PI)
            {
               this.shakePre = Math.min(Math.PI,this.shakePre + 0.35);
               this.dpo.y = this.rect.y = this.shakeY + 15 * Math.sin(this.shakePre);
               if((!(this.enemy == null)) && (this.enemy.type == Enemy.Snake))
               {
                  this.enemy.dpo.y = this.rect.y - this.enemy.rect.height;
               }
            }
            else
            {
               this.shaking = false;
            }
         }
      }
      
      public function shake() : void
      {
         this.shaking = true;
         this.shakePre = 0;
         this.shakeY = this.rect.y;
      }
      
      public function reset(x:int, w:int) : void
      {
         if(w > 0)
         {
            this.buildData(x,w);
            this.buildBitmap(w);
            this.updateView();
         }
      }
      
      public function resetForHelp(x:int, y:int) : void
      {
         this.rect.x = x;
         this.rect.y = y;
         this.rect.width = marginal * 2 + (limit - 1) * unit;
         this._space = 0;
         this.buildBitmap(limit - 1);
         this.updateView();
      }
      
      private function updateView() : void
      {
         this.dpo.x = this.rect.x;
         this.dpo.y = this.rect.y;
      }
      
      private function buildData(x:int, w:int) : void
      {
         this.rect.y = y_base + int(Math.random() * y_limit) * y_unit;
         this.rect.x = x;
         this.rect.width = marginal * 2 + w * unit;
         this._space = (int(Math.random() * (space_max - space_min)) + space_min) * space_unit;
      }
      
      private function buildBitmap(w:int) : void
      {
         this.dpo.bitmapData = _bitmapData[w];
         var bitmapData:BitmapData = this.dpo.bitmapData;
		 if(bitmapData.getPixel(0,0) == 0)
		 {
			 return;
		 }
         var rect:Rectangle = new Rectangle();
         var point:Point = new Point();
         bitmapData.lock();
         rect.height = img_height;
         rect.width = marginal;
         rect.x = 0;
         point.x = 0;
         bitmapData.copyPixels(src,rect,point);
         rect.x = unit * 3 + marginal;
         point.x = marginal + w * unit;
         bitmapData.copyPixels(src,rect,point);
         rect.width = unit;
         var i:int = 0;
         while(i < w)
         {
            point.x = i * unit + marginal;
            rect.x = unit * int(Math.random() * 3) + marginal;
            bitmapData.copyPixels(src,rect,point);
            i++;
         }
         bitmapData.unlock();
      }
   }
}
