/*	AVAILABLE DATA
	thisCommand_obj
		data						This command's data
		run()						This function
		nextEvent()			Function that triggers the next sibling command
		moveTimeout			Array + Functions to manage this command's timeout ID   (used to stop the script)
*/
#include "functions/once.as"
// run()
define_moveRelative = function( thisCommand_obj ){
	
	
	var prom = VOW.make();
	var nextEvent = once( prom.keep );		// calling nextEvent() calls prom.keep( true )
	
	
	if(TRACE_SCRIPT)
		trace("moveRelative");
	
	
	
	// apply autoDirection
	// assume strings are variable paths, and add brackets if they're missing
	if(typeof(thisCommand_obj.data.position.x)=="string")
		if(thisCommand_obj.data.position.x.charAt(0)!="[")
			thisCommand_obj.data.position.x = "["+thisCommand_obj.data.position.x+"]";
	if(typeof(thisCommand_obj.data.position.y)=="string")
		if(thisCommand_obj.data.position.y.charAt(0)!="[")
			thisCommand_obj.data.position.y = "["+thisCommand_obj.data.position.y+"]";
	
	// get direction traveled
	var xUnit = Number( nestedEval( thisCommand_obj.data.position.x, "RAM", "_this" ) );
	var yUnit = Number( nestedEval( thisCommand_obj.data.position.y, "RAM", "_this" ) );
	//var xUnit = thisCommand_obj.data.position.x;
	//var yUnit = thisCommand_obj.data.position.y;
	
	if(thisCommand_obj.data.autoDirection)
	{
		// compare x & y
		if( Math.abs(yUnit) > Math.abs(xUnit) ){// vert
			if( yUnit < 0){// up
				thisCommand_obj.sprite.image.setParams({direction:"up"});
			}else{// down
				thisCommand_obj.sprite.image.setParams({direction:"down"});
			}// if:  up or down
		}else{// horz
			if( xUnit < 0 ){// left
				thisCommand_obj.sprite.image.setParams({direction:"left"});
			}else{// right
				thisCommand_obj.sprite.image.setParams({direction:"right"});
			}// if:  left or right
		}// if:  vert or horz
	}// if:  autoDirection
	
	
	
	// apply autoAnim
	if(thisCommand_obj.data.autoAnim)
		thisCommand_obj.sprite.image.setParams({isAnimating:true});
	
	
	
	// prepare to move
	var startX = thisCommand_obj.sprite._x;
	var startY = thisCommand_obj.sprite._y;
	var endX = startX + xUnit;
	var endY = startY + yUnit;
	
	
	
	// if:   no duration
	// instantly done
	if(thisCommand_obj.data.duration == 0){
		// jump to destination
		thisCommand_obj.sprite._x = endX;
		thisCommand_obj.sprite._y = endY;
		// stop animating
		if(thisCommand_obj.data.autoAnim)		// ON
			thisCommand_obj.sprite.image.setParams({isAnimating:false});
		// finish instantly
		return VOW.make().keep();
	}// if:   no duration
	
	
	
	// slide position
	var react_to_unload = react.once().to("unload");
	var originalName = thisCommand_obj.sprite._name;
	// if(thisCommand_obj.data.duration==0)
	// 	thisCommand_obj.data.duration = 0.001;
	// add slideX and slideY variables into the affected sprite
	var slideX = thisCommand_obj.sprite.slideX = new mx.transitions.Tween( thisCommand_obj.sprite, "_x", null, startX, endX, thisCommand_obj.data.duration, true);
	var slideY = thisCommand_obj.sprite.slideY = new mx.transitions.Tween( thisCommand_obj.sprite, "_y", null, startY, endY, thisCommand_obj.data.duration, true);
	slideY.thisCommand_obj = thisCommand_obj;
	
	var motionDone = function( thisTween )
	{
		react_to_unload.disable();
		//var spriteRemoved = (!sameSprite  ||  thisCommand_obj.sprite.wasRemoved  ||  thisCommand_obj.sprite._name == undefined  ||  thisCommand_obj.sprite._name == "");
		var sameSprite = thisCommand_obj.sprite == SPRITES[originalName];
		var spriteRemoved = (!sameSprite);
		var wasMoving = Boolean(slideX.onMotionFinished);
		slideX.onMotionFinished = null;
		slideY.onMotionFinished = null;
		
		// clean-up tween object
		slideX.stop();
		slideY.stop();
		delete slideX;
		delete slideY;
		delete thisCommand_obj.sprite.slideX;
		delete thisCommand_obj.sprite.slideY;
		
		if( !spriteRemoved )
		{// if:  sprite still exists
			if(thisCommand_obj.data.autoAnim)		// ON
				thisCommand_obj.sprite.image.setParams({isAnimating:false});
			if(wasMoving)		thisCommand_obj.sprite.broadcastMessage("onMoveFinish");
		}// if:  sprite still exists
		
		// check timeout before continuing
		var timeoutExists = thisCommand_obj.moveTimeout.exists( thisCommand_obj.timeout );
		if( timeoutExists )
		{// if:  timeout hasn't been deleted
			// clearTimeout
			thisCommand_obj.moveTimeout.remove( thisCommand_obj.timeout );
			// run next command
			if(!spriteRemoved)
				nextEvent();
			else
				prom.doBreak();		// thisCommand_obj.abort();
		}// if:  timeout hasn't been deleted
		else{
			// if:  timeout is missing
			prom.doBreak();		// thisCommand_obj.abort();
		}
	}// motionDone()
	motionDone = once( motionDone );
	//slideX.onMotionFinished = motionDone;
	slideY.onMotionFinished = motionDone;
	react_to_unload.then = motionDone;
	
	
	
	// allow motion to be interrupted  (occurs during teleports for instance)
	slideY.onMotionChanged = function()
	{
		var thisCommand_obj = this.thisCommand_obj;
		//thisCommand_obj.sprite.gridCollide_obj.loop();	// update grid position
		thisCommand_obj.sprite.broadcastMessage("onMove", {x:thisCommand_obj.sprite._x, y:thisCommand_obj.sprite._y, sprite:thisCommand_obj.sprite});
		var timeoutExists = thisCommand_obj.moveTimeout.exists( thisCommand_obj.timeout );
		//var spriteRemoved = (!sameSprite  ||  thisCommand_obj.sprite.wasRemoved  ||  thisCommand_obj.sprite._name == undefined  ||  thisCommand_obj.sprite._name == "");
		var sameSprite = thisCommand_obj.sprite == SPRITES[originalName];
		var spriteRemoved = (!sameSprite);
		if(spriteRemoved)
			thisCommand_obj.sprite.resetToStartPosition();
		if( spriteRemoved || !timeoutExists ){
			motionDone( this );
		}
	}// during move()
	
	
	
	// wait a moment
	var dudFunction = function(){};
	var waitTime = thisCommand_obj.data.duration*1000;		// convert seconds to milliseconds
	thisCommand_obj.timeout = setTimeout( dudFunction, waitTime, thisCommand_obj );		// artifically generate a timeout ID,  and internally store it
	thisCommand_obj.moveTimeout.addTimeout( thisCommand_obj.timeout );		// externally store wait timeout
	//thisCommand_obj.moveTimeout = thisCommand_obj.sprite.moveTimeout;		// allow this command to store its timeouts
	
	
	
	// wait for promise
	return prom;


}// define_moveRelative()