// Written by Ian Henderson in 2005.  Copy and modify freely, as long as this line is present and unmodified.

var animationQueue = [];
var animationIntervalHandle = false;
var animationResolution = 50; // in milliseconds

function animating()
{
	return (animationIntervalHandle == false);
}

function addAnimation(animation)
{
	animationQueue.push(animation);
}

function animate(what, functionName, howLong, finishedCode)
{
	addAnimation({kind:'timed', object:what, action:functionName, duration:howLong, remaining:howLong, code:finishedCode});
	startAnimating();
}

function animateUntil(what, functionName, finishedCondition, finishedCode)
{
	addAnimation({kind:'until', object:what, action:functionName, current:0, finishedCondition:finishedCondition, code:finishedCode});
	startAnimating();
}

function startAnimating()
{
	if (!animationIntervalHandle) {
		animationIntervalHandle = window.setInterval("tick()", animationResolution);
	}
}

function stopAnimating()
{
	animationQueue = []; // drop everything you were doing
	window.clearInterval(animationIntervalHandle);
	animationIntervalHandle = false;
}

function removeAnimationAtIndex(i)
{
	var animation = animationQueue[i];
	if (animation.code) {
		eval(animation.code);
	}
	animationQueue.splice(i, 1);
}

function tick()
{
	var i;
	for (i=0; i<animationQueue.length; i++) {
		var animation = animationQueue[i];
		if (animation.kind == 'until') {
			if (eval(animation.finishedCondition)) {
				removeAnimationAtIndex(i);
				i--;
			} else {
				animation.action(animation.object, animation.current);
				animation.current += animationResolution;
			}
		} else if (animation.kind == 'timed') {
			animation.remaining -= animationResolution;
			if (animation.remaining >= 0) {
				animation.action(animation.object, 1 - (animation.remaining / animation.duration));
			}
			if (animation.remaining <= 0) {
				removeAnimationAtIndex(i);
				i--;
			}
		}
	}
	if (animationQueue.length == 0) {
		stopAnimating();
	}
}

function setAnimationResolution(seconds)
{
	animationResolution = seconds;
}
