//
// duration: overall transition duration in milliseconds
// type: transition type: easeIn, easeOut
// parameters: node attributes, etc to change
// values: holds parameter values they need to be changed to from current values
//

var zsite_transition_timer = null;
var zsite_current_transitions = Array();


var zsite_transitionfuncs = Array();
zsite_transitionfuncs["easeIn"] = function(step)
{
	return Math.sin(Math.PI/2*step);
}

zsite_transitionfuncs["easeOut"] = function(step)
{
	return 1-Math.cos(Math.PI/2*step);
}

function newTransition(duration, type, startvalues, endvalues, callback, finishcallback)
{
	if(zsite_transitionfuncs[type] == null)
	{
		alert("Unknown transition type");
		return false;
	}

	thisTransition = Array();

	thisTransition["step"] = 0.0;
	thisTransition["duration"] = duration;
	thisTransition["type"] = type;
	thisTransition["endvalues"] = endvalues;
	thisTransition["startvalues"] = startvalues;
	thisTransition["callback"] = callback;
	thisTransition["finishcallback"] = finishcallback;
	thisTransition["startTime"] = new Date();

	zsite_current_transitions[zsite_current_transitions.length] = thisTransition;

	ZSite_ProcessTransitions();
}

function ZSite_ProcessTransitions()
{
	var moreTransitions = false;
	var realInterval = 50;
	if(zsite_transition_timer == null)
	{
		zsite_transition_timer = new Date();
		realInterval = 40;
	}
	else
	{
		//check if we have enough CPU power to increase timer
		//frequency or decrease timer interval on slow CPUs
		var realInterval = Date() - zsite_transition_timer;
		if(realInterval < 50) realInterval = 50; //don't call too often, this is 50 fps
		if(realInterval > 300) realInterval = 300; //don't get too long
		zsite_transition_timer = new Date();
	}	

	for(var i = 0; i < zsite_current_transitions.length; i++)
	{
		if(zsite_current_transitions[i] == null) continue;

		//process single transition
		var tr = zsite_current_transitions[i];

		//if transition is already over, go to last step
		if((tr["startTime"] - zsite_transition_timer + tr["duration"]) < 0)
		{
			//transition is over
			var params = Array();

			for(var j = 0; j < tr["endvalues"].length; j++)
				params[j] = tr["endvalues"][j];

			tr["callback"](params);

			//remove transition
			zsite_current_transitions[i] = null;
			var newtrans = Array();
			for(var j = 0; j < zsite_current_transitions.length; j++)
			{
				if(zsite_current_transitions[j] != null)
					newtrans[newtrans.length] = zsite_current_transitions[j];
			}
			zsite_current_transitions = newtrans;

			if(tr["finishcallback"]!=null)
				tr["finishcallback"]();
		}
		else
		{
			var moreTransitions = true;

			//calculate step
			//linear step
			var linstep = ((zsite_transition_timer-tr["startTime"])/tr["duration"]);
			var realstep = zsite_transitionfuncs[tr["type"]](linstep);

			var params = Array();
			for(var j = 0; j < tr["endvalues"].length; j++)
				params[j] = tr["startvalues"][j]-(tr["startvalues"][j] - tr["endvalues"][j])*realstep;

			tr["callback"](params);
		}
	}

	//if all transitions are still not done, repeat function after interval
	if(moreTransitions)
	{
		setTimeout(ZSite_ProcessTransitions, realInterval);
	}
	else
	{
		zsite_transition_timer = null;
	}
}

