function motion()
{
	// Internal Attributes
	this.obj;
	this.iSpeedyMax;
	this.factorMultiplier;
	this.jumpIteractions;
	this.type;
	this.precision; // Class father should replace this value
	
	// Methods
	this.exec;
	this.setValues = motionSetValues;
	this.smooth = motionSmooth;
	this.smoothGetFactorCorrect = motionSmoothGetFactorCorrect;
	this.uniform = motionUniform;
	this.transform = motionTransform;
	//this.scale = motionScale;
	this.go = motionGo;
}


// Get factor to correct sum of the pixels
function motionSmoothGetFactorCorrect(refObj)
{
	// Attributes
	var coordFactorCorrect = new Object();
	var aux;
	var ac = 0;
	
	// Determine coordinate position
	this.factorMultiplier = refObj.interval.iteractions/this.iSpeedyMax;
	this.jumpIteractions = this.iSpeedyMax/(refObj.interval.iteractions-this.iSpeedyMax);
	for(var i=1; i<=refObj.interval.iteractions; i++)
	{
		if(i >= this.iSpeedyMax)
		{
			aux = ((refObj.interval.iteractions-i)*this.jumpIteractions)*this.factorMultiplier;
		}
		else
		{
			aux = (i*this.factorMultiplier);
		}
		aux = (aux*aux)+aux;
		ac += aux;
	}
	coordFactorCorrect.x = this.x/ac;
	coordFactorCorrect.y = this.y/ac;
	coordFactorCorrect.width = this.width/ac;
	coordFactorCorrect.height = this.height/ac;
	return coordFactorCorrect;
}


function motionSmooth(refObj)
{
	// Attributes
	var coordFactorCorrect = this.smoothGetFactorCorrect(refObj);
	var ac = 0;
	var aux;
	var tmpX;
	var tmpY;
	var returnData = new Object();
	
	// Determine coordinate position
	if(refObj.interval.iteraction > this.iSpeedyMax)
	{
		aux = ((refObj.interval.iteractions-refObj.interval.iteraction)*this.jumpIteractions)*this.factorMultiplier;
	}
	else
	{
		aux = (refObj.interval.iteraction*this.factorMultiplier);
	}
	tmpX = ((aux*aux)+aux)*coordFactorCorrect.x;
	tmpY = ((aux*aux)+aux)*coordFactorCorrect.y;
	tmpWidth = ((aux*aux)+aux)*coordFactorCorrect.width;
	tmpHeight = ((aux*aux)+aux)*coordFactorCorrect.height;
	
	// Position object
	if(refObj.interval.iteraction == refObj.interval.iteractions)
	{
		// Exact final position
		returnData.x = refObj.x;
		returnData.y = refObj.y;
		returnData.width = refObj.width;
		returnData.height = refObj.height;
	}
	else
	{
		// Intermediary position
		returnData.x = strToNumber(refObj.leftIdeal)+tmpX;
		returnData.y = strToNumber(refObj.topIdeal)+tmpY;
		returnData.width = strToNumber(refObj.widthIdeal)+tmpWidth;
		returnData.height = strToNumber(refObj.heightIdeal)+tmpHeight;
	}
	// Ideal values
	refObj.leftIdeal = returnData.x;
	refObj.topIdeal = returnData.y;
	refObj.widthIdeal = returnData.width;
	refObj.heightIdeal = returnData.height;
	// Round
	returnData.x = Math.round(returnData.x);
	returnData.y = Math.round(returnData.y);
	returnData.width = Math.round(returnData.width);
	returnData.height = Math.round(returnData.height);
	// Number to pixel
	returnData.x = numberToPixel(returnData.x);
	returnData.y = numberToPixel(returnData.y);
	returnData.width = numberToPixel(returnData.width);
	returnData.height = numberToPixel(returnData.height);
	return returnData;
}

function motionUniform(refObj)
{
	// Attributes
	var tmpX = this.x/(refObj.interval.iteractions+1);
	var tmpY = this.y/(refObj.interval.iteractions+1);
	var tmpWidth = this.width/(refObj.interval.iteractions+1);
	var tmpHeight = this.height/(refObj.interval.iteractions+1);
	var returnData = new Object();
	
	// Position object
	if(refObj.interval.iteraction == refObj.interval.iteractions)
	{
		// Exact final position
		returnData.x = Math.round(refObj.x);
		returnData.y = Math.round(refObj.y);
		returnData.width = Math.round(refObj.width);
		returnData.height = Math.round(refObj.height);
	}
	else
	{
		// Intermediary position
		returnData.x = Math.round(strToNumber(refObj.leftIdeal)+tmpX);
		returnData.y = Math.round(strToNumber(refObj.topIdeal)+tmpY);
		returnData.width = Math.round(strToNumber(refObj.widthIdeal)+tmpWidth);
		returnData.height = Math.round(strToNumber(refObj.heightIdeal)+tmpHeight);
	}
	// Ideal values
	refObj.leftIdeal = returnData.x;
	refObj.topIdeal = returnData.y;
	refObj.widthIdeal = returnData.width;
	refObj.heightIdeal = returnData.height;
	// Round
	returnData.x = Math.round(returnData.x);
	returnData.y = Math.round(returnData.y);
	returnData.width = Math.round(returnData.width);
	returnData.height = Math.round(returnData.height);
	// Number to pixel
	returnData.x = numberToPixel(returnData.x);
	returnData.y = numberToPixel(returnData.y);
	returnData.width = numberToPixel(returnData.width);
	returnData.height = numberToPixel(returnData.height);
	return returnData;
}


function motionSetValues(refObj, refMotion)
{
	// Calc Distance X to move
	var distanceX = Math.max(strToNumber(refObj.obj.style.left), refObj.x)-Math.min(strToNumber(refObj.obj.style.left), refObj.x);
	if(strToNumber(refObj.obj.style.left) > refObj.x)
	{
		distanceX *= -1;
	}
	refMotion.x = distanceX;
	// Calc Distance Y to move
	var distanceY = Math.max(strToNumber(refObj.obj.style.top), refObj.y)-Math.min(strToNumber(refObj.obj.style.top), refObj.y);
	if(strToNumber(refObj.obj.style.top) > refObj.y)
	{
		distanceY *= -1;
	}
	refMotion.y = distanceY;
	// Calc Dimension X to scale
	var dimensionX = Math.max(strToNumber(refObj.obj.style.width), refObj.width)-Math.min(strToNumber(refObj.obj.style.width), refObj.width);
	if(strToNumber(refObj.obj.style.width) > refObj.width)
	{
		dimensionX *= -1;
	}
	refMotion.width = dimensionX;
	// Calc Dimension Y to scale
	var dimensionY = Math.max(strToNumber(refObj.obj.style.height), refObj.height)-Math.min(strToNumber(refObj.obj.style.height), refObj.height);
	if(strToNumber(refObj.obj.style.height) > refObj.height)
	{
		dimensionY *= -1;
	}
	refMotion.height = dimensionY;
}


function motionTransform(refObj)
{
	var moveValues = new Object();
	// Select type of the tranformation/scalation
	if(this.type == "smoothIn")
	{
		this.iSpeedyMax = parseInt(refObj.interval.iteractions*0.7);
		moveValues = this.smooth(refObj);
	}
	else if(this.type == "smoothOut")
	{
		this.iSpeedyMax = parseInt(refObj.interval.iteractions*0.3);
		moveValues = this.smooth(refObj);
	}
	else if(this.type == "smoothInOut")
	{
		this.iSpeedyMax = parseInt(refObj.interval.iteractions*0.5);
		moveValues = this.smooth(refObj);
	}
	else if(this.type == "uniform")
	{
		this.iSpeedyMax = 0;
		moveValues = this.uniform(refObj);
	}
	if(this.obj.style.left && isPixel(moveValues.x))
		this.obj.style.left =  moveValues.x;
	if(this.obj.style.top && isPixel(moveValues.y))
		this.obj.style.top = moveValues.y;
	if(this.obj.style.width && isPixel(moveValues.width))
		this.obj.style.width =  moveValues.width;
	if(this.obj.style.height && isPixel(moveValues.height))
		this.obj.style.height = moveValues.height;
}


function motionGo(object, refMotion)
{
	refMotion.exec(object);
	object.stopFunction();
}
