package  
{
	import net.flashpunk.graphics.Text;
	import net.flashpunk.utils.Draw;
	import net.flashpunk.World;
	import net.flashpunk.utils.Input;
	import net.flashpunk.utils.Draw;
	import net.flashpunk.Sfx;
	
	/**
	 * ...
	 * @author Benn
	 */
	public class GameWorld extends World 
	{
		
		[Embed(source = '../assets/levels/level1.oel', mimeType = 'application/octet-stream')] private static const LEVEL1:Class;
		[Embed(source = '../assets/levels/level2.oel', mimeType = 'application/octet-stream')] private static const LEVEL2:Class;
		[Embed(source = '../assets/levels/level3.oel', mimeType = 'application/octet-stream')] private static const LEVEL3:Class;
		[Embed(source = '../assets/levels/level4.oel', mimeType = 'application/octet-stream')] private static const LEVEL4:Class;
		[Embed(source = '../assets/levels/level5.oel', mimeType = 'application/octet-stream')] private static const LEVEL5:Class;
		[Embed(source = '../assets/levels/level6.oel', mimeType = 'application/octet-stream')] private static const LEVEL6:Class;
		[Embed(source = '../assets/levels/level7.oel', mimeType = 'application/octet-stream')] private static const LEVEL7:Class;
		[Embed(source = '../assets/levels/level8.oel', mimeType = 'application/octet-stream')] private static const LEVEL8:Class;
		[Embed(source = '../assets/levels/level9.oel', mimeType = 'application/octet-stream')] private static const LEVEL9:Class;
		[Embed(source = '../assets/levels/level10.oel', mimeType = 'application/octet-stream')] private static const LEVEL10:Class;
		[Embed(source = '../assets/levels/level11.oel', mimeType = 'application/octet-stream')] private static const LEVEL11:Class;
		[Embed(source = '../assets/levels/level12.oel', mimeType = 'application/octet-stream')] private static const LEVEL12:Class;
		[Embed(source = '../assets/levels/level13.oel', mimeType = 'application/octet-stream')] private static const LEVEL13:Class;
		[Embed(source = '../assets/levels/level14.oel', mimeType = 'application/octet-stream')] private static const LEVEL14:Class;
		[Embed(source = '../assets/levels/level15.oel', mimeType = 'application/octet-stream')] private static const LEVEL15:Class;
		
		[Embed(source = '../assets/sound/music.mp3')] private static const MUSIC:Class;
		
		private var music:Sfx = new Sfx(MUSIC);
		
		private var Levels:Array = [];
		
		private var GameText:Array = [];
		
		private var LevelCounter:int = 0;
		
		public var GamePlayer:Player;
		
		public var Blocks:Array = [];
		
		public var BlockStoppers:Array = [];
		
		public var Lasers:Array = [];
		
		public var _finalbeam:FinalBeam;
		
		public var CurrentLevel:Level;
		
		public var GameOver:Boolean = false;
		
		public var _beambackground:BeamBackground;
		public var _kittybackground:KittyBackground;
		public var _playerbackground:PlayerBackground;
		public var _finalbackground:FinalBackground;
		
		public function LoadLevels():void
		{
			
			Levels.push(new Level(LEVEL1));
			Levels.push(new Level(LEVEL2));
			Levels.push(new Level(LEVEL3));
			Levels.push(new Level(LEVEL4));
			Levels.push(new Level(LEVEL5));
			Levels.push(new Level(LEVEL6));
			Levels.push(new Level(LEVEL7));
			Levels.push(new Level(LEVEL8));
			Levels.push(new Level(LEVEL9));
			Levels.push(new Level(LEVEL10));
			Levels.push(new Level(LEVEL11));
			Levels.push(new Level(LEVEL12));
			Levels.push(new Level(LEVEL13)); 
			Levels.push(new Level(LEVEL14)); 
			Levels.push(new Level(LEVEL15)); 
			
		}
		
		public function ClearBlocks():void
		{
			var length:int = Blocks.length;
			
			for (var i:int = 0; i < length; i++) 
			{
				remove(Blocks[i]);
			}
			
			for (var ii:int = 0; ii < length; ii++) 
			{
				Blocks.pop();
			}
			
			length = BlockStoppers.length;
			
			for (i = 0; i < length; i++) 
			{
				remove(BlockStoppers[i]);
			}
			
			for (ii = 0; ii < length; ii++) 
			{
				BlockStoppers.pop();
			}
			
		}
		
		public function LoadBlocks():void
		{
			
			var dataList:XMLList;
			var dataElement:XML;
			
			dataList = CurrentLevel.LevelData.objects.Block;
			for each (dataElement in dataList)
			{
				
				var NewBlock:Block = new Block(0);
				
				add(NewBlock);
				
				NewBlock.x = int(dataElement.@x);
				NewBlock.y = int(dataElement.@y);
				
				Blocks.push(NewBlock);
			}
			
			dataList = CurrentLevel.LevelData.objects.BlockLarge;
			for each (dataElement in dataList)
			{
				
				var LargeBlock:Block = new Block(1);
				
				add(LargeBlock);
				
				LargeBlock.x = int(dataElement.@x);
				LargeBlock.y = int(dataElement.@y);
				
				Blocks.push(LargeBlock);
			}
			
			dataList = CurrentLevel.LevelData.objects.BlockWide;
			for each (dataElement in dataList)
			{
				
				var WideBlock:Block = new Block(2);
				
				add(WideBlock);
				
				WideBlock.x = int(dataElement.@x);
				WideBlock.y = int(dataElement.@y);
				
				Blocks.push(WideBlock);
			}
			
			dataList = CurrentLevel.LevelData.objects.BlockTall;
			for each (dataElement in dataList)
			{
				
				var TallBlock:Block = new Block(3);
				
				add(TallBlock);
				
				TallBlock.x = int(dataElement.@x);
				TallBlock.y = int(dataElement.@y);
				
				Blocks.push(TallBlock);
			}
			
			dataList = CurrentLevel.LevelData.objects.BlockStoppers;
			for each (dataElement in dataList)
			{
				
				var NewStopper:BlockStopper = new BlockStopper;
				
				add(NewStopper);
				
				NewStopper.x = int(dataElement.@x);
				NewStopper.y = int(dataElement.@y);
				
				BlockStoppers.push(NewStopper);
			}
			
		}
		
		public function ClearLasers():void
		{
			var length:int = Lasers.length;
			
			for (var i:int = 0; i < length; i++) 
			{
				Lasers[i].DeactivateBeam();
				remove(Lasers[i]);
			}
			
			for (var ii:int = 0; ii < length; ii++) 
			{
				Lasers.pop();
			}
		}
		
		public function LoadLasers():void
		{
			
			var dataList:XMLList;
			var dataElement:XML;
			
			dataList = CurrentLevel.LevelData.objects.LaserLeft;
			for each (dataElement in dataList)
			{
				
				var LeftLaser:Laser = new Laser(0);
				
				add(LeftLaser);
				
				LeftLaser.x = int(dataElement.@x);
				LeftLaser.y = int(dataElement.@y);
				
				LeftLaser.ActivateBeam();
				
				Lasers.push(LeftLaser);
			}
			
			dataList = CurrentLevel.LevelData.objects.LaserRight;
			for each (dataElement in dataList)
			{
				
				var RightLaser:Laser = new Laser(1);
				
				add(RightLaser);
				
				RightLaser.x = int(dataElement.@x);
				RightLaser.y = int(dataElement.@y);
				
				RightLaser.ActivateBeam();
				
				Lasers.push(RightLaser);
			}
			
			dataList = CurrentLevel.LevelData.objects.LaserDown;
			for each (dataElement in dataList)
			{
				
				var DownLaser:Laser = new Laser(2);
				
				add(DownLaser);
				
				DownLaser.x = int(dataElement.@x);
				DownLaser.y = int(dataElement.@y);
				
				DownLaser.ActivateBeam();
				
				Lasers.push(DownLaser);
			}
			
		}
		
		public function LookForFinalBeam():void
		{
			
			var dataList:XMLList;
			var dataElement:XML;
			
			dataList = CurrentLevel.LevelData.objects.FinalBeam;
			for each (dataElement in dataList)
			{
				_finalbeam = new FinalBeam;
				_finalbeam.x = int(dataElement.@x);
				_finalbeam.y = int(dataElement.@y);
				
				add(_finalbeam);
			}
			
		}
		
		public function LoadPlayer():void
		{
			
			var dataList:XMLList;
			var dataElement:XML;
			
			dataList = CurrentLevel.LevelData.objects.Player;
			for each (dataElement in dataList)
			{
				GamePlayer.x = int(dataElement.@x) + 16;
				GamePlayer.y = int(dataElement.@y) + 16;
			}
		
			GamePlayer.SetSpawnLocation(GamePlayer.x, GamePlayer.y);
			
			add(GamePlayer);
			
		}
		
		public function GameWorld() 
		{
			
			music.loop();
			
			LoadLevels();
			
			GamePlayer = new Player;
		
			CurrentLevel = Levels[LevelCounter];
			
			add(CurrentLevel);
			
			LoadPlayer();
				
			ClearBlocks();
			
			LoadBlocks();
			
			ClearLasers();
			
			LoadLasers();
			
			LoadLevelText();
			
		}
		
		override public function update():void 
		{
			
			if (GamePlayer.IsGameOver)
			{
				if (!GameOver)
				{
					
					LevelCounter++;
					
					CurrentLevel.ResetMask();
					
					remove(CurrentLevel);
				
					remove(GamePlayer);
					
					remove(_finalbeam);
					
					_finalbackground = new FinalBackground;
					
					add(_finalbackground);
					
					_kittybackground = new KittyBackground;
					
					add(_kittybackground);
					
					_playerbackground = new PlayerBackground;
					
					add(_playerbackground);
					
					_beambackground = new BeamBackground;
					
					add(_beambackground);
					
					LoadLevelText();
					
					GameOver = true;
					
				}
				
				super.update();
				
				return;
			}
			
			if (Input.mousePressed)
			{
				var GrabBlock:Block = collidePoint("block", Input.mouseX, Input.mouseY) as Block
				{
					if (GrabBlock)
					{
						GrabBlock.SetBeingHeld(true);
						GrabBlock.SetHeldLocation(Input.mouseX, Input.mouseY);
						GamePlayer.SetPlayerMovingObject(true);
					}
				}
			}
			
			if (Input.mouseReleased)
			{
				var length:int = Blocks.length;
			
				for (var i:int = 0; i < length; i++) 
				{
					
					if (Blocks[i].CanBeDropped)
					{
						Blocks[i].SetBeingHeld(false);
						GamePlayer.SetPlayerMovingObject(false);
					}
				}		
			}
			
			if (GamePlayer.IsOutOfBounds())
			{
				
				LevelCounter++;
				
				CurrentLevel.ResetMask();
				
				CurrentLevel = Levels[LevelCounter];
				
				remove(CurrentLevel);
				
				add(CurrentLevel);
				
				remove(GamePlayer);
				
				LoadPlayer();
				
				ClearBlocks();
				
				LoadBlocks();
				
				ClearLasers();
				
				LoadLasers();
				
				LoadLevelText();
				
				LookForFinalBeam();
				
			}
			
			super.update();
		}
		
		public function ClearLevelText():void
		{
			
			var length:int = GameText.length;
			
			for (var i:int = 0; i < length; i++) 
			{
				remove(GameText[i]);
			}
			
			for (var ii:int = 0; ii < length; ii++) 
			{
				GameText.pop();
			}
			
		}
		
		public function LoadLevelText():void
		{
			
			ClearLevelText();
			
			var NewText:InGameText;
			
			switch (LevelCounter)
			{
				
				case 0:
				
				NewText = new InGameText("Hello.", 0);
				
				NewText.x = 50;
				NewText.y = 50;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("You are the last survivor of your species.", 1);
				
				NewText.x = 50;
				NewText.y = 100;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("...I'm sorry.", 2);
				
				NewText.x = 50;
				NewText.y = 150;
				
				add(NewText);
				
				GameText.push(NewText);
				
				break;
				
				case 1:
				
				NewText = new InGameText("The only way we could save you was to", 0);
				
				NewText.x = 210;
				NewText.y = 50;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("rearrange your DNA and hide your true", 0.25);
				
				NewText.x = 210;
				NewText.y = 75;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("form.", 0.5);
				
				NewText.x = 210;
				NewText.y = 100;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("Unfortunately, some damage was caused", 1.5);
				
				NewText.x = 210;
				NewText.y = 150;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("to the DNA transformer during your", 1.75);
				
				NewText.x = 210;
				NewText.y = 175;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("retransformation, and you have been", 2);
				
				NewText.x = 210;
				NewText.y = 200;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("rendered into this unspecified green", 2.25);
				
				NewText.x = 210;
				NewText.y = 225;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("object.", 2.50);
				
				NewText.x = 210;
				NewText.y = 250;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("Again, sorry.", 3.5);
				
				NewText.x = 210;
				NewText.y = 300;
				
				add(NewText);
				
				GameText.push(NewText);
				
				break;
				
				case 2:
				
				NewText = new InGameText("You must make your way to the", 0);
				
				NewText.x = 75;
				NewText.y = 75;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("other side of the ship.", 0.25);
				
				NewText.x = 75;
				NewText.y = 100;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("However, it is dangerous", 1.25);
				
				NewText.x = 75;
				NewText.y = 150;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("to go alone.", 1.5);
				
				NewText.x = 75;
				NewText.y = 175;
				
				add(NewText);
				
				GameText.push(NewText);
				
				break;
				
				case 3:
				
				NewText = new InGameText("Fortunately, your psionic capabilities survived the DNA", 0);
				
				NewText.x = 50;
				NewText.y = 50;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("transformation.", 0.25);
				
				NewText.x = 50;
				NewText.y = 75;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("Use your powers to defeat the obstacles before you.", 1.25);
				
				NewText.x = 50;
				NewText.y = 125;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("Find the DNA transformer, and return to your true form!", 2.25);
				
				NewText.x = 50;
				NewText.y = 175;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("Good Luck.", 3.25);
				
				NewText.x = 50;
				NewText.y = 225;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("Drag this object using the mouse!", 0);
				
				NewText.x = 314;
				NewText.y = 314;
				
				add(NewText);
				
				GameText.push(NewText);
				
				break;
				
				case 6:
				
				NewText = new InGameText("Watch out for the lasers!", 0);
				
				NewText.x = 50;
				NewText.y = 50;
				
				add(NewText);
				
				GameText.push(NewText);
				
				break;
				
				case 14:
				
				NewText = new InGameText("Quickly! Step into the beam!", 0);
				
				NewText.x = 50;
				NewText.y = 50;
				
				add(NewText);
				
				GameText.push(NewText);
				
				break;
				
				case 15:
				
				NewText = new InGameText("You did it!", 4);
				
				NewText.x = 400;
				NewText.y = 50;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("You have returned to", 5);
				
				NewText.x = 400;
				NewText.y = 100;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("your true form!", 5.25);
				
				NewText.x = 400;
				NewText.y = 125;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("You are Kitty McMeowMeow", 6.25);
				
				NewText.x = 400;
				NewText.y = 175;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("Whiskerface, Destroyer", 6.50);
				
				NewText.x = 400;
				NewText.y = 200;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("of Worlds!", 6.75);
				
				NewText.x = 400;
				NewText.y = 225;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("Now go, crush your", 7.75);
				
				NewText.x = 400;
				NewText.y = 275;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("enemies!", 8);
				
				NewText.x = 400;
				NewText.y = 300;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("DESTROY!", 9);
				
				NewText.x = 400;
				NewText.y = 350;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("The End :)", 10);
				
				NewText.x = 400;
				NewText.y = 400;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("Created By Benn Powell", 11);
				
				NewText.x = 10;
				NewText.y = 405;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("Twitter: @bennpowell", 11);
				
				NewText.x = 10;
				NewText.y = 430;
				
				add(NewText);
				
				GameText.push(NewText);
				
				NewText = new InGameText("http://benn-gaming.co.uk", 11);
				
				NewText.x = 10;
				NewText.y = 455;
				
				add(NewText);
				
				GameText.push(NewText);
				
				break;
				
			}
			
		}
		
	}

}