//=====================================================================
// AccelimationAug - Accel[erated] [an]imation object 
// By youngpup.net 
// Augmented by bedrockjava.com
// change a property of an object over time in an accelerated fashion
// Cross-browser augmentation
//=====================================================================
// obj 		: reference to the object you would like to change 
// prop 	: AccelimationAug-specific value describing property to modify
//				Presently supports:
//				- AccelimationAug.OPACITY
//				- AccelimationAug.LEFT
// from   	: starting value of prop
// to   	: final value of prop
// time 	: time the animation should take to run
// zip		: optional. specify the zippiness of the acceleration. pick a 
//		 		number between -1 and 1 where -1 is full decelerated, 1 is 
//		  		full accelerated, and 0 is linear (no acceleration). default
//		  		is 0.
// unit		: optional. specify the units for use with prop. default is 
//		  			"px".
//=====================================================================
// bezier functions lifted from the lib_animation.js file in the 
// 13th Parallel API. www.13thparallel.org
//=====================================================================


function AccelimationAug(obj, prop, from, to, time, zip) 
{
	if (typeof zip  == "undefined") zip  = 0;
	if (typeof unit == "undefined") unit = "";
		
	this.obj	= obj
	this.prop	= prop;
	this.x0		= from;
	this._x1	= to;
	this.dt		= time;
	this.zip	= -zip;
	this.timer	= null;
	this.onend	= new Function();
	
	AccelimationAug.MAXOP=AccelimationAug.getOpacityMax(obj);//nothing is final in js
}

//=====================================================================
// public methods
//=====================================================================

// after you create an AccelimationAug, you call this to start it-a runnin'
AccelimationAug.prototype.start = function() 
{
	this.t0 = new Date().getTime();
	this.t1 = this.t0 + this.dt;
	var dx	= this._x1 - this.x0;
	this.c1 = this.x0 + ((1 + this.zip) * dx / 3);
	this.c2 = this.x0 + ((2 + this.zip) * dx / 3);
	AccelimationAug._add(this);
}

// and if you need to stop it early for some reason...
AccelimationAug.prototype.stop = function() 
{
	AccelimationAug._remove(this);
}

//=====================================================================
// public static methods
//=====================================================================

AccelimationAug.stopAll = function() 
{
	for (var i = 0; i < this.instances.length; i++) 
	{
		this.instances[i].stop;
	}
}
//=====================================================================
// private methods
//=====================================================================

// paints one frame. gets called by AccelimationAug._paintAll.
AccelimationAug.prototype._paint = function(time) 
{
	var elapsed = time - this.t0;
	x=AccelimationAug._getBezier(elapsed/this.dt,this.x0,this._x1,this.c1,this.c2);
	
	//=============================================================
	// This is where the augmentation is, providing
	// cross-browser(non-DOM) support for various properties
	//=============================================================
	if (time <= this.t1) 
	{
		if(this.prop==AccelimationAug.PROPERTY_OPACITY)
		{
			AccelimationAug.setOpacity(this.obj,x/.99);
		}
		
		if(this.prop==AccelimationAug.PROPERTY_LEFT)
		{
			AccelimationAug.setX(this.obj,x);
		}
		
		if(this.prop==AccelimationAug.PROPERTY_TOP)
		{
			AccelimationAug.setY(this.obj,x);
			window.status='this.x0='+this.x0+' this._x1='+this._x1+' x='+x;
		}
	}
	else
	{
		this._end();
	}
}

// ends the animation
AccelimationAug.prototype._end = function() 
{
	if(this.prop==AccelimationAug.PROPERTY_OPACITY)
	{
		AccelimationAug.setOpacity(this.obj,this._x1);
	}
	if(this.prop==AccelimationAug.PROPERTY_LEFT)
	{
		AccelimationAug.setX(this.obj,this._x1);
	}
	if(this.prop==AccelimationAug.PROPERTY_TOP)
	{
		AccelimationAug.setY(this.obj,this._x1);
	}
	if(this.prop==AccelimationAug.SIMPLE_EVENT)
	{
		//window.status=('this.eventString='+this.eventString);
		eval(this.eventString);
	}
	//this.onend();
	AccelimationAug._remove(this);
}

//=====================================================================
// static methods (all private)
//=====================================================================

// add a function to the list of ones to call periodically
AccelimationAug._add = function(o) 
{
	var index = this.instances.length;
	this.instances[index] = o;
	//window.status='adding total='+index;
	// if this is the first one, start the engine
	if (this.instances.length == 1) 
	{
		this.timerID = window.setInterval("AccelimationAug._paintAll()", this.targetRes);
	}
}

// remove a function from the list
AccelimationAug._remove = function(o) 
{
	for (var i = 0; i < this.instances.length; i++) 
	{
		if (o == this.instances[i]) 
		{
			this.instances = this.instances.slice(0,i).concat( this.instances.slice(i+1) );
			break;
		}
	}
	// if that was the last one, stop the engine
	if (this.instances.length == 0) 
	{
		window.clearInterval(this.timerID);
		this.timerID = null;
	}
}

// "engine" - call each function in the list every so often
AccelimationAug._paintAll = function() 
{
	var now = (new Date()).getTime();
	for (var i = 0; i < this.instances.length; i++) 
	{
		this.instances[i]._paint(now);
	}
}


// Bezier functions:
AccelimationAug._B1 = function(t) { return t*t*t }
AccelimationAug._B2 = function(t) { return 3*t*t*(1-t) }
AccelimationAug._B3 = function(t) { return 3*t*(1-t)*(1-t) }
AccelimationAug._B4 = function(t) { return (1-t)*(1-t)*(1-t) }


//Finds the coordinates of a point at a certain stage through a bezier curve
AccelimationAug._getBezier = function(percent,startPos,endPos,control1,control2) 
{
	return endPos * this._B1(percent) + control2 * this._B2(percent) + control1 * this._B3(percent) + startPos * this._B4(percent);
}


//=====================================================================
// static properties
//=====================================================================

AccelimationAug.instances 		= [];
AccelimationAug.targetRes 		= 40;
AccelimationAug.timerID 		= null;

AccelimationAug.PROPERTY_OPACITY=0;
AccelimationAug.PROPERTY_LEFT	=1;
AccelimationAug.PROPERTY_TOP	=2;
AccelimationAug.SIMPLE_EVENT	=3;

AccelimationAug.MAXOP			=1;

//=====================================================================
// Miscellaneous extra functions
// Simplifying Cross-browser Coding
// by bedrockjava.com
//=====================================================================
AccelimationAug.getObjRef = function(elName)
{
	if(document.all)
	{
		return document.all[elName];
	}
	else if(document.getElementById(elName))
	{
		return document.getElementById(elName);
	}
	//Still need NN4 compatibility
	return false;
}

AccelimationAug.getOpacityMax = function()
{
	if(document.all&&document.images[0].filters)
	{
		return 100;
	}
	else
	{
		return .99; // bug workaround for Safari 1.2
	}
}

AccelimationAug.setOpacity = function(obj,x)
{
	if(document.all&&obj.filters)
	{
		if(browser.isMac)//MacIE says it has filters, but doesn't deliver.
		{
			return false;
		}
		obj.filters.alpha.opacity=x;
		return true;
	}
	else if(document.getElementById)
	{
		if(obj.style&&obj.style.MozOpacity!=null)
		{
			obj.style.MozOpacity=x;
			return true;
		}
		else if(obj.style&&obj.style.opacity!=null)
		{
			obj.style.opacity=x;//Safari 1.2... lets hope every one else gets the idea 
			return true;
		}
		else if(obj.style&&obj.style.getPropertyValue&&obj.style.getPropertyValue('-khtml-opacity')!=null)
		{
			obj.style.setProperty('-khtml-opacity',x);//Safari 1.1, this was hard to find out. 
			return true;
			//obj.style.KhtmlOpacity=x;
		}
	}
	return false;
}

AccelimationAug.getOpacity = function(obj)
{
	if(document.all&&obj.filters)
	{
		if(browser.isMac)//MacIE says it has filters, but doesn't deliver.
		{
			return false;
		}
		return obj.filters.alpha.opacity;
	}
	else if(document.getElementById)
	{
		if(obj.style&&obj.style.MozOpacity!=null)
		{
			return obj.style.MozOpacity;
		}
		else if(obj.style&&obj.style.opacity!=null)
		{
			return obj.style.opacity;//Safari 1.2... lets hope every one else gets the idea 
		}
		else if(obj.style&&obj.style.getPropertyValue&&obj.style.getPropertyValue('-khtml-opacity')!=null)
		{
			return obj.style.getProperty('-khtml-opacity');//Safari 1.1, this was hard to find out. 
		}
	}
	return false;
}

AccelimationAug.setX = function(obj,x)
{
	if(document.all){obj.style.pixelLeft=x;return;}
	if(document.getElementById){obj.style.left=x+"px";return;}
	if(document.layers){obj.left=x;}
}
AccelimationAug.setY = function(obj,y)
{
	if(document.all){obj.style.pixelTop=y;return;}
	if(document.getElementById){obj.style.top=y+"px";return;}
	if(document.layers){obj.top=y;}
}
AccelimationAug.setWidth = function(obj,w)
{
	if(document.all){obj.style.width=w;return;}
	if(document.getElementById){obj.style.width=w+"px";return;}
	if(document.layers){obj.width=w;}
}
AccelimationAug.setHeight = function(obj,h)
{
	if(document.all){obj.style.height=h;return;}
	if(document.getElementById){obj.style.height=h+"px";return;}
	if(document.layers){obj.height=h;}
}
AccelimationAug.show = function(obj)
{
	if(document.all){obj.style.visibility='visible';}
	else if(document.getElementById){obj.style.visibility='visible';}
	else if(document.layers){obj.visibility='show';}
}
AccelimationAug.hide = function(obj)
{
	if(document.all){obj.style.visibility='hidden';}
	else if(document.getElementById){obj.style.visibility='hidden';}
	else if(document.layers)obj.visibility='hide';
}
AccelimationAug.getX = function(obj)
{
	if(document.all)
	{
		return obj.style.pixelLeft;
	}
	if(document.getElementById)
	{
		var xValue = obj.style.left;
		var pxIndex = xValue.indexOf('px');
		if(pxIndex!=-1)
		{
			xValue = xValue.substring(0,pxIndex);
		}
		return xValue;
	}
	if(document.layers)
	{
		return obj.left;
	}
}
AccelimationAug.getY = function(obj)
{
	if(document.all)
	{
		return obj.style.pixelTop;
	}
	if(document.getElementById)
	{
		var yValue = obj.style.top;
		var pxIndex = yValue.indexOf('px');
		if(pxIndex!=-1)
		{
			yValue = yValue.substring(0,pxIndex);
		}
		//alert('returning '+yValue); 
		return yValue;
	}
	if(document.layers)
	{
		return obj.top;
	}
}
AccelimationAug.setClip = function(obj,t,r,b,l)
{
	if(document.all || document.getElementById)
	{
		obj.style.clip="rect("+t+"px "+r+"px "+b+"px "+l+"px)";
	}
	if(document.layers)
	{
		obj.css.clip.top=t; 
		obj.css.clip.right=r; 
		obj.css.clip.bottom=b; 
		obj.css.clip.left=l;
	}
}

AccelimationAug.findPosX = function(obj) //thanks to quirksmode findPosX(bjectRef('projects_image_link'))
{
	if(document.layers)return 0;
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

AccelimationAug.setZIndex = function(obj,x)
{
	if(document.all){obj.style.zIndex=x;return;}
	if(document.getElementById){obj.style.zIndex=x;return;}
}



