var Tween = {};

var moving = new Array( );
Tween.Animate = function( target, easing, speed, parameters, callFunction )
{
	this.id 			= target;
	this.target 		= document.getElementById( this.id );
	this.tweenObj 		= '_tween_' + target;
    this.tweenFunction 	= '_animate_' + target;
    this.interval 		= 10;
    this.callFunction 	= callFunction;
	
    this.initVals = new Array( );
    this.initVals[0] = parseInt( this.getStyle( this.id, 'left' ) );
    this.initVals[1] = parseInt( this.getStyle( this.id, 'top' ) );
    this.initVals[2] = parseInt( this.getStyle( this.id, 'width' ) );
    this.initVals[3] = parseInt( this.getStyle( this.id, 'height' ) );
    
    this.finalVals 	= new Array( );
    this.distance 	= new Array( );
    this.step 		= new Array( );
    this.duration 	= new Array( );
    this.paramDef 	= new Array( );
    this.nullValue 	= new Array( );
    this.endTerms 	= new Array( );
    
    this.endTerms[0] = false;
    this.endTerms[1] = false;
    this.endTerms[2] = false;
    this.endTerms[3] = false;
    
    this.setDuration( speed );
    this.setFinalVals( parameters[0], parameters[1], parameters[2], parameters[3] );
    this.easingMethod = easing;
}

Tween.Animate.prototype.setDuration = function( speed )
{
    this.speed = ( 1000 / this.interval ) * speed;
}

Tween.Animate.prototype.setFinalVals = function( X, Y, W, H )
{
	if( moving[this.id] )
    {
        return;
    }

    this.finalVals[0] = X;
    this.finalVals[1] = Y;
    this.finalVals[2] = W;
    this.finalVals[3] = H;
    
    if( this.finalVals[0][0] == 0 )
    {
    	this.finalVals[0] = this.target.offsetLeft;
    }
    else if( this.finalVals[0][0] > 0 || this.finalVals[0][0] < 0 )
    {
    	this.finalVals[0] = this.target.offsetLeft + this.finalVals[0][0];
    }
    
    if( this.finalVals[1][0] == 0 )
    {
    	this.finalVals[1] = this.target.offsetTop;
    }
    else if( this.finalVals[1][0] > 0 || this.finalVals[1][0] < 0 )
    {
    	this.finalVals[1] = this.target.offsetTop + this.finalVals[1][0];
    }
    
    if( this.finalVals[2][0] == 0 )
    {
    	this.finalVals[2] = this.target.offsetWidth;
    }
    else if( this.finalVals[2][0] > 0 || this.finalVals[2][0] < 0 )
    {
    	this.finalVals[2] = this.target.offsetWidth + this.finalVals[2][0];
    }
    
    if( this.finalVals[3][0] == 0 )
    {
    	this.finalVals[3] = this.target.offsetHeight;
    }
    else if( this.finalVals[3][0] > 0 || this.finalVals[3][0] < 0 )
    {
    	this.finalVals[3] = this.target.offsetHeight + this.finalVals[3][0];
    }
    
    moving[this.id] = true;
    this.execute( );
}

Tween.Animate.prototype.ease = function( t, b, c, d )
{
	switch ( this.easingMethod )
	{
		case 'EaseIn':
			return c * Math.pow (t/d, 3) + b;	
			break;
		case 'EaseOut':
			return c * (Math.pow (t/d-1, 3) + 1) + b;	
			break;
		case 'EaseInOut':
			if ( ( t /= d/2 ) < 1)
			{
				return c/2 * Math.pow ( t, 5 ) + b;
			}
			return c/2 * ( Math.pow ( t-2, 5 ) + 2 ) + b;	
			break;
	}
}

Tween.Animate.prototype.getStyle = function( el, styleProp )
{	
	this.browser = new BrowserDetect();
	this.isSafari2 = this.browser.isSafari && this.browser.versionMajor < 421;
	
	var x = document.getElementById( el );
	if ( x.currentStyle && !this.isSafari2 )
	{
		var y = x.currentStyle[styleProp];
	}
	else if ( window.getComputedStyle && !this.isSafari2 )
	{
		var y = document.defaultView.getComputedStyle( x, null ).getPropertyValue( styleProp );
	}
	else if( this.isSafari2 )
	{
		var z = document.defaultView.getComputedStyle( x, null )
		var y = z.getPropertyValue( styleProp );
	}
	return y;
}

Tween.Animate.prototype.execute = function( )
{	
	for( var i = 0; i < this.initVals.length; i++ )
	{
		this.distance[i] 	= this.finalVals[i] - this.initVals[i];
		if( this.distance[i] != 0 )
		{
    		this.step[i] 		= this.distance[i] / this.speed;
    		this.duration[i] 	= this.distance[i] / this.step[i];
    		this.nullValue[i] 	= 0;
		}
		else
		{
			this.nullValue[i] = 1;
		}
	}
	
	var self = this;
    self.time = 0;
    
    self.tweenFunction = function( )
    {
    	self.time++;
    
    	self.paramDef[0] = parseInt( self.getStyle( self.id, 'left' ) );
    	self.paramDef[1] = parseInt( self.getStyle( self.id, 'top' ) );
    	self.paramDef[2] = parseInt( self.getStyle( self.id, 'width' ) );
    	self.paramDef[3] = parseInt( self.getStyle( self.id, 'height' ) );
    	
    	if( self.nullValue[0] )
    	{
    		self.target.style.left = parseInt( self.getStyle( self.id, 'left' ) );
    	}
    	else
    	{
    		self.target.style.left = self.ease( self.time, self.initVals[0], self.distance[0], parseInt( self.duration[0] ) ) + 'px';
    	}
    	
    	if( self.nullValue[1] )
    	{
    		self.target.style.top = parseInt( self.getStyle( self.id, 'top' ) );
    	}
    	else
    	{
    		self.target.style.top = self.ease( self.time, self.initVals[1], self.distance[1], parseInt( self.duration[1] ) ) + 'px';
    	}
    	
    	if( self.nullValue[2] )
    	{
    		self.target.style.width = parseInt( self.getStyle( self.id, 'width' ) );
    	}
    	else
    	{
    		self.target.style.width = self.ease( self.time, self.initVals[2], self.distance[2], parseInt( self.duration[2] ) ) + 'px';
    	}
 
    	if( self.nullValue[3] )
    	{
    		self.target.style.height = parseInt( self.getStyle( self.id, 'height' ) );
    	}
    	else
    	{
    		self.target.style.height = self.ease( self.time, self.initVals[3], self.distance[3], parseInt( self.duration[3] ) ) + 'px';
    	}
    	
    	for( var i = 0; i < self.initVals.length; i++ )
    	{
    		if( parseInt( self.paramDef[i] ) == self.finalVals[i] )
    		{
    			self.endTerms[i] = true;
    		}
    		if( self.endTerms[0] && self.endTerms[1] && self.endTerms[2] && self.endTerms[3] )
    		{
    			moving[self.id] = false;
    			clearInterval( self.tweenObj );
    			if( self.callFunction )
    			{
    				self.callFunction( );
    			}
    		}
    	}
    }
    self.tweenObj = setInterval( self.tweenFunction, self.interval );
}