// Simple Animation engine

var _animEngine = null;
var _animQueue = new Array();
var _animFPS = Math.round(1000/40);

function Animator() {
	// Interval-powered function that scans the animation queue and animates all relevant items
	if (_animQueue.length > 0) {
		for (var i=0;i<_animQueue.length;i++) {
			var thisobj = _animQueue[i];
			var animated = Animate(thisobj);
			if (animated == false) {
				// Engage end trigger, if present
				if (thisobj.EndTrigger != null) {
					thisobj.EndTrigger();
				}
				// Remove from queue
				thisobj.AnimateMe = false;
				_animQueue.splice(i,1);
				i--;
			}
		}
	} else {
		// No items in queue, stop engine
		window.clearInterval(_animEngine);
		_animEngine = null;
	}
}

function StartAnimation(who,tx,ty,ex,ey,sx,sy,et) {
	// Prep object for animation, set parameters, add to animation queue and engage the engine, if necessary
	if (typeof who == "undefined" || who == null || ((typeof tx == "undefined" || tx == null) && (typeof ty == "undefined" || ty == null))) {
		return null;
	} else {
		// Set animation stamp
		who.AnimateMe = true;
		if (typeof who.MyOffsetX != "undefined") {
			who.CurrentX = who.MyOffsetX;
			who.CurrentY = who.MyOffsetY;
		} else {
			who.CurrentX = _getRealX(who);
			who.CurrentY = _getRealY(who);
		}
		who.TargetX = tx;
		who.TargetY = ty;
		// Check other params
		if (typeof ex == "undefined" || ex == null || ex == 0 || isNaN(ex)) {
			// Assume default ex as 3
			who.EasingX = 3;
		}
		if (typeof ey == "undefined" || ey == null || ey == 0 || isNaN(ey)) {
			// Assume default ey as 3
			who.EasingY = 3;
		}
		if (typeof sx == "undefined" || sx == null || sx == 0 || isNaN(sx)) {
			// Assume default sx as 0
			who.SpeedX = 0;
		} else {
			// Defined speed cancels easing
			who.SpeedX = sx;
			who.EasingX = 0;
		}
		if (typeof sy == "undefined" || sy == null || sy == 0 || isNaN(sy)) {
			// Assume default sy as 0
			who.SpeedY = 0;
		} else {
			// Defined speed cancels easing
			who.SpeedY = sy;
			who.EasingY = 0;
		}
		if (typeof et == "function") {
			who.EndTrigger = et;
		} else {
			who.EndTrigger = null;
		}
		who.AnimationType = 0;
		// Add to animation queue, if not duplicate
		var isDuplicate = false;
		for (var i=0;i<_animQueue.length;i++) {
			if (_animQueue[i] == who) {
				isDuplicate = true;
				break;
			}
		}
		if (!isDuplicate) _animQueue.push(who);
		// Check if engine is running
		if (_animEngine == null) {
			// Not running, start
			_animEngine = window.setInterval(Animator,_animFPS);
		}
	}
}

function StartSizeAnimation(who,tsx,tsy,et) {
	if (typeof who == "undefined" || who == null || ((typeof tsx == "undefined" || tsx == null) && (typeof tsy == "undefined" || tsy == null))) {
		return null;
	} else {
		// Parameters ok
		who.AnimationType = 1;
		who.AnimateMe = true;
		who.CurrentWidth = who.offsetWidth;
		who.CurrentHeight = who.offsetHeight - Number((who.getAttribute("mzhdiff")!=null && isIE==false)?who.getAttribute("mzhdiff"):0);
		who.TargetWidth = (typeof tsx == "undefined" || tsx == null || isNaN(tsx))?who.CurrentWidth:tsx;
		who.TargetHeight = (typeof tsy == "undefined" || tsy == null || isNaN(tsy))?who.CurrentHeight:tsy;
		//alert(who.TargetHeight - who.CurrentHeight);
		if (typeof et != "function") {
			who.EndTrigger = null;
		} else {
			who.EndTrigger = et;
		}
		var isDuplicate = false;
		for (var i=0;i<_animQueue.length;i++) {
			if (_animQueue[i] == who) {
				isDuplicate = true;
				break;
			}
		}
		if (!isDuplicate) _animQueue.push(who);
		// Check if engine is running
		if (_animEngine == null) {
			// Not running, start
			_animEngine = window.setInterval(Animator,_animFPS);
		}
	}
}

function StartAlphaAnimation(who,sa,ta,de,sp,et) {
	if (typeof who == "undefined" || who == null || (typeof sa != "number" && typeof ta != "number")) return null;
	else {
		// Parameters
		who.AnimationType = 2;
		who.AnimateMe = true;
		who.CurrentAlpha = (sa == null)?100:sa;
		who.TargetAlpha = (ta == null)?100:ta;
		who.Delay = (typeof de != "number")?0:de;
		who.Speed = (typeof sp != "number")?0:sp;
		if (typeof et != "function") {
			who.EndTrigger = null;
		} else {
			who.EndTrigger = et;
		}
		var isDuplicate = false;
		for (var i=0;i<_animQueue.length;i++) {
			if (_animQueue[i] == who) {
				isDuplicate = true;
				break;
			}
		}
		if (!isDuplicate) _animQueue.push(who);
		// Check if engine is running
		if (_animEngine == null) {
			// Not running, start
			_animEngine = window.setInterval(Animator,_animFPS);
		}
	}
}

function Animate(who) {
	// Checks the object for animation parameters and animates, if necessary (returns "true"). If not, returns a "false".
	// Check object validity
	if (typeof who == "undefined" || who == null || who.AnimateMe != true) {
		return false;
	} else {
		// Animation permitted, check animation type
		if (who.AnimationType == 0) {
			// Type 0 - positioning animation
			var tx = who.TargetX;
			var ty = who.TargetY;
			var cx = who.CurrentX;
			var cy = who.CurrentY;
			var ex = who.EasingX;
			var ey = who.EasingY;
			var sx = who.SpeedX;
			var sy = who.SpeedY;
			var wasAnimated = false;
			// Animate
			if (tx != null && cx != tx) {
				// X animation needed
				wasAnimated = true;
				var dx = null;
				if (sx != 0 && ex == 0) {
					// Speed-animation
					dx = cx + sx;
				} else {
					// Easing animation
					dx = cx + (tx - cx)/ex;
				}
				if (ex != 0 && Math.abs(tx - dx) < 0.5) {
					dx = tx;
				} else if (sx != 0 && ((sx<0 && (tx-dx)>0) || (sx>0 && (tx-dx)<0))) {
					dx = tx;
				}
				who.CurrentX = dx;
				if (typeof who.MyOffsetX == "undefined") {
					who.style.left = Math.round(dx) + "px";
				} else {
					who.MyOffsetX = Math.round(dx);
				}
			}
			if (ty != null && cy != ty) {
				// Y animation needed
				wasAnimated = true;
				var dy = null;
				if (sy != 0 && ey == 0) {
					// Speed-animation
					dy = cy + sy;
				} else {
					// Easing animation
					dy = cy + (ty - cy)/ey;
				}
				if (ey != 0 && Math.abs(ty - dy) < 0.5) {
					dy = ty;
				} else if (sy != 0 && ((sy<0 && (ty-dy)>0) || (sy>0 && (ty-dy)<0))) {
					dy = ty;
				}
				who.CurrentY = dy;
				if (typeof who.MyOffsetY == "undefined") {
					who.style.top = Math.round(dy) + "px";
				} else {
					who.MyOffsetY = Math.round(dy);
				}
			}
			// Return animation state
			return wasAnimated;
		} else if (who.AnimationType == 1) {
			// Type 1 = sizing animation
			var cx = who.CurrentWidth;
			var cy = who.CurrentHeight;
			var tx = who.TargetWidth;
			var ty = who.TargetHeight;
			var wasAnimated = false;
			// Animate
			if (cx != tx) {
				// Width-animation
				var dx = (tx - cx)/3;
				cx += dx;
				if (Math.abs(tx - cx) < 0.5) cx = tx;
				wasAnimated = true;
			}
			if (cy != ty) {
				// Height animation
				var dy = (ty - cy)/3;
				cy += dy;
				if (Math.abs(ty - cy) < 0.5) cy = ty;
				wasAnimated = true;
			}
			if (wasAnimated) {
				who.style.width = Math.round(cx) + "px";
				who.style.height = Math.round(cy) + "px";
				who.CurrentWidth = cx;
				who.CurrentHeight = cy;
			}
			return wasAnimated;
		} else if (who.AnimationType == 2) {
			// Type 2 = alpha animation
			var ca = who.CurrentAlpha;
			var ta = who.TargetAlpha;
			var de = who.Delay;
			var sp = who.Speed;
			var wasAnimated = false;
			if (de == 0) {
				if (ca != ta) {
					wasAnimated = true;
					if (sp == 0) {
						ca += (ta - ca) / 3;
					} else {
						ca += sp;
					}
					if ((sp<0 && ca<ta) || (sp>0 && ca>ta) || (sp==0 && Math.abs(ta - ca)<0.5)) {
						ca = ta;
					}
					who.CurrentAlpha = Math.round(ca);
					SetAlpha(who,who.CurrentAlpha);
				}
			} else {
				who.Delay--;
				SetAlpha(who,ca);
				wasAnimated = true;
			}
			return wasAnimated;
		}
	}
}

function SetAlpha(obj,alpha) {
	if (isIE == true) {
		try {
			obj.style.filter = "Alpha(opacity="+alpha+")";
		} catch(e) {
		}
	} else {
		obj.style.opacity = (alpha / 100);
	}
}


