/////////////////////////////////////////////////////////////////////////////////////////////////////////
// 
// Transition 
// 
// latest update : 2009.05.13
// 
/////////////////////////////////////////////////////////////////////////////////////////////////////////

var Timeline = function(){}
Timeline.initTime = new Date().getTime();
Timeline.time = 0;
Timeline.timer = null;
Timeline.container = [];
Timeline.add = function(func)
{
	Timeline.container.push(func);
}
Timeline.remove = function(func)
{
	var n = Timeline.container.length;
	for(var i=0;i<n;i++)
	{
		if(Timeline.container[i] == func)
		{
			Timeline.container.splice(i, 1); break;
		}
	}
}
Timeline.start = function(fps)
{
	Timeline.timer = setInterval(
		function()
		{
			var t = Timeline.time = new Date().getTime() - Timeline.initTime;
			var list = Timeline.container.concat();
			var n = list.length;
			for(var i=0;i<n;i++) list[i](t);
		},
		parseInt(1000 / fps));
}
Timeline.stop = function()
{
	if (Timeline.timer != null) clearInterval(Timeline.timer);
	Timeline.timer = null;
}



var Transition = function(){}
Transition.defaultEasing = function(t)
{
	return (t -= 1) * t * t + 1;
}
Transition.tween = function(target, parameters, time, delay, easing, callback)
{
	if(!easing) easing = Transition.defaultEasing;
	if(!delay) delay = 0.0;
	if(!time) time = 0.45;
	if(delay > 0) delay = Math.round(delay * 1000);
	if(time > 0) time = Math.round(time * 1000);
	var s = null;
	
	var it = {};
	var dt = {};
	var ex = {};
	
	for(var name in parameters)
	{
		var v = target[name] + "";
		if(!target[name]) v = "0";
		
		var n = Number(v.replace(/[^\d]/g, ""));
		dt[name] = parameters[name] - (it[name] = n);
	}
	
	var f = function(t)
	{
		if(s == null) s = Timeline.time;
		var d = t - s - delay;
		if(d < 0) return;
		
		var e = d / time;
		if(e > 1) e = 1;
		var n = easing(e);
		
		for(var name in dt)
		{
			var v = it[name] + dt[name] * n;
			if(name == "width" || name == "height")
			{
				target[name] = v + "px";
			}
			else
			{
				target[name] = v;
			}
		}
		
		if(e == 1)
		{
			Timeline.remove(arguments.callee);
			if(callback) callback(target);
		}
	}
	Timeline.add(f);
}

var Easing = function(){}
Easing.backEaseIn = function(t, s) { if(isNaN(s)) {s = 1.70158;} return t * t * ((s + 1) * t - s); }
Easing.backEaseInOut = function(t, s) { if(isNaN(s)) {s = 1.70158;} if (t < 0.5) return 0.5 * (t*t*(((s*=(1.525))+1)*t-s)); return 0.5*((t-=2)*t*(((s*=(1.525))+1)*t+s)+2); }
Easing.backEaseOut = function(t, s) { if(isNaN(s)) {s = 1.70158;} return (t = t - 1) * t * ((s + 1) * t + s) + 1; }
Easing.backEaseOutIn = function(t, s) { if(isNaN(s)) {s = 1.70158;} if (t < 0.5) return Easing.backEaseOut(t * 2, s) * 0.5; else return Easing.backEaseIn(t * 2 - 1, s) * 0.5 + 0.5; }

Easing.bounceEaseIn = function(t) { return 1 - Easing.bounceEaseOut(1 - t); }
Easing.bounceEaseInOut = function(t) { if (t < 0.5) return Easing.bounceEaseIn(t * 2) * 0.5; else return Easing.bounceEaseOut(t * 2 - 1) * 0.5 + 0.5; }
Easing.bounceEaseOut = function(t) { if (t < 0.36363636363636365) return 7.5625 * t * t; else if (t < 0.7272727272727273) return 7.5625 * (t -= 0.5454545454545454) * t + 0.75; else if (t < 0.9090909090909091) return 7.5625 * (t -= 0.8181818181818182) * t + 0.9375; else return 7.5625 * (t -= 0.9545454545454546) * t + 0.984375; }
Easing.bounceEaseOutIn = function(t) { if (t < 0.5) return Easing.bounceEaseOut(t * 2) * 0.5; else return Easing.bounceEaseIn(t * 2 - 1) * 0.5 + 0.5; }


Easing.elasticEaseIn = function(t, a, p) { var s; if(t==0.0)return 0.0; if(t==1.0)return 1.0; if(!p)p=0.3; if(!a||a<1.0){a=1; s=p*0.25;}else{s=p/6.283185307179586*Math.asin(1.0/a);} return -(a*Math.pow(2.0,10.0*(t-=1.0))*Math.sin((t-s)*6.283185307179586/p)); }
Easing.elasticEaseInOut = function(t, a, p) { if(t==0.0)return 0.0; if(t==1.0)return 1.0; if(!p)p=0.45;var s; if(!a||a<1.0){a = 1.0;s = p*0.25;}else{s=p/6.283185307179586*Math.asin(1.0/a);}if(t<1.0){ return -0.5*(a*Math.pow(2.0,10.0*(t-=1.0))*Math.sin((t-s)*6.283185307179586 /p));} return a*Math.pow(2,-10*(t-=1.0))*Math.sin((t-s)*6.283185307179586/p)*0.5+1.0; }
Easing.elasticEaseOut = function(t, a, p) { if(t==0)return 0.0; if(t==1)return 1.0; if(!p)p=0.3; var s; if(!a||a<1.0){a=1.0;s=p*0.25;}else{s=p/6.283185307179586*Math.asin(1.0/a);}return a*Math.pow(2,-10*t)*Math.sin((t-s)*6.283185307179586/p)+1.0; }
Easing.elasticEaseOutIn = function(t, a, p) { if(t<0.5) return easeOut(t*2,a,p)*0.5; else return easeIn(t*2-1,a,p)*0.5+0.5; }

Easing.cubicEaseIn = function(t){return t * t * t;}
Easing.cubicEaseInOut = function(t){if (t < 0.5) return (t *= 2) * t * t * 0.5; else return ((t = t * 2 - 2) * t * t + 1) * 0.5 + 0.5;}
Easing.cubicEaseOut = function(t){return (t -= 1) * t * t + 1;}
Easing.cubicEaseOutIn = function(t){if (t < 0.5) return ((t = t * 2 - 1) * t * t + 1 ) * 0.5; else return (t = t * 2 - 1) * t * t * 0.5 + 0.5;}

Easing.quinticEaseIn = function(t){return t * t * t * t * t;}
Easing.quinticEaseInOut = function(t){if ((t /= 0.5) < 1) return 0.5 * t * t * t * t * t; return 0.5 * ((t -= 2) * t * t * t * t + 2);}
Easing.quinticEaseOut = function(t){return (t -= 1) * t * t * t * t + 1;}
Easing.quinticEaseOutIn = function(t){if (t < 0.5) return easeOut(t * 2) * 0.5; else return easeIn(t * 2 - 1) * 0.5 + 0.5;}

sineEaseIn = function(t){ return -Math.cos(t * 1.5707963267948966) + 1.0; }
sineEaseInOut = function(t) { return -0.5 * (Math.cos(3.141592653589793 * t) - 1.0); }
sineEaseOut = function(t) { return Math.sin(t * 1.5707963267948966); }
sineEaseOutIn = function(t) { if (t < 0.5) return easeOut(t * 2) * 0.5; else return easeIn(t * 2 - 1) * 0.5 + 0.5; }
