package game
{
   import interf.ISteper;
   import flash.display.BitmapData;
   import flash.geom.Rectangle;
   import flash.geom.Point;
   import flash.display.DisplayObjectContainer;
   import flash.display.Bitmap;
   import vo.gameTime;
   
   public class Enemy extends Object implements ISteper
   {
      
      public function Enemy(max:int = -1)
      {
         super();
         var p:Enemy = null;
         this.probability = new <Number>[0.8,0.9,0.97,0.985,1];
         this.effBmp = new Bitmap();
         this.clearBmp = new Bitmap();
         this._max = max;
         if(max > 0)
         {
            p = this;
            while(--max > 0)
            {
               p._next = new Enemy();
               p = p._next;
            }
            p._next = this;
         }
         this.reset(0,0);
      }
      
      public static const Snake:int = 0;
      
      public static const Raven:int = 1;
      
      public static const Bomb:int = 2;
      
      public static const numTypes:int = 3;
      
      private static var MonsterBmp:Class = Enemy_MonsterBmp;
      
      public static const src:BitmapData = new MonsterBmp().bitmapData;
      
      private static const snakeBmpds:Vector.<BitmapData> = new Vector.<BitmapData>();
      
      private static const ravenBmpds:Vector.<BitmapData> = new Vector.<BitmapData>();
      
      private static const bombBmpds:Vector.<BitmapData> = new Vector.<BitmapData>();
      
      private static const _bitmapData:Vector.<Vector.<BitmapData>> = new <Vector.<BitmapData>>[snakeBmpds,ravenBmpds,bombBmpds];
      
      private static var EffBmp:Class = Enemy_EffBmp;
      
      public static const effSrc:BitmapData = new EffBmp().bitmapData;
      
      private static const bombEffBmpds:Vector.<BitmapData> = new Vector.<BitmapData>();
      
      private static const numFrames:int = 3;
      
      public static function init() : void
      {
         var i:* = 0;
         var j:* = 0;
         var bmpd:BitmapData = null;
         var rect:Rectangle = new Rectangle(0,0,76,78);
         var dest:Point = new Point();
         i = 0;
         while(i < numTypes)
         {
            rect.y = rect.height * i;
            j = 0;
            while(j < numFrames)
            {
               rect.x = rect.width * j;
               bmpd = new BitmapData(rect.width,rect.height);
               bmpd.copyPixels(src,rect,dest);
               _bitmapData[i].push(bmpd);
               j++;
            }
            i++;
         }
         rect.width = 108;
         rect.height = 95;
         rect.x = rect.y = 0;
         i = 0;
         while(i < 4)
         {
            bmpd = new BitmapData(rect.width,rect.height);
            rect.x = rect.width * i;
            bmpd.copyPixels(effSrc,rect,dest);
            bombEffBmpds.push(bmpd);
            i++;
         }
      }
      
      private var _type:int;
      
      public function get type() : int
      {
         return this._type;
      }
      
      private var _next:Enemy;
      
      public function get next() : Enemy
      {
         return this._next;
      }
      
      public const rect:Rectangle = new Rectangle(0,0,76,78);
      
      private var _max:int = 1;
      
      public function get max() : int
      {
         return this._max;
      }
      
      public function step() : void
      {
         var enemy:Enemy = this;
         var i:int = 0;
         while(i < this._max)
         {
            enemy.updateBitmapData();
            enemy.effStep();
            enemy = enemy.next;
            i++;
         }
      }
      
      public var isBruised:Boolean;
      
      public function bruise() : void
      {
         this.isBruised = true;
         this.disappearEff();
      }
      
      public function showAs(dpoc:DisplayObjectContainer) : void
      {
         dpoc.addChild(this.dpo);
         dpoc.addChild(this.effBmp);
         dpoc.addChild(this.clearBmp);
      }
      
      public function reset(x:int, boradY:int) : void
      {
         this.rect.x = x;
         this.rect.y = boradY - this.rect.height;
         this.buildData();
         this.buildBitmap();
      }
      
      public function resetForHelp(x:int, boradY:int) : void
      {
         this.rect.x = x + 800;
         this.rect.y = boradY - this.rect.height;
         this._type = int(Math.random() * 3);
         this.isBruised = false;
         this.buildBitmap();
      }
      
      private var probability:Vector.<Number>;
      
      private function buildData() : void
      {
         switch(null)
         {
            case Raven:
               this.rect.y = this.rect.y - 150;
               break;
            case Bomb:
               this.rect.y = this.rect.y - int(Math.random() * 3) * 150;
               break;
         }
         this.isBruised = false;
      }
      
      public const dpo:Bitmap = new Bitmap();
      
      private function buildBitmap() : void
      {
         this.dpo.bitmapData = _bitmapData[this.type][0];
         this.dpo.x = this.rect.x;
         this.dpo.y = this.rect.y;
         this.dpo.visible = true;
         this.effBmp.x = this.rect.x - 20;
         this.effBmp.y = this.rect.y - 10;
         this.effBmp.visible = false;
         this.clearBmp.x = this.rect.x - 25;
         this.clearBmp.y = this.rect.y - 24;
         this.clearBmp.visible = false;
      }
      
      private var effStart:int;
      
      private function disappearEff() : void
      {
         if(this._type == Bomb)
         {
            this.dpo.visible = false;
         }
         this.effBmp.visible = true;
         this.effStart = gameTime;
      }
      
      private var effBmp:Bitmap;
      
      private function updateBitmapData() : void
      {
         var frame:* = 0;
         this.dpo.bitmapData = _bitmapData[this.type][int(gameTime / 83.3) % 3];
         if(this.effBmp.visible)
         {
            if(this._type == Bomb)
            {
               frame = int((gameTime - this.effStart) / 50);
               if(frame > 3)
               {
                  this.effBmp.visible = false;
                  this.dpo.visible = false;
               }
               else
               {
                  this.effBmp.bitmapData = bombEffBmpds[frame];
               }
            }
            else
            {
               this.effBmp.visible = false;
            }
         }
      }
      
      private var clearTime:int;
      
      private var effecting:Boolean;
      
      private var clearBmp:Bitmap;
      
      public function clear() : void
      {
         this.isBruised = true;
         this.dpo.visible = false;
         this.clearBmp.visible = true;
         this.effecting = true;
         this.clearTime = gameTime;
      }
      
      private function effStep() : void
      {
         if(!this.effecting)
         {
            return;
         }
         var frame:int = int((gameTime - this.clearTime) / 17.8);//add by LayaFlash, 需要整数时强制转换
         if(frame < 0)
         {
            return;
         }
         if(frame < 3)
         {
            this.clearBmp.bitmapData = Food.getEffBmpds(frame);
         }
         else
         {
            this.clearBmp.alpha = 1 - 0.2 * (frame - 3);
         }
         if(frame > 8)
         {
            this.clearBmp.visible = this.effecting = false;
         }
      }
   }
}
