// main Tween object
Tween =
{
	init: function(obj, prop, duration, method, sufix)
	{
		// validate user input
		if (!obj) return false;
		
		// set values
		this.duration	= duration | 1;
		this.current	= 0;
		this.obj 		= obj;
		this.prop		= prop || {};
		this.method		= method || Tween.easing.easeNone;
		this.sufix		= sufix || '';
	},
	
	next: function(obj, prop, duration, method, sufix)
	{
		this.init(obj, prop, duration, method, sufix);
		this.onAction = Class.E;
		this.onStop	= Class.E;
		this.start();
	},
	
	start: function(back)
	{
		// translate propertios
		this.att = {};
		for (val in this.prop)
		{
			if (!back)
			{
				var start	= typeof(this.prop[val]) != 'number' ? this.prop[val][0] : parseFloat(this.obj[val]);
				var end		= typeof(this.prop[val]) != 'number' ? this.prop[val][1] : this.prop[val];
			}
			else
			{
				var start	= typeof(this.prop[val]) != 'number' ? this.prop[val][1] : this.prop[val];
				var end		= typeof(this.prop[val]) != 'number' ? this.prop[val][0] : parseFloat(this.obj[val]);
			}
			
			var diff	= end - start;
			this.att[val] = {
							start: start,
							diff: diff
							};
		}
		
		// start animation
		this.current = 0;
		this.action();
	},
	
	action: function()
	{
		// preform action
		for (val in this.att)
		{
			this.obj[val] = this.method(this.current, this.att[val].start, this.att[val].diff, this.duration) + this.sufix;		
		}
		
		this.current++;
	
		// init on action 
		this.onAction();
			
		// animation
		if (this.current < this.duration)
		{
			setTimeout("Tween.action();", 1);
		}
		else
		{
			// set to end position(just in case)
			for (val in this.att)
			{
				this.obj[val] = this.att[val].start + this.att[val].diff + this.sufix;	
			}
			
			this.stop();
		}
	},
	
	stop: function()
	{
		// stop animation
		clearTimeout();
		
		// init on stop action
		this.onStop();
	},
	
	onAction: Class.E,
	onStop: Class.E
}


/**
 * @desc					:	Tween animation formulas(all function have same arguments)
 * @param	t	:	number	:	Time value used to compute current value.
 * @param	b	:	number	:	Starting value.
 * @param	c	:	number	:	Delta between start and end values.
 * @param	d	:	number	:	Total length of animation.
 * @return		:	number	:	The computed value for the current animation frame.
 * @credits					:	Yahoo!'s yui
 */
Tween.easing = 
{
	// Uniform speed between points.
	easeNone: function(t, b, c, d)
	{
		return b+c*(t/=d);
	},
 
	// Begins slowly and accelerates towards end.
 	easeIn: function(t, b, c, d)
 	{
 		return b+c*((t/=d)*t*t);
 	},
 
	// Begins quickly and decelerates towards end.
	easeOut: function(t, b, c, d)
	{
		var ts=(t/=d)*t;
		var tc=ts*t;
		return b+c*(tc + -3*ts + 3*t);
	},
 
	// Begins slowly and decelerates towards end.
	easeBoth: function(t, b, c, d)
	{
	 	var ts=(t/=d)*t;
	 	var tc=ts*t;
	 	return b+c*(-2*tc + 3*ts);
	},
 

	// Begins by going below staring value.
	backIn: function(t, b, c, d)
	{
	 	var ts=(t/=d)*t;
	 	var tc=ts*t;
	 	return b+c*(-3.4005*tc*ts + 10.2*ts*ts + -6.2*tc + 0.4*ts);
	},
 
	// End by going beyond ending value.
	backOut: function(t, b, c, d)
	{
	 	var ts=(t/=d)*t;
	 	var tc=ts*t;
	 	return b+c*(8.292*tc*ts + -21.88*ts*ts + 22.08*tc + -12.69*ts + 5.1975*t);
	},
 
	// Starts by going below staring value, and ends by going beyond ending value.
	backBoth: function(t, b, c, d)
	{
	 	var ts=(t/=d)*t;
	 	var tc=ts*t;
	 	return b+c*(0.402*tc*ts + -2.1525*ts*ts + -3.2*tc + 8*ts + -2.05*t);
	}
};

// Tween animations(contols)
Tween.Controls = 
{
	scrollTo: function(obj, duration, method)
	{
		obj = $('obj')
		
		Position.prepare();
		var prop  = 
		{
			scrollx: [Position.deltaX, point.x || point.offsetLeft],
      		scrolly: [Position.deltaY, point.y || point.offsetTop]
		}
		
		Tween.init(obj, prop, duration, method);
		Tween.start();
		Tween.onAction = function()
		{
			window.scrollTo(Tween.obj.scrollx, Tween.obj.scrolly);
		}
		Tween.onStop = function()
		{
			Element.scrollTo(Tween.obj);
		}
	},
	
	show: function(obj, parent, duration, method, action, stop)
	{
		Tween.init(obj.style, {'margin': obj.offsetHeight}, duration, method, 'px');
		Tween.onAction	= action || Tween.onAction;
		Tween.onStop	= stop || Tween.onStop;
		Tween.start();
	},
	
	hide: function(obj, parent, duration, method, action, stop)
	{
		Tween.init(obj.style, {'margin': -obj.offsetHeight}, duration, method, 'px');
		Tween.onAction	= action || Tween.onAction;
		Tween.onEnd		= end || Tween.onEnd;
		Tween.start();
	},
	
	toggle: function(obj, parent, duration, method, action, stop)
	{
		Tween.init(obj.style, {'margin': -obj.offsetHeight}, duration, method, 'px');
		Tween.onAction	= action || Tween.onAction;
		Tween.onStop	= stop || Tween.onStop;
		Tween.start(parseFloat(obj.style.margin) > -obj.offsetHeight ? 0 : 1);
	}, 
	
	fade: function(obj)
	{
	},
	
	appear: function(obj)
	{
	},
	
	moveTo: function(obj, x, y, duration, method, action, stop)
	{
		Tween.init(obj.style, {'top': x, 'left': y}, duration, method, 'px');
		Tween.onAction	= action || Tween.onAction;
		Tween.onStop	= stop || Tween.onStop;
		Tween.start();
	},

	text: function(obj, prop, duration, method)
	{
	}
}