
/* =================================================================================================
* AlphaOpacity component - by Mark Wubben
* November 2, 2003; version 1.0
* http://neo.dzygn.com/code/alphaopacity
*
* AlphaOpacity provides methods to get and set the alpha opacity on nodes, crossbrowser
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.

* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.

* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
==================================================================================================*/

//=====================================================================
// object AlphaOpacity
//=====================================================================
var AlphaOpacity = {
	//=====================================================================
	// AlphaOpacity properties (all public)
	//=====================================================================
	isSupported : null,
	isInitiated : false,

	//=====================================================================
	// AlphaOpacity properties (all private)
	//=====================================================================
	_isIE : false,
	_property : null,
	_regExpGet : null,
	_regExpSet : null,

	//=====================================================================
	// AlphaOpacity methods (all public)
	//=====================================================================
	initiate : function(oNode){
		this.isSupported = true;
		if(typeof oNode.style.MozOpacity != "undefined"){
			this._property = "MozOpacity";
		} else if(typeof oNode.style.opacity != "undefined"){
			this._property = "opacity";
		} else if(typeof oNode.style.KhtmlOpacity != "undefined"){
			this._property = "KhtmlOpacity";
		} else if(typeof oNode.style.filter != "undefined"){
			this._property = "filter";
			this._isIE = true;
			this._regExpGet = /.*opacity=([0-9]+).*/; // IE doesn't seem to understand \d
			this._regExpSet = /(.*opacity=)[0-9]+(.*)/;
		} else {
			this.isSupported = false;
		}

if( navigator.appCodeName=="Mozilla" && navigator.appVersion.substr(0,14)=="5.0 (Macintosh" ) {
	// Buggy!
			this.isSupported = false;
}

		this.isInitiated = true;
	},

	set : function(oNode, nValue){
		if(!this.isInitiated){ this.initiate(oNode); }
		if(!this.isSupported){ return null; }	

		nValue = Math.round(nValue);
		if( nValue < 0 ) nValue=100 + nValue;
		if(!this._isIE){
			oNode.style[this._property] = nValue / 100;
			return nValue;
		} else if(this.get(oNode) != null){ // In IE we could be dealing with multiple filters
			oNode.style[this._property] = (oNode.currentStyle ? oNode.currentStyle[this._property] : oNode.style[this._property]).replace(this._regExpSet, "$1" + nValue + "$2");
			return nValue;
		} else {
			oNode.style[this._property] +=  "alpha(opacity=" + nValue + ")";
			return nValue;
		}

		return null;
	},
	
	get : function(oNode){
		var sStyle;

		if(!this.isInitiated){ this.initiate(oNode); }
		if(!this.isSupported){ return null; }

		sStyle = document.defaultView ? document.defaultView.getComputedStyle(oNode, null)[this._property] : oNode.currentStyle ? oNode.currentStyle[this._property] : oNode.style[this._property];
		if(!this._isIE){
			return isNaN(sStyle) ? null : sStyle * 100;
		} else {
			return sStyle.match(this._regExpGet) ? sStyle.replace(this._regExpGet, "$1") : null;
		}
		
		return null;
	}
}









/* =================================================================================================
* Animation Engine, "Angine" - by Mark Wubben
* November 2, 2003; version 1.0
* http://neo.dzygn.com/code/angine
*
* AlphaOpacity provides methods to get and set the alpha opacity on nodes, crossbrowser
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.

* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.

* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
==================================================================================================*/

//=====================================================================
// class Angine
//=====================================================================
function Angine(iStart, iEnd, iDuration, fpOutput, oOutputScope, fpCalc, oCalcScope){
	this.iStart = iStart;
	this.iEnd = iEnd;
	this.iDelta = iEnd - iStart;
	this.iDuration = iDuration;
	this.fpOutput = fpOutput;
	this.oOutputScope = oOutputScope;
	if(fpCalc == null){
		this.fpCalc = this._defaultCalc;
		this.oCalcScope = this;
	} else {
		this.fpCalc = fpCalc;
		this.oCalcScope = oCalcScope;
	}
	this.oTime;
}

//=====================================================================
// Angine instance properties (all private)
//=====================================================================
Angine._queue = new Array();
Angine._callRate = 40;
Angine._oInterval = false;

//=====================================================================
// Angine instance methods (all private)
//=====================================================================
Angine._paint = function(){
	var oAngine, newValue;

	if(this._queue.length <= 0){
		this._stop();
		return;
	}

	for(var i = 0; i < this._queue.length; i++){
		oAngine = this._queue[i];
		
		oAngine.oTime.update();
		if(oAngine.oTime.current < oAngine.oTime.end){
			var newValue = oAngine.fpCalc.apply(oAngine.oCalcScope, new Array(oAngine));
			oAngine.fpOutput.apply(oAngine.oOutputScope, new Array(newValue, oAngine));
		} else {
			oAngine.fpOutput.apply(oAngine.oOutputScope, new Array(oAngine.iEnd, oAngine));
			oAngine.stop();
		}
	}
}

Angine._start = function(){
	if(this._oInterval == false){
		this._oInterval = setInterval("Angine._paint()", this._callRate);
	}
}

Angine._stop = function(){
	window.clearInterval(this._oInterval);
	this._oInterval = false;
}

Angine._add = function(oAngine){
	var length = this._queue.length;
	this._queue[length] = oAngine;

	if(this._queue.length == 1){
		this._start();
	}
}

Angine._remove = function(oAngine){
	for(var i = 0; i < this._queue.length; i++){
		if(oAngine == this._queue[i]){
			this._queue = this._queue.slice(0,i).concat(this._queue.slice(i+1));
			break;
		}
	}

	if(this._queue.length == 0) {
		this._stop();
	}
}

//=====================================================================
// Angine class methods (all public)
//=====================================================================
Angine.prototype = {
	start : function(){
		if(!this.oTime){
			this.oTime = new TimeObj(this.iDuration);	
		} else {
			this.oTime.reset();
		}
		Angine._add(this);
		if(this.onstart){ this.onstart(); }
	},
	
	stop : function(){
		Angine._remove(this);
		if(this.onend){ this.onend(); }		
	}
}

//=====================================================================
// Angine class methods (private)
//=====================================================================
Angine.prototype.	_defaultCalc = function(){
	return (this.oTime.getProgress() * this.iDelta);
}

//=====================================================================
// class TimeObj
//=====================================================================
function TimeObj(iDuration){
	this.start = new Date();
	this.current = this.start;
	this.end = new Date(this.start.getTime() + iDuration);
	this.duration = iDuration;
}

//=====================================================================
// TimeObj class methods (all public)
//=====================================================================
TimeObj.prototype = {
	update : function(){
		this.current = new Date();
		return this.current.getTime();
	},
	
	reset : function(){
		this.start = new Date();
		this.current = this.start;
		this.end = new Date(this.start.getTime() + this.duration);
	},
	
	getProgress : function(){
		return (this.current.getTime() - this.start.getTime()) / this.duration;
	}
}