
/*
    
    function test() {
		var anim = CSNGAnim.create({
			objectId: "test",
			property: "left",
			speed: 10,
			steps: 20,
			start: 0,
			stop: 80
		});
		anim.start();
    }
     

 */

if (typeof(CSNGAnim) == 'undefined') {
	CSNGAnim = {
		curAnims: Array(),
		
		isIE: (window.navigator.userAgent.indexOf("MSIE") != -1),
		isIE6: (parseFloat(window.navigator.userAgent.substring(window.navigator.userAgent.indexOf("MSIE ") + 5)) <= 6),

		proxy: function(index) {
			if (index != -1) {
				var anim = this.curAnims[index];
				anim.runStep();
			}
		},
		
		create: function(info) { /*objectId, property, start, stop, steps, speed) {*/
			if (info.steps == undefined) {
				info.steps = Math.abs(info.start - info.stop);
			}
			
			if (info.autoDelete == undefined)
				info.autoDelete = true;
				
			if (info.onComplete == undefined)
				info.onComplete = function() { };
				
			if (info.animFunc == undefined)
				info.animFunc = easeOutCubic;
			
			var newAnim = {
				proxyIndex: -1,
				curStep: 0,
				numSteps: info.steps,
				startValue: info.start,
				stopValue: info.stop,
				objProp: info.property,
				object: document.getElementById(info.objectId),
				animSpeed: info.speed,
				isRunning: false,
				deleteOnCompletion: info.autoDelete,
				onComplete: info.onComplete,
				animFunc: info.animFunc,
				
				reset: function() {
					this.curStep = 0;
				},
				start: function() {
					this.isRunning = true;
					setTimeout('CSNGAnim.proxy(' + this.proxyIndex + ')', this.animSpeed);
					
				},
				stop: function() {
					this.isRunning = false;
				},
				runStep: function() {
					if (this.isRunning) {
						this.curStep++;
						
						var dist = (this.stopValue - this.startValue);
						//var value = this.startValue + (dist * (this.curStep / this.numSteps));
						
						var value = this.animFunc(this.curStep, this.startValue, dist, this.numSteps);
						this.update(value);
						
						if (this.curStep >= this.numSteps) {
							this.isRunning = false;
						}
						
						if (this.isRunning) {
							setTimeout('CSNGAnim.proxy(' + this.proxyIndex + ')', this.animSpeed);
						} else if (this.deleteOnCompletion) {
							CSNGAnim.curAnims[this.proxyIndex] = null;
							this.proxyIndex = -1;
						}
						
						if (!this.isRunning) {this.onComplete();}
					}
				},
				update: function(value) {
					eval('CSNGAnim.curAnims[' + this.proxyIndex + '].object.style.' + this.objProp + ' = "' + value + 'px"');
				}
			};
			
			this.curAnims.push(newAnim);
			newAnim.proxyIndex = this.curAnims.length - 1;
			return newAnim;
		}
	};
	
	/**
	* Generates linear tween with constant velocity and no acceleration.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function linear(t, b, c, d) {
		return c*t/d+b;
	}
	
	/**
	* Generates quadratic, or "normal" easing in tween where equation for motion is based on a squared variable.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInQuad(t, b, c, d) {
		return c*(t /= d)*t+b;
	}
	
	/**
	* Generates quadratic, or "normal" easing out tween where equation for motion is based on a squared variable.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutQuad(t, b, c, d) {
		return -c*(t /= d)*(t-2)+b;
	}
	
	/**
	* Generates quadratic, or "normal" easing in-out tween (two half tweens fused together) where equation for motion is based on a squared variable.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInOutQuad(t, b, c, d) {
		if ((t /= d/2)<1) {
			return c/2*t*t+b;
		}
		return -c/2*((--t)*(t-2)-1)+b;
	}
	
	/**
	* Generates exponential (sharp curve) easing in tween where equation for motion is based on the number 2 raised to a multiple of 10.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInExpo(t, b, c, d) {
		return (t == 0) ? b : c*Math.pow(2, 10*(t/d-1))+b;
	}
	
	/**
	* Generates exponential (sharp curve) easing out tween where equation for motion is based on the number 2 raised to a multiple of 10.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutExpo(t, b, c, d) {
		return (t == d) ? b+c : c*(-Math.pow(2, -10*t/d)+1)+b;
	}
	
	/**
	* Generates exponential (sharp curve) easing in-out tween where equation for motion is based on the number 2 raised to a multiple of 10.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInOutExpo(t, b, c, d) {
		if (t == 0) {
			return b;
		}
		if (t == d) {
			return b+c;
		}
		if ((t /= d/2)<1) {
			return c/2*Math.pow(2, 10*(t-1))+b;
		}
		return c/2*(-Math.pow(2, -10*--t)+2)+b;
	}
	
	/**
	* Generates exponential (sharp curve) easing out-in tween where equation for motion is based on the number 2 raised to a multiple of 10.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutInExpo(t, b, c, d) {
		if (t == 0) {
			return b;
		}
		if (t == d) {
			return b+c;
		}
		if ((t /= d/2)<1) {
			return c/2*(-Math.pow(2, -10*t)+1)+b;
		}
		return c/2*(Math.pow(2, 10*(t-2))+1)+b;
	}
	
	/**
	* Generates elastic easing in tween where equation for motion is based on Hooke's Law of <code>F = -kd</code>.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @param a		(optional) amplitude, or magnitude of wave's oscillation
	* @param p		(optional) period
	* @return		position
	*/
	function easeInElastic(t, b, c, d, a, p) {
		var s;
		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;
			s = p/4;
		} else {
			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;
	}
	
	/**
	* Generates elastic easing out tween where equation for motion is based on Hooke's Law of <code>F = -kd</code>.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @param a		(optional) amplitude, or magnitude of wave's oscillation
	* @param p		(optional) period
	* @return		position
	*/
	function easeOutElastic(t, b, c, d, a, p) {
		var s;
		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;
			s = p/4;
		} else {
			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);
	}
	
	/**
	* Generates elastic easing in-out tween where equation for motion is based on Hooke's Law of <code>F = -kd</code>.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @param a		(optional) amplitude, or magnitude of wave's oscillation
	* @param p		(optional) period
	* @return		position
	*/
	function easeInOutElastic(t, b, c, d, a, p) {
		var s;
		if (t == 0) {
			return b;
		}
		if ((t /= d/2) == 2) {
			return b+c;
		}
		if (!p) {
			p = d*(.3*1.5);
		}
		if (!a || a<Math.abs(c)) {
			a = c;
			s = p/4;
		} else {
			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;
	}
	
	/**
	* Generates elastic easing out-in tween where equation for motion is based on Hooke's Law of <code>F = -kd</code>.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @param a		(optional) amplitude, or magnitude of wave's oscillation
	* @param p		(optional) period
	* @return		position
	*/
	function easeOutInElastic(t, b, c, d, a, p) {
		var s;
		if (t == 0) {
			return b;
		}
		if ((t /= d/2) == 2) {
			return b+c;
		}
		if (!p) {
			p = d*(.3*1.5);
		}
		if (!a || a<Math.abs(c)) {
			a = c;
			s = p/4;
		} else {
			s = p/(2*Math.PI)*Math.asin(c/a);
		}
		if (t<1) {
			return .5*(a*Math.pow(2, -10*t)*Math.sin((t*d-s)*(2*Math.PI)/p))+c/2+b;
		}
		return c/2+.5*(a*Math.pow(2, 10*(t-2))*Math.sin((t*d-s)*(2*Math.PI)/p))+b;
	}
	
	/**
	* Generates tween where target backtracks slightly, then reverses direction and moves to position.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @param s		(optional) controls amount of overshoot, with higher value yielding greater overshoot.
	* @return		position
	*/
	function easeInBack(t, b, c, d, s) {
		if (s == undefined) {
			s = 1.70158;
		}
		return c*(t /= d)*t*((s+1)*t-s)+b;
	}
	
	/**
	* Generates tween where target moves and overshoots final position, then reverse direction to reach final position.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @param s		(optional) controls amount of overshoot, with higher value yielding greater overshoot.
	* @return		position
	*/
	function easeOutBack(t, b, c, d, s) {
		if (s == undefined) {
			s = 1.70158;
		}
		return c*((t=t/d-1)*t*((s+1)*t+s)+1)+b;
	}
	
	/**
	* Generates tween where target backtracks slightly, then reverses direction towards final position, overshoots final position, then ultimately reverses direction to reach final position.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @param s		(optional) controls amount of overshoot, with higher value yielding greater overshoot.
	* @return		position
	*/
	function easeInOutBack(t, b, c, d, s) {
		if (s == undefined) {
			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;
	}
	
	/**
	* Generates tween where target moves towards and overshoots final position, then ultimately reverses direction to reach its beginning position.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @param s		(optional) controls amount of overshoot, with higher value yielding greater overshoot.
	* @return		position
	*/
	function easeOutInBack(t, b, c, d, s) {
		if (s == undefined) {
			s = 1.70158;
		}
		if ((t /= d/2)<1) {
			return c/2*(--t*t*(((s *= (1.525))+1)*t+s)+1)+b;
		}
		return c/2*(--t*t*(((s *= (1.525))+1)*t-s)+1)+b;
	}
	
	/**
	* Generates easing out tween where target bounces before reaching final position.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutBounce(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;
		}
	}
	
	/**
	* Generates easing in tween where target bounces upon entering the animation and then accelarates towards its final position.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInBounce(t, b, c, d) {
		return c-easeOutBounce(d-t, 0, c, d)+b;
	}
	
	/**
	* Generates easing in-out tween where target bounces upon entering the animation and then accelarates towards its final position.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInOutBounce(t, b, c, d) {
		if (t<d/2) {
			return easeInBounce(t*2, 0, c, d)*.5+b;
		} else {
			return easeOutBounce(t*2-d, 0, c, d)*.5+c*.5+b;
		}
	}
	
	/**
	* Generates easing out-in tween where target bounces upon entering the animation and then accelarates towards its final position.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutInBounce(t, b, c, d) {
		if (t<d/2) {
			return easeOutBounce(t*2, 0, c, d)*.5+b;
		}
		return easeInBounce(t*2-d, 0, c, d)*.5+c*.5+b;
	}
	
	/**
	* Generates cubic easing in tween where equation for motion is based on the power of three and is a bit more curved than a quadratic ease.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInCubic(t, b, c, d) {
		return c*(t /= d)*t*t+b;
	}
	
	/**
	* Generates cubic easing out tween where equation for motion is based on the power of three and is a bit more curved than a quadratic ease.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutCubic(t, b, c, d) {
		return c*((t=t/d-1)*t*t+1)+b;
	}
	
	/**
	* Generates cubic easing in-out tween where equation for motion is based on the power of three and is a bit more curved than a quadratic ease.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInOutCubic(t, b, c, d) {
		if ((t /= d/2)<1) {
			return c/2*t*t*t+b;
		}
		return c/2*((t -= 2)*t*t+2)+b;
	}
	
	/**
	* Generates cubic easing out-in tween where equation for motion is based on the power of three and is a bit more curved than a quadratic ease.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutInCubic(t, b, c, d) {
		t /= d/2;
		return c/2*(--t*t*t+1)+b;
	}
	
	/**
	* Generates quartic easing in tween where equation for motion is based on the power of four and feels a bit "other-worldly" as the acceleration becomes more exaggerated.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInQuart(t, b, c, d) {
		return c*(t /= d)*t*t*t+b;
	}
	
	/**
	* Generates quartic easing out tween where equation for motion is based on the power of four and feels a bit "other-worldly" as the acceleration becomes more exaggerated.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutQuart(t, b, c, d) {
		return -c*((t=t/d-1)*t*t*t-1)+b;
	}
	
	/**
	* Generates quartic easing in-out tween where equation for motion is based on the power of four and feels a bit "other-worldly" as the acceleration becomes more exaggerated.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInOutQuart(t, b, c, d) {
		if ((t /= d/2)<1) {
			return c/2*t*t*t*t+b;
		}
		return -c/2*((t -= 2)*t*t*t-2)+b;
	}
	
	/**
	* Generates quartic easing out-in tween where equation for motion is based on the power of four and feels a bit "other-worldly" as the acceleration becomes more exaggerated.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutInQuart(t, b, c, d) {
		if ((t /= d/2)<1) {
			return -c/2*(--t*t*t*t-1)+b;
		}
		return c/2*(--t*t*t*t+1)+b;
	}
	
	/**
	* Generates quartic easing in tween where equation for motion is based on the power of five and motion starts slow and becomes quite fast in what appears to be a fairly pronounced curve.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInQuint(t, b, c, d) {
		return c*(t /= d)*t*t*t*t+b;
	}
	
	/**
	* Generates quartic easing out tween where equation for motion is based on the power of five and motion starts slow and becomes quite fast in what appears to be a fairly pronounced curve.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutQuint(t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t+1)+b;
	}
	
	/**
	* Generates quartic easing in-out tween where equation for motion is based on the power of five and motion starts slow and becomes quite fast in what appears to be a fairly pronounced curve.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInOutQuint(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;
	}
	
	/**
	* Generates quartic easing out-in tween where equation for motion is based on the power of five and motion starts slow and becomes quite fast in what appears to be a fairly pronounced curve.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutInQuint(t, b, c, d) {
		t /= d/2;
		return c/2*(--t*t*t*t*t+1)+b;
	}
	
	/**
	* Generates sinusoidal easing in tween where equation for motion is based on a sine or cosine function.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInSine(t, b, c, d) {
		return -c*Math.cos(t/d*(Math.PI/2))+c+b;
	}
	
	/**
	* Generates sinusoidal easing out tween where equation for motion is based on a sine or cosine function.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutSine(t, b, c, d) {
		return c*Math.sin(t/d*(Math.PI/2))+b;
	}
	
	/**
	* Generates sinusoidal easing in-out tween where equation for motion is based on a sine or cosine function.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInOutSine(t, b, c, d) {
		return -c/2*(Math.cos(Math.PI*t/d)-1)+b;
	}
	
	/**
	* Generates sinusoidal easing out-in tween where equation for motion is based on a sine or cosine function.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutInSine(t, b, c, d) {
		if ((t /= d/2)<1) {
			return c/2*(Math.sin(Math.PI*t/2))+b;
		}
		return -c/2*(Math.cos(Math.PI*--t/2)-2)+b;
	}
	
	/**
	* Generates circular easing in tween where equation for motion is based on the equation for half of a circle, which uses a square root.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInCirc(t, b, c, d) {
		return -c*(Math.sqrt(1-(t /= d)*t)-1)+b;
	}
	
	/**
	* Generates circular easing out tween where equation for motion is based on the equation for half of a circle, which uses a square root.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutCirc(t, b, c, d) {
		return c*Math.sqrt(1-(t=t/d-1)*t)+b;
	}
	
	/**
	* Generates circular easing in-out tween where equation for motion is based on the equation for half of a circle, which uses a square root.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeInOutCirc(t, b, c, d) {
		if ((t /= d/2)<1) {
			return -c/2*(Math.sqrt(1-t*t)-1)+b;
		}
		return c/2*(Math.sqrt(1-(t -= 2)*t)+1)+b;
	}
	
	/**
	* Generates circular easing out-in tween where equation for motion is based on the equation for half of a circle, which uses a square root.
	* @param t		time
	* @param b		beginning position
	* @param c		total change in position
	* @param d		duration of the tween
	* @return		position
	*/
	function easeOutInCirc(t, b, c, d) {
		if ((t /= d/2)<1) {
			return c/2*Math.sqrt(1- --t*t)+b;
		}
		return c/2*(2-Math.sqrt(1- --t*t))+b;
	}
}
