package
{
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.ui.Keyboard;
	import flash.utils.setTimeout;
	
	import game.Achieve;
	import game.Board;
	import game.Enemy;
	import game.Food;
	import game.Ground;
	import game.Help;
	import game.Panda;
	import game.Scene;
	import game.Shoots;
	import game.Smoke;
	
	import iflash.method.bind;
	
	import interf.FpsGame;
	import interf.ICtrl;
	import interf.ISteper;
	
	import sound.DeadSound;
	
	import ui.About;
	import ui.GameOver;
	import ui.GameRank;
	import ui.GameSound;
	import ui.GameUI;
	import ui.Store;
	import ui.Welcome;
	
	import vo.Mem;
	import vo.frameDelay;
	import vo.gameTime;
	
	[SWF(width="800",height="500",backgroundColor="#83e8ff")]
	public class Game extends Sprite implements ISteper, ICtrl
	{
		
		public function Game()
		{
			super();
			
			if(stage)
				init();
			else
				addEventListener(Event.ADDED_TO_STAGE, init);
			
		}
		
		private function init(event:Event = null):void
		{
			IFlash.setSize(800, 500); //设置场景尺寸
			IFlash.setOrientationEx(1); //是否为横屏模式
			IFlash.setBgcolor("#83e8ff"); //背景色
			IFlash.showInfo(true); //是否显示帧率
			
			var loader:Loader = new Loader();
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, initGame);
			loader.load(new URLRequest("assets/pandaRun.swf"), new LoaderContext(false, ApplicationDomain.currentDomain));
			
		}
		
		private function initGame(event:Event):void {
			var i:* = 0;
			stage.scaleMode = StageScaleMode.EXACT_FIT;
			Board.init();
			Panda.init();
			Food.init();
			Enemy.init();
			Smoke.init();
			Help.init();
			this.panda = new Panda();
			this.scene = new Scene();
			this.board = new Board(Mem.numBoards);
			this.food = new Food(Mem.numFoods);
			this.enemy = new Enemy(Mem.numEnemys);
			this.shoots = new Shoots(Mem.numShoots);
			this.ground = new Ground();
			this.smoke = new Smoke(Mem.numSmoke);
			this.gui = new GameUI(this.goStart);
			this.help = new Help(this.goStart);
			this.achieve = new Achieve(this.goStart);
			this.welcome = new Welcome(this.goPlay, this.goRank, this.goStore, this.goHelp, this.goAbout, this.goAcv);
			this.over = new GameOver(this.goPlay, this.goStore, this.goStart);
			this.store = new Store(this.goPlay, this.goStart);
			this.about = new About(this.goStart);
			this.rank = new GameRank(this.goStart);
			this.core = new <ISteper>[this.panda, this.scene, this.enemy, this.board, this.food, this.shoots, this.ground, this.gui, this.smoke, this.help, this.achieve];
			this.data = new Data();
			this.data.load();
			this.sound1 = new GameSound();
			this.panda.numBamboo = this.data.bamboo;
			this.panda.mallShoots = this.data.shoots;
			this.panda.numMilk = Math.max(1, this.data.milk);
			this.panda.numAmulet = Math.max(1, this.data.amulet);
			this.panda.consumption = this.data.consumption;
			this.panda.sound1 = this.sound1;
			this.panda.data = this.data;
			this.scene.buildSpdUpBmp();
			this.scene.panda = this.panda;
			this.scene.board = this.board;
			this.scene.food = this.food;
			this.scene.enemy = this.enemy;
			this.gui.panda = this.panda;
			this.gui.sound1 = this.sound1;
			this.store.panda = this.panda;
			this.store.data = this.data;
			this.over.panda = this.panda;
			this.over.data = this.data;
			this.rank.data = this.data;
			this.board.reset(0, 10);
			this.panda.init(this.board, this.food, this.enemy, this.shoots, this.ground, this.scene);
			this.ground.scene = this.scene;
			this.ground.startAlone();
			this.ground.showAs(this);
			this.help.scene = this.scene;
			this.help.panda = this.panda;
			this.achieve.panda = this.panda;
			this.achieve.data = this.data;
			i = 0;
			while (i < Mem.numBoards)
			{
				this.board.showAs(this.scene.dpoc);
				this.board = this.board.next;
				i++;
			}
			i = 0;
			while (i < Mem.numFoods)
			{
				this.food.showAs(this.scene.dpoc);
				this.food = this.food.next;
				i++;
			}
			i = 0;
			while (i < Mem.numEnemys)
			{
				this.enemy.showAs(this.scene.dpoc);
				this.enemy = this.enemy.next;
				i++;
			}
			i = 0;
			while (i < Mem.numShoots)
			{
				this.shoots.enemy = this.enemy;
				this.shoots.showAs(this.scene.dpoc);
				this.shoots = this.shoots.next;
				i++;
			}
			i = 0;
			while (i < Mem.numSmoke)
			{
				this.panda.smoke = this.smoke;
				this.smoke.showAs(this.scene.dpoc);
				this.smoke = this.smoke.next;
				i++;
			}
			this.panda.showAs(this.scene.dpoc);
			this.scene.dpoc.visible = false;
			addChild(this.scene.dpoc);
			this.achieve.showAs(this);
			this.gui.showAs(this);
			this.gui.welcome = this.welcome;
			this.store.showAs(this);
			this.help.showAs(this);
			this.rank.showAs(this);
			this.about.showAs(this);
			this.welcome.showAs(this);
			this.over.showAs(this);
			this.goStart();
			this.engine = new FpsGame(this, this);
			this.gui.engine = this.engine;
			this.help.engine = this.engine;
		}
		
		public static const HelpModel:int = 0;
		
		public static const RandomModel:int = 1;
		
		public static const overSound:DeadSound = new DeadSound();
		
		private var core:Vector.<ISteper>;
		
		private var enemy:Enemy;
		
		private var board:Board;
		
		private var food:Food;
		
		private var panda:Panda;
		
		private var shoots:Shoots;
		
		private var scene:Scene;
		
		private var ground:Ground;
		
		private var smoke:Smoke;
		
		private var help:Help;
		
		private var achieve:Achieve;
		
		private var gui:GameUI;
		
		private var welcome:Welcome;
		
		private var over:GameOver;
		
		private var store:Store;
		
		private var rank:GameRank;
		
		private var about:About;
		
		private var data:Data;
		
		private var sound1:GameSound;
		
		private var engine:FpsGame;
		
		private function goPlay():void
		{
			this.achieve.open();
			this.gameStart();
			this.scene.normalUpdate();
		}
		
		private function goStart():void
		{
			this.gui.visible = false;
			this.scene.dpoc.visible = false;
			this.about.visible = false;
			this.welcome.visible = true;
			this.ground.auto = true;
			this.ground.startAlone();
			this.sound1.stopBGSound();
		}
		
		private function goRank():void
		{
			this.scene.dpoc.visible = false;
			this.welcome.visible = false;
			this.about.visible = false;
			this.rank.visible = true;
			this.rank.show();
		}
		
		private function goStore():void
		{
			this.scene.dpoc.visible = false;
			this.welcome.visible = false;
			this.about.visible = false;
			this.store.show();
		}
		
		private function goHelp():void
		{
			this.achieve.close();
			this.help.start();
			this.gameStart();
			setTimeout(bind(stage, stage.addEventListener), 100, MouseEvent.MOUSE_UP, bind(this.help, this.help.next));
		}
		
		private function goAbout():void
		{
			this.scene.dpoc.visible = false;
			this.welcome.visible = false;
			this.about.visible = true;
		}
		
		private function goAcv():void
		{
			this.scene.dpoc.visible = false;
			this.welcome.visible = false;
			this.achieve.showPanel();
		}
		
		private var _max:int;
		
		public function get max():int
		{
			return this._max;
		}
		
		public function step():void
		{
			var i:* = 0;
			var o:ISteper = null;
			frameDelay = this.engine.delay / 1000;
			gameTime = this.engine.currTime;
			var len:int = this.core.length;
			for each (o in this.core)
			{
				o.step();
			}
			if (this.panda.rect.y > 680)
			{
				this.gameOver();
			}
		}
		
		public function gameStart():void
		{
			this.about.visible = false;
			this.welcome.visible = false;
			this.gui.visible = true;
			this.scene.dpoc.visible = true;
			this.ground.auto = false;
			this.ground.stopAlone();
			this.ground.normal();
			this.achieve.reset();
			this.panda.start();
			this.engine.start();
			this.gui.startInit(this.panda.numAmulet, this.panda.numShoots, this.panda.numMilk);
			this.sound1.playBGSound();
		}
		
		public function gameOver():void
		{
			if (this.help.helping)
			{
				this.help.retry();
			}
			else
			{
				this.gui.visible = false;
				this.over.show();
				this.sound1.stopBGSound();
			}
			this.engine.stop();
			this.ground.auto = true;
			this.panda.over();
			this.panda.board = this.scene.nextBoard();
			overSound.play();
			this.sound1.stopFlySound();
		}
		
		private var half:int = 800;
		
		private var prevMouseX:int = 0;
		
		private var fullScreenCtrlA:Boolean = false;
		
		private function ctrl(e:MouseEvent):void
		{
			if ((e.stageX < 75) && (e.stageY < 65))
			{
				this.pause();
			}
			else if (this.fullScreenCtrlA)
			{
				switch (e.type)
				{
					case MouseEvent.MOUSE_DOWN: 
						this.ctrlA();
						break;
					case MouseEvent.MOUSE_UP: 
						this.cancelA();
						break;
				}
			}
			else
			{
				switch (e.type)
				{
					case MouseEvent.MOUSE_DOWN: 
						if (this.half > e.stageX)
						{
							this.ctrlA();
						}
						else
						{
							this.ctrlB();
						}
						this.prevMouseX = e.stageX;
						break;
					case MouseEvent.MOUSE_UP: 
						if (this.half > e.stageX)
						{
							this.cancelA();
						}
						else
						{
							this.cancelB();
						}
						break;
					case MouseEvent.MOUSE_MOVE: 
						if ((this.half > e.stageX) && (this.half < this.prevMouseX))
						{
							this.ctrlA();
							this.cancelB();
						}
						else if ((this.half < e.stageX) && (this.half > this.prevMouseX))
						{
							this.ctrlB();
							this.cancelA();
						}
						
						this.prevMouseX = e.stageX;
						break;
				}
			}
		
		}
		
		public function ctrlA():void
		{
			this.panda.a();
			this.gui.a();
		}
		
		public function ctrlB():void
		{
			this.panda.b();
			this.gui.b();
		}
		
		public function cancelA():void
		{
			this.panda.ca();
			this.gui.ca();
		}
		
		public function cancelB():void
		{
			this.panda.cb();
			this.gui.cb();
		}
		
		private function keyCtrl(e:KeyboardEvent):void
		{
			if (e.keyCode == Keyboard.HOME)
			{
				this.pause();
			}
			else if (e.keyCode == Keyboard.BACK)
			{
				this.pause();
				//NativeApplication.nativeApplication.exit();//fix by layaFlash
			}
			else
			{
				this.panda.b();
			}
		
		}
		
		public function ctrlStart():void
		{
			stage.addEventListener(MouseEvent.MOUSE_DOWN, this.ctrl);
			stage.addEventListener(MouseEvent.MOUSE_UP, this.ctrl);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, this.keyCtrl);
			stage.addEventListener(Event.DEACTIVATE, this.onDeactivate);
		}
		
		public function ctrlPause():void
		{
			stage.removeEventListener(MouseEvent.MOUSE_DOWN, this.ctrl);
			stage.removeEventListener(MouseEvent.MOUSE_UP, this.ctrl);
			stage.removeEventListener(KeyboardEvent.KEY_DOWN, this.keyCtrl);
			stage.removeEventListener(Event.DEACTIVATE, this.onDeactivate);
		}
		
		private function onDeactivate(e:Event):void
		{
			this.pause();
		}
		
		public function pause():void
		{
			if (this.help.helping)
			{
				return;
			}
			this.engine.pause();
			this.gui.pause();
			this.sound1.stopBGSound();
			this.sound1.stopFlySound();
		}
	}
}
