
var Animate = new function(){
	var tween = function(obj,prop,func,begin,finish,duration,suffix,prefix){
		func = Animate[func];
		var this_tween = this;
		var starting_time = (new Date()).getTime();
		var ending_time = starting_time + (duration*1000);
		var current_update;
	
		this.update = function(){
			var now = new Date().getTime();
			var t = (now-starting_time)/1000;
			var new_pos = func(t, begin, finish-begin, duration);
			obj[prop] = prefix+new_pos+suffix;
			if(now <= ending_time){
				current_update = window.setTimeout(this_tween.update,0);
			} else{
				obj[prop]=prefix+finish+suffix;
				if(this_tween.onMotionFinished) this_tween.onMotionFinished();
				this_tween.finished = true;
				cancel();
				return true;
			}
		}
		var cancel = function(){
			if(current_update) window.clearTimeout(current_update);
			obj.tweens[prop] = false;
		}
		this.cancel=cancel;
	}
	this.Tween = function(obj, prop, func, begin, finish, duration, suffix, prefix){
		if (!arguments.length || !obj) return;
		if(!suffix) suffix = '';
		if(!prefix) prefix = '';
		// IF A TWEEN AFFECTING THE SAME PROPERTY ON THE SAME OBJECT IS ALREADY GOING ON, THEN CANCEL THAT ONE AND SET THE BEGINNING OF THIS ONE TO THE CURRENT VALUE OF THE THAT ONE
		if(obj.tweens && obj.tweens[prop]){
			obj.tweens[prop].cancel();
			begin = parseFloat(obj[prop]);
		}
		var t = new tween(obj,prop,func,begin,finish,duration,suffix,prefix);
		if(!obj.tweens)obj.tweens = [];
		obj.tweens[prop] = t;
		t.update();
		return t;
	}
	this.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;
	}
	this.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;
	}
	this.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;
	}
	this.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;
	}
	this.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);
	}
	this.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;
	}
	
	this.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;
		}
	}
	this.bounceEaseIn = function(t,b,c,d){
		return c - this.bounceEaseOut (d-t, 0, c, d) + b;
	}
	this.bounceEaseInOut = function(t,b,c,d){
		if (t < d/2) return this.bounceEaseIn (t*2, 0, c, d) * .5 + b;
		else return this.bounceEaseOut (t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
	this.strongEaseInOut = function(t,b,c,d){
		return c*(t/=d)*t*t*t*t + b;
	}
	this.regularEaseIn = function(t,b,c,d){
		return c*(t/=d)*t + b;
	}
	this.regularEaseOut = function(t,b,c,d){
		return -c *(t/=d)*(t-2) + b;
	}
	this.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;
	}
	this.strongEaseIn = function(t,b,c,d){
		return c*(t/=d)*t*t*t*t + b;
	}
	this.strongEaseOut = function(t,b,c,d){
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	}
	this.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;
	}
}



