/*
VERSION:	1.3
	1.3		Added optional manual tweening code  (Flash tween is still smoother)
	1.2		Added "tileSize" parameter
	1.1		Added checks for RAM.keys.up down left right...  which override the default controls while they exist

USAGE:
	#include "tileWalk.as"
	myWalk_obj = makeTileWalk( my_mc );
	
SETTINGS:
	walkSpeed			How many seconds it takes to walk 1 tile		(smaller = faster)		(default: 0.13  (RpgMaker)
	
NOTES:
	This system has hooks for these collision and sprite systems:
		sprite.as							(Sprite system 2)
		TileWalkCollision.as
	
ADDING COLLISION:
	A collision system can be added like this:
		walk_obj.collision = new Collision( player_mc, walk_obj, collision_array, -8, -8 );
	The walk_obj is this walk system.
*/
makeTileWalk = function( player_mc, playerSprite_mc, tileSize )
{
	var tileSize = tileSize || MAP.tileSize || 16;
	var fps = 30;
	// create system container
	var _this = new Object();
	
	// Settings
	_this.walkSpeed = 0.13;		// How many seconds it takes to walk 1 tile  (smaller = faster)
	_this.playerSprite_mc = playerSprite_mc;
	var posOffset = {
		x: Math.floor(tileSize/2),
		y: Math.floor(tileSize/2)
	}
	
	// initial animation
	_this.playerSprite_mc.setParams({isAnimating:false});
	
	//default walk buttons.  This allows the keys to be changed externally.
	_this.up_key = Key.UP;
	_this.down_key = Key.DOWN;
	_this.left_key = Key.LEFT;
	_this.right_key = Key.RIGHT;
	
	
	
	// create loop
	_this.loop = function()
	{
		// if movement is enabled
		if(_this.disableKeys)		return;

		
		// Define movement
		if(Key.isDown(RAM.keys.up || _this.up_key))
		{
			_this.xVel = 0;
			_this.yVel = -1;
			_this.playerSprite_mc.setParams({direction:"up"});
		}// if:  key up
		else if(Key.isDown(RAM.keys.down || _this.down_key))
		{
			_this.xVel = 0;
			_this.yVel = 1;
			_this.playerSprite_mc.setParams({direction:"down"});
		}// if:  key down
		else if(Key.isDown(RAM.keys.left || _this.left_key))
		{
			_this.xVel = -1;
			_this.yVel = 0;
			_this.playerSprite_mc.setParams({direction:"left"});
		}// if:  key left
		else if(Key.isDown(RAM.keys.right || _this.right_key))
		{
			_this.xVel = 1;
			_this.yVel = 0;
			_this.playerSprite_mc.setParams({direction:"right"});
		}// if:  key right
		
		
		
		if(Key.isDown(RAM.keys.up || _this.up_key)  ||
			Key.isDown(RAM.keys.down || _this.down_key)  ||
			Key.isDown(RAM.keys.left || _this.left_key)  ||
			Key.isDown(RAM.keys.right || _this.right_key) )
		{
			// Apply externally-defined collision
			_this.collision.run();
		}// if:  key right
		
		
		
		// Do movement
		if(_this.xVel || _this.yVel)
		{
			_this.playerSprite_mc.setParams({isAnimating:true});
			// disable key detection
			_this.disableKeys = true;
			
			
			// tween movement
			var xStart = Math.floor(player_mc._x / tileSize) * tileSize;
			var yStart = Math.floor(player_mc._y / tileSize) * tileSize;
			xStart += posOffset.x;
			yStart += posOffset.y;
			
			var xDest = xStart + (tileSize * _this.xVel);
			var yDest = yStart + (tileSize * _this.yVel);
			
			var doneMoving = function(){
				_this.disableKeys = false;
				if(_this.isPaused == undefined  ||  _this.isPaused==false){
					// linger on destination for 1 frame  (let loop() automatially occur 1 frame after movement finishes)
					//_this.loop();
				}else{
					_this.playerSprite_mc.setParams({isAnimating:false});
				}
			}// doneMoving()
			
			
			/*
			// Use manual tween for movement
			var frameLength = Math.floor(1000/fps);		// 33.333 ms => 33 ms  (round down to schedule ahead of each frame)
			var totalSteps_exact = fps * _this.walkSpeed;
			var totalSteps = Math.ceil(totalSteps_exact);		// total number of frames is an integer  (use rounded value for consistency between values & current-frame comparisons)
			var xDiff = Math.round(xDest-xStart);		// total distance is a whole-pixel value
			var xInc = xDiff / totalSteps;	// distance per frame is a whole-pixel value
			var yDiff = Math.round(yDest-yStart);		// total distance is a whole-pixel value
			var yInc = yDiff / totalSteps;	// distance per frame is a whole-pixel value
			
			var thisStep = 0;
			var doStep = function(){
				thisStep++;
				// tightly control player's position during movement
				//player_mc._x = xStart + (thisStep * xInc);
				//player_mc._y = yStart + (thisStep * yInc);
				// loosely control player's position during movement  (allow other things to shift the player's position)
				player_mc._x += xInc;
				player_mc._y += yInc;
				if(thisStep >= totalSteps)		return false;		// done moving
				return true;
			}// doStep()
			
			// tightly control player's starting position
			player_mc._x = xStart;
			player_mc._y = yStart;
			// do 1st step now
			doStep();
			
			// continue doing steps
			var moveInterval = setInterval(function(){
				if( doStep() == false )
				{
					// tightly control player's destination position  (cancel all external shifting during movement)
					//player_mc._x = xDest;
					//player_mc._y = yDest;
					// loosely correct player's destination position  (repeatedly adding decimals isn't quite accurate)
					var xEnd = Math.floor(player_mc._x / tileSize) * tileSize;
					var yEnd = Math.floor(player_mc._y / tileSize) * tileSize;
					xEnd += posOffset.x;
					yEnd += posOffset.y;
					player_mc._x = xEnd;
					player_mc._y = yEnd;
					
					clearInterval( moveInterval );
					doneMoving();
				}
			}, frameLength);
			*/
			
			
			// Use Flash tween for movement
			var easing = mx.transitions.easing.None.easeNone;
			_this.xTween = new mx.transitions.Tween( player_mc, "_x", easing, xStart, xDest, _this.walkSpeed, true);
			_this.yTween = new mx.transitions.Tween( player_mc, "_y", easing, yStart, yDest, _this.walkSpeed, true);
			
			// enable key detection
			if(_this.xVel)
			{
				_this.xTween.onMotionFinished = function(){
					doneMoving();
					_this.loop();
				};
				_this.yTween.onMotionFinished = function(){}
			}// if:  horz movement
			else if(_this.yVel)
			{
				_this.xTween.onMotionFinished = function(){}
				_this.yTween.onMotionFinished = function(){
					doneMoving();
					_this.loop();
				};
			}// if:  vert movement
			
			
			
			// reset velocities
			_this.xVel = 0;
			_this.yVel = 0
		}// if:  arrow key is pressed
		else
		{// if:  not moving
			_this.playerSprite_mc.setParams({isAnimating:false});
		}
	}// loop()
	
	
	
	// make this loop
	_this.loopInterval = setInterval( _this.loop, 1000/fps ); 
	
	
	
	// return a reference to this system
	return _this;
}// makeTileWalk()
