/*	AVAILABLE DATA
	thisCommand_obj
		data						This command's data
		run()						This function
		nextEvent()			Function that triggers the next sibling command
		storeTimeout()	Function that stores this command's timeout ID   (used to stop the script)
			var waitId = setTimeout( parentScript.nextEvent, thisCommand_obj.data.value*1000 );
			thisCommand_obj.storeTimeout( waitId );
*/
#include "gameFunctions/copyObject.as"
#include "gameFunctions/makeStringObject.as"
	// nestedEval
	// evalPath
	// getImpliedValue
	// resolveContainer

// run()
define_setVariable = function( thisCommand_obj ){
	
	
	var prom = VOW.make();
	
	// var TRACE_SCRIPT = true;
	// if "auto" command has just started, wait a bit before potentially removing this sprite  (via flags)	(this prevents crashing the game)
	var autoDelay = 1;
	var endTime = getTimer();
	if( TRACE_SCRIPT )		trace("setVariable  startTime: "+startTime);
	var elapsedTime = endTime - startTime;
	// "startTime" only exists if this is an "auto" script,  otherwise the script will always be allowed to run
	var allowRun = false;
	if( startTime === undefined ){
		if( TRACE_SCRIPT )		trace("setVariable  This is not an 'auto' script,  because 'startTime' doesn't exist,  therefore allow");
		allowRun = true;
	}else if( isNaN(elapsedTime) ){
		if( TRACE_SCRIPT )		trace("setVariable  elapsedTime is broken for some reason,  therefore ignore it and allow");
		if( TRACE_SCRIPT )		trace("  elapsedTime: "+elapsedTime);
		allowRun = true;
	}else if( elapsedTime > autoDelay ){		// NaN will always pass > evaluations ...for some reason.  Therefore only check this when the other conditions don't apply.
		if( TRACE_SCRIPT )		trace("setVariable  Initial delay is sufficient,  therefore allow");
		allowRun = true;
	}
	if( allowRun )
	{// if:  time has passed since "auto" script started		(prevent game crash)		... or when this script is not an "auto" script
		if( TRACE_SCRIPT )		trace("setVariable  Delay checks passed,  running setVariable command");
		if(thisCommand_obj.data.update==undefined)		thisCommand_obj.data.update = true;		// legacy support
		// resolve targets
		var data = thisCommand_obj.data;
		
		
		
		// (first part)  resolve target variable
		var target_str = nestedEval( data.condition[0], "RAM", "_this");
		var divideAt = target_str.lastIndexOf(".");
		if(divideAt==-1)
		{// if:  not a variable path  (single variable)
			// assume this single variable exists within RAM
			var varContainerName = "RAM";
			var varContainer = RAM;
		}// if:  not a variable path  (single variable)
		else
		{// if:  is a variable path
			// determine the intended container
			var varContainerName = target_str.substr(0,divideAt);
			var varContainer = evalPath( varContainerName, "RAM", "_this" );
		}// if:  is a variable path
		var varName = target_str.substr(divideAt+1);
		
		
		
		// (last part)  resolve value  &  optionally create objects
		var operationDone = false;
		var thisValue = data.condition[2];
		thisValue = makeStringObject( thisValue, "RAM", "_this");		// construct an object if specified
		thisValue = nestedEval( thisValue, "RAM", "_this");
		thisValue = getImpliedValue(thisValue);		// convert string to appropriate datatype if neccessary
		if(thisValue == "\\object"){
			// create new object
			varContainer[varName] = {};
			var operationDone = true;
		}else if(thisValue == "\\array"){
			// create new array
			varContainer[varName] = [];
			var operationDone = true;
		}else if(thisValue=="\\delete"){
			varContainer[varName] = undefined;
			delete varContainer[varName];
			var operationDone = true;
		}
		var value;
		if(  (thisValue instanceof Object) === false  ||  data.reference === true)
		{// if:  reference the data directly  /  copy a variable
			value = thisValue;
		}// if:  reference the data directly  /  copy a variable
		else
		{// if:  clone the data
			if(thisValue instanceof Array){
				// array
				value = [];
				copyObject( thisValue, value );
			}else if(thisValue instanceof Object){
				// object
				value = {};
				copyObject( thisValue, value );
			}
		}// if:  clone the data
		
		
		
		
		// (middle part)  apply operation
		if( !operationDone )
		{
			if(TRACE_SCRIPT){
				var op = data.condition[1];
				if( op === "=" )		op = "=>";
				trace("setVariable: "+varName+"  ("+varContainer[varName]+" "+op+" "+value+")");
			} 
			
			
			switch( data.condition[1] )
			{
				case "=":
					varContainer[varName] = value;
				break;
				case "+":
					var bothAreNumbers = (!isNaN(varContainer[varName])) && (!isNaN(value));
					if(bothAreNumbers){
						varContainer[varName] = Number(varContainer[varName]) + Number(value);
					}else{
						varContainer[varName] = String(varContainer[varName]) + String(value);
					}
				break;
				case "-":
					varContainer[varName] -= Number(value);
				break;
				case "*":
					varContainer[varName] *= Number(value);
				break;
				case "/":
					if(Number(value)==0){
						varContainer[varName] = undefined;
					}else{
						varContainer[varName] /= Number(value);
					}
				break;
				case "%":
					if(Number(value)==0){
						varContainer[varName] = undefined;
					}else{
						varContainer[varName] %= Number(value);
					}
				break;
				case "!":
					if(typeof(value)=="boolean"){
						varContainer[varName] = !value;
					}
				break;
			}// switch:  operator
			
			
			// catch NaN
			if( typeof(varContainer[varName])=="number"  &&  isNaN(varContainer[varName]) ){
				varContainer[varName] = undefined;
			}
		}// if:  not a special operation, such as deleting or creating objects
		
		// update sprite visibility flags
		if(data.update)
			SPRITES.updateSprites();
		
		
		// instantly done
		return VOW.make().keep();
		
		
	}// if:  time has passed since "auto" script started		(prevent game crash)
	else
	{// if:  NO time has passed since the "auto" script began
		
		
		// wait for promise
		if( TRACE_SCRIPT )		trace("setVariable  Initial delay is too soon,  delaying setVariable command");
		var prom = VOW.make();
		setTimeout( function(){
			var inner_prom = define_setVariable( thisCommand_obj );
			if( !inner_prom.is_promise )		inner_prom = VOW.make().keep();
			inner_prom.then = prom.keep;
		}, autoDelay );
		return prom;
		
		
	}// if:  NO time has passed since the "auto" script began
}// define_setVariable()