package Mobs
{
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	
	/**
	 * ...
	 * @author Michael Miriti
	 */
	public class Player extends Mob
	{
		static public const GRAVITY:Number = 2;
		static public const MAX_SPEED:Number = 2;
		static private const PLAYER_COLOR:Number = 15;
		static private const X_ACC:Number = 1.5;
		static private const JUMP_POWER_MAX:Number = 0.9;
		static private const JUMP_POWER_MIN:Number = 0.3;
		private var _running:Boolean = false;
		private var _frameTime:Number = 0;
		private var _dir:int = 1;
		private var _inJump:Boolean = false;
		private var _jumpHold:Boolean = false;
		private var ySpeed:Number = 0;
		private var xSpeed:Number = 0;
		
		public function Player()
		{
			x = 2;
			y = 2;
			
			_inJump = true;
			
			Main.i.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
			Main.i.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
		}
		
		private function onKeyUp(e:KeyboardEvent):void
		{
			_jumpHold = false;
		}
		
		private function onKeyDown(e:KeyboardEvent):void
		{
		
		}
		
		override public function update(delta:Number):void
		{
			super.update(delta);
			
			if (Main.i.isLeft)
			{
				xSpeed -= (delta / 1000) * X_ACC;
				if (xSpeed < -MAX_SPEED)
					xSpeed = -MAX_SPEED;
			}
			
			if (Main.i.isRight)
			{
				xSpeed += (delta / 1000) * X_ACC;
				if (xSpeed > MAX_SPEED)
					xSpeed = MAX_SPEED;
			}
			
			if (xSpeed < 0)
				_dir = -1;
			if (xSpeed > 0)
				_dir = 1;
			
			_running = (Main.i.isLeft) || (Main.i.isRight);
			
			if (!_running)
				_frameTime = 0;
			
			if (Main.i.isUp)
			{
				jump();
			}
			
			fy += ySpeed;
			fx += xSpeed;
			
			if (xSpeed < 0)
			{
				xSpeed += (delta / 1000) * 1;
				if (xSpeed > 0)
					xSpeed = 0;
			}
			else if (xSpeed > 0)
			{
				xSpeed -= (delta / 1000) * 1;
				if (xSpeed < 0)
					xSpeed = 0;
			}
			
			if (!_jumpHold)
				ySpeed += GRAVITY * (delta / 1000);
		}
		
		private function jump():void
		{
			if (!_inJump)
			{
				_inJump = true;
				_jumpHold = true;
				ySpeed = -JUMP_POWER_MIN;
			}
			else if (_jumpHold)
			{
				ySpeed -= 0.15;
				if (ySpeed <= -JUMP_POWER_MAX)
				{
					ySpeed = -JUMP_POWER_MAX;
					_jumpHold = false;
				}
			}
		}
		
		override public function render(delta:Number):void
		{
			if (_inJump)
			{
				frameJump();
			}
			else if (xSpeed != 0)
			{
				if (_frameTime < 100)
				{
					frameRun0();
				}
				else
				{
					frameRun1();
					if (_frameTime > 200)
						_frameTime = 0;
				}
				_frameTime += delta;
			}
			else
				frameStill();
		}
		
		private function frameStill():void
		{
			var px:int = x - MapManager.inst.shiftX;
			var py:int = y - MapManager.inst.shiftY;
			
			Main.i.setChar(px, py, "o".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px, py));
			Main.i.setChar(px, py + 1, "l".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px, py + 1));
			Main.i.setChar(px - 1, py + 1, "/".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 1));
			Main.i.setChar(px + 1, py + 1, "\\".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 1));
			Main.i.setChar(px - 1, py + 2, "/".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 2));
			Main.i.setChar(px + 1, py + 2, "\\".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 2));
		}
		
		private function frameRun0():void
		{
			var px:int = x - MapManager.inst.shiftX;
			var py:int = y - MapManager.inst.shiftY;
			Main.i.setChar(px, py, "o".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px, py));
			Main.i.setChar(px, py + 1, "l".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px, py + 1));
			
			if (_dir == 1)
			{
				Main.i.setChar(px - 1, py + 1, "/".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 1));
				Main.i.setChar(px + 1, py + 1, "-".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 1));
				Main.i.setChar(px - 1, py + 2, "/".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 2));
				Main.i.setChar(px + 1, py + 2, ">".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 2));
			}
			else
			{
				Main.i.setChar(px - 1, py + 1, "-".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 1));
				Main.i.setChar(px + 1, py + 1, "]".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 1));
				Main.i.setChar(px - 1, py + 2, "<".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 2));
				Main.i.setChar(px + 1, py + 2, "\\".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 2));
			}
		}
		
		private function frameRun1():void
		{
			var px:int = x - MapManager.inst.shiftX;
			var py:int = y - MapManager.inst.shiftY;
			Main.i.setChar(px, py, "o".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px, py));
			Main.i.setChar(px, py + 1, "l".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px, py + 1));
			
			if (_dir == 1)
			{
				Main.i.setChar(px - 1, py + 1, "[".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 1));
				Main.i.setChar(px + 1, py + 1, "\\".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 1));
				Main.i.setChar(px - 1, py + 2, ">".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 2));
				Main.i.setChar(px + 1, py + 2, "\\".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 2));
			}
			else
			{
				Main.i.setChar(px - 1, py + 1, "/".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 1));
				Main.i.setChar(px + 1, py + 1, "-".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 1));
				Main.i.setChar(px - 1, py + 2, "/".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 2));
				Main.i.setChar(px + 1, py + 2, "<".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 2));
			}
		}
		
		private function frameJump():void
		{
			var px:int = x - MapManager.inst.shiftX;
			var py:int = y - MapManager.inst.shiftY;
			Main.i.setChar(px, py, "o".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px, py));
			Main.i.setChar(px, py + 1, "l".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px, py + 1));
			
			if (_dir == 1)
			{
				Main.i.setChar(px - 1, py + 1, "/".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 1));
				Main.i.setChar(px + 1, py, "/".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 1));
				Main.i.setChar(px - 1, py + 2, "/".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 2));
				Main.i.setChar(px + 1, py + 2, ">".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 2));
			}
			else
			{
				Main.i.setChar(px + 1, py + 1, "\\".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 1));
				Main.i.setChar(px - 1, py, "\\".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 1));
				Main.i.setChar(px - 1, py + 2, "<".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px - 1, py + 2));
				Main.i.setChar(px + 1, py + 2, "\\".charCodeAt(0) - 1, PLAYER_COLOR, Main.i.getColor(px + 1, py + 2));
			}
		}
		
		override public function get fy():Number
		{
			return super.fy;
		}
		
		override public function set fy(value:Number):void
		{
			var srcY:int = Math.floor(_y);
			var destY:int = Math.floor(value);
			
			var dir:int = destY > srcY ? 1 : -1;
			var add:int = destY > srcY ? 3 : 0;
			
			var cy:int = srcY;
			
			if (destY + 4 > MapManager.inst.mapH)
			{
				value = MapManager.inst.mapH - 4;
				dispatchEvent(new Event("death"));
			}
			else if (destY < 0)
			{
				value = 0;
			}
			else if ((MapManager.inst.mapData[x][destY+2] != null) && (MapManager.inst.mapData[x][destY+2] is MapCellLava))
			{
				dispatchEvent(new Event("death"));
			}
			else
			{
				while (cy != destY)
				{
					if ((cy + add > MapManager.inst.mapH) || (cy + add < 0))
					{
						value = cy;
						break;
					}
					
					if ((!MapManager.inst.canPass(x, cy + add)) || (!MapManager.inst.canPass(x - 1, cy + add)) || (!MapManager.inst.canPass(x + 1, cy + add)))
					{
						value = cy;
						
						if (dir == 1)
						{
							_inJump = false;
							ySpeed = 0;
						}
						else
						{
							ySpeed = -ySpeed;
						}
						_jumpHold = false;
						break;
					}
					cy += dir;
				}
			}
			
			super.fy = value;
		}
		
		override public function get fx():Number
		{
			return super.fx;
		}
		
		override public function set fx(value:Number):void
		{
			var srcX:int = Math.floor(_x);
			var dstX:int = Math.floor(value);
			var add:int = dstX > srcX ? 2 : -2;
			var dir:int = dstX > srcX ? 1 : -1;
			var cx:int = srcX;
			
			if (dstX - 1 < 0)
			{
				value = 1;
				xSpeed = 0;
			}
			else
			{
				while (cx != dstX)
				{
					if ((!MapManager.inst.canPass(cx + add, y)) || (!MapManager.inst.canPass(cx + add, y + 1)) || (!MapManager.inst.canPass(cx + add, y + 2)))
					{
						xSpeed = 0;
						value = cx;
						break;
					}
					cx += dir;
				}
			}
			
			super.fx = value;
		}
	}

}