// JavaScript Document
var fps = 40;
var isIE = (navigator.appName == "Microsoft Internet Explorer");
var tweenManager;

function TweenManager(){
	this.tweens;
	
	this.init = function(){
		this.tweens = [];
	}
	
	this.push = function(tween){
		this.tweens.push(tween);
	}
	
	this.remove = function(tween){
		//var i = this.tweens.indexOf(tween);
		var i = this.indexOf(tween);
		this.tweens.splice(i, 1);
	}
	
	this.removeAll = function(){
		var l = this.tweens.length;
		for(var i=0;i<l;i++){
			this.tweens.pop();
		}
	}
	
	this.showAllTweens = function(){
		var l = this.tweens.length;
		for(var i=0;i<l;i++){
			var str ="";
			for(var n in this.tweens[i].target){
				str += n+" :: "+this.tweens[i].target[n]+" \n";
			}
			alert(str);
		}
	}
	
	this.stopTween = function(tween){
		if(tween != null){ tween.stop(); }
	}
	
	this.stopAllTweens = function(tween){
		var l=this.tweens.length;
		for(var i=0;i<l;i++){
			this.stopTween(this.tweens[i]);
		}
	}
	
	this.indexOf = function(tween){
		var l = this.tweens.length;
		for(var i=0;i<l;i++){
			if(this.tweens[i] == tween){
				return i;
			}
		}
		return null;
	}
	
	this.init();
}


function Tween(target,time,tweenProps,otherProps){
	this.target = target;
	this.timer;
	
	this.duration = time;
	this.time = 0;
	this.startTime = 0;
	
	this.tweenProps = tweenProps;
	this.otherProps = otherProps;
	this.tweens;
	this.stepsTaken;
	this.stepsToTake;
	this.ease = "linear";
	
	this.init = function(){
		var thisObj = this;
		
		if(tweenManager == null){
			tweenManager = new TweenManager();
		}
		
		this.initTweens(this.stepsToTake);
		tweenManager.push(this);
		
		if(this.otherProps != null){
			if("ease" in this.otherProps){ this.ease = this.otherProps.ease; }
			if("delay" in this.otherProps){ this.timer = setInterval(function(){ thisObj.startTween() }, thisObj.otherProps.delay); }
		}else{
			this.startTween();
		}
	}
	
	this.startTween = function(){
		this.startTime = this.getTimer();
		
		if(this.timer != null){
			clearInterval(this.timer);
			this.timer = null;
		}
		
		var thisObj = this;
		this.fireCallback("startListener");
		this.timer = setInterval(function(){ thisObj.onEnterFrame() }, 1000/fps);
	}
	
	this.fireCallback = function(p_listener){
		if(this.otherProps != null && this.otherProps.scope != null && this.otherProps[p_listener] != null && this.otherProps[p_listener] != ""){
			this.otherProps.scope[this.otherProps[p_listener]](this);
		}
	}
	
	this.initTweens = function(p_numSteps){
		this.stepsTaken = 0;
		this.tweens = [];
		for(var n in this.tweenProps){
			var obj = new Object();
			obj.prop = n;
			obj.endVal = this.tweenProps[n];
			
			if(typeof(this.target.style[n] == "string")){
				//alert("IS STRING ::: "+this.target.style[n]);
				if(this.target.style[n] == ""){
					obj.begin = 0;
					if(obj.prop == "opacity" && obj.endVal == 0){
						obj.begin = 1;
					}
				}else{
					if(obj.prop != "opacity"){
						obj.begin = parseInt(this.target.style[n]);
					}else if(isIE){
						//alert("PARSE INT :: "+this.target.filters.alpha.opacity);
						obj.begin = this.target.filters.alpha.opacity;
						if(obj.begin > 0){
							obj.begin/= 100;
						}
						//alert("BEGIN ::: "+obj.begin);
					}else{
						obj.begin = parseInt(this.target.style[n]);
						//console.log("INIT :: "+obj.begin);
					}
				}
			}else{
				obj.begin = this.target.style[n];
			}
			
			obj.change = obj.endVal - obj.begin;
			obj.distancePerFrame = Math.abs((obj.endVal - obj.begin)/p_numSteps);
			obj.current = obj.begin;
			obj.dir = 1;
			if(obj.endVal < obj.begin){ obj.dir = -1; }
			this.tweens.push(obj);
		}
	}
	
	this.onEnterFrame = function(){
		this.setTime((this.getTimer() - this.startTime) / 1000);
		this.fireCallback("progressStartListener");
	
		var style = this.target.style;
		
		var l = this.tweens.length;
		for(var i = 0;i<l;i++){
			var prop = this.tweens[i].prop;
			var val = Tween[this.ease](this.time,this.tweens[i].begin,this.tweens[i].change,this.duration/1000);
						
			switch(prop){
				case "left": case "top": case "bottom": case "right": 
					style[prop] = String(val)+"px";
					break;
				case "opacity":
					if(val < 0) val += 1;
					if(!isIE){
						//if(this.tweens[i].begin == 1) console.log("ENTER FRAME ::: "+val+" ::: "+this.tweens[i].endVal);
						style[prop] = val;
					}else{
						if(this.target.filters.alpha != undefined){
							this.target.filters.alpha.opacity = val * 100;
							//var myVal = Math.round(val * 100);
							//if(myVal < 1){ myVal = 1; }
							//this.target.style.filter  = "alpha(opacity=" + myVal + ")";

							//alert("FADE ::: "+this.target.filters.alpha.opacity);
						}else{
							//this.target.filters = "alpha(opacity=0)";
							//alert("ELSE :: "+this.target.style.filters+" ::: "+val);
						}
					}
					break;
				default:
					style[prop] = val;
					break;
			}
		}
		this.fireCallback("progressListener");
		
		if(this.time >= (this.duration/1000)){
			this.endInterval();	
		}
	}
	
	this.endInterval = function(){
		clearInterval(this.timer);
		this.timer = null;
		this.finalize();
	}
	
	this.finalize = function(){
		var style = this.target.style;
		var l = this.tweens.length;
		for(var i = 0;i<l;i++){
			var prop = this.tweens[i].prop;
			switch(prop){
				case "left": case "top": case "bottom": case "right": 
					style[prop] = String(this.tweens[i].endVal)+"px";
					break;
				case "opacity":
					if(!isIE){
						style[prop] = this.tweens[i].endVal;
					}else{
						if(this.target.filters.alpha != undefined){
							//if(this.tweens[i].endVal == 0){
							//	this.target.filters.alpha.opacity = 100;
								//this.target.style.filter = "alpha(opacity=1)";
							//}else{
								this.target.filters.alpha.opacity = this.tweens[i].endVal * 100;
								//this.target.style.filter = "alpha(opacity=" + this.tweens[i].endVal * 100 + ")";
							//}
							//alert(this.tweens[i].endVal);
							//alert("FADE ::: "+this.target.filters.alpha.opacity);
						}else{
							//this.target.filters = "alpha(opacity=0)";
							//alert("ELSE :: "+this.target.style.filters+" ::: "+val);
						}
					}
					break;
				default:
					style[prop] = this.tweens[i].endVal;
					break;
			}

			
		}
		tweenManager.remove(this);
		this.fireCallback("completeListener");
	}
	
	this.getTimer = function(){
		return new Date().getTime() - this.time;
	}
	
	this.setTime = function(p_time){
		this.time = p_time;
	}
	
	this.stop = function(){
		this.endInterval();
	}

	this.init();
}

/* borrowed easing functionality */
Tween.backEaseIn = function(t,b,c,d,a,p){
	if (s == undefined) var s = 1.70158;
	return c*(t/=d)*t*((s+1)*t - s) + b;
}
Tween.backEaseOut = function(t,b,c,d,a,p){
	if (s == undefined) var s = 1.70158;
	return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
}
Tween.backEaseInOut = function(t,b,c,d,a,p){
	if (s == undefined) var s = 1.70158; 
	if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
	return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
}
Tween.elasticEaseIn = function(t,b,c,d,a,p){
		if (t==0) return b;  
		if ((t/=d)==1) return b+c;  
		if (!p) p=d*.3;
		if (!a || a < Math.abs(c)) {
			a=c; var s=p/4;
		}
		else 
			var s = p/(2*Math.PI) * Math.asin (c/a);
		
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	
}
Tween.elasticEaseOut = function (t,b,c,d,a,p){
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (!a || a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return (a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b);
	}
Tween.elasticEaseInOut = function (t,b,c,d,a,p){
	if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) var p=d*(.3*1.5);
	if (!a || a < Math.abs(c)) {var a=c; var s=p/4; }
	else var s = p/(2*Math.PI) * Math.asin (c/a);
	if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
}

Tween.bounceEaseOut = function(t,b,c,d){
	if ((t/=d) < (1/2.75)) {
		return c*(7.5625*t*t) + b;
	} else if (t < (2/2.75)) {
		return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
	} else if (t < (2.5/2.75)) {
		return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
	} else {
		return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
	}
}
Tween.bounceEaseIn = function(t,b,c,d){
	return c - Tween.bounceEaseOut (d-t, 0, c, d) + b;
}
Tween.bounceEaseInOut = function(t,b,c,d){
	if (t < d/2) return Tween.bounceEaseIn (t*2, 0, c, d) * .5 + b;
	else return Tween.bounceEaseOut (t*2-d, 0, c, d) * .5 + c*.5 + b;
}
Tween.strongEaseInOut = function(t,b,c,d){
	return c*(t/=d)*t*t*t*t + b;
}
Tween.regularEaseIn = function(t,b,c,d){
	return c*(t/=d)*t + b;
}
Tween.regularEaseOut = function(t,b,c,d){
	return -c *(t/=d)*(t-2) + b;
}
Tween.regularEaseInOut = function(t,b,c,d){
	if ((t/=d/2) < 1) return c/2*t*t + b;
	return -c/2 * ((--t)*(t-2) - 1) + b;
}
Tween.strongEaseIn = function(t,b,c,d){
	return c*(t/=d)*t*t*t*t + b;
}
Tween.strongEaseOut = function(t,b,c,d){
	return c*((t=t/d-1)*t*t*t*t + 1) + b;
}

Tween.strongEaseInOut = function(t,b,c,d){
	if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
	return c/2*((t-=2)*t*t*t*t + 2) + b;
}

Tween.linear = function(t,b,c,d){
	return c*(t/=d);
}
