/**
 * AnimateCSS.js
 * This file defines a function named animateCSS(), which serves as a framework
 * for creating CSS-based animations. The arguments to this function are:
 *	element: 	The HTML element to be animated
 *	numFrames:	The total number of frames in the animation
 *	timePerFrame:	The number of milliseconds to display each frame
 *	animation:	An object that defines the animation; described below
 *	whendone:	An optional function to call when the animation finishes.
 *			If specified, this function is passed element as its argument.
 *
 * The animateCSS() function simply defines an animation framework. It is
 * the properties of the animation object that specify the animation to be;
 * done. Each property should have the same name a a CSS style property. The
 * value of eacah property must be a function that returns values for that 
 * style property. Each function is passed the frame number and the total 
 * amount of elapsed time, and it can use these to compute the style value it
 * should return fot that frame, for example, to anmate an image so that it 
 * slides in from the upper left, you might invole animateCSS as follows:
 *
 * animateCSS(image, 25, 50, // animate image for 25 frames of 50ms each
 *		{	// Set top and left attribute for each of the frame as follows
*			top:	function(frame, time) { return frame*8 + "px';},
*			left:	function(frame, time) { return frame*8 + "px";}
*		});
*
**/
function animateCSS(element, numFrames, timePerFrame, animation, whendone) {
	var frame = 0;	// Store current frame number
	var time = 0;	// Store total elapsed time

	// Arrange to call displayNextFrame() every timePerFrame milliseconds.
	// This will display each of the frames of the animation.
	var intervalId = setInterval(displayNextFrame, timePerFrame);

	// The call to animateCSS() returns now, but the previous line ensures that 
	// the following nested function will be invoked once for each frame
	// of the anumation.
	function displayNextFrame() {
		if (frame >= numFrames) {			// Fisrt see if we're done
			clearInterval(intervalId)		// If so, stop calling ourselves
			if (whendone) whendone(element); // Invoke whendone function
			return;							// And we're finished
		}
		
		// Now loop through all properties in the animation object
		for (var cssprop in animation) {
			// For each property, call its animation function, passing the
			// frame number and the elapsed time. Use the return value of the 
			// function as new value of the corresponding style property
			// of the specified element. Use try/catch to ignore any 
			// exceptions caused by bad return values
			try {
				element.style[cssprop] = animation[cssprop](frame, time);
			} catch(e) {};
		}
		frame++;				// Increment the frame number
		time += timePerFrame;	// Increment the elapsed time
	}
}

function changeImage(img, numFrames, timePerFrame, imageChange, whendone) {
	var frame = 0;	// Store current frame number
	var time = 0;	// Store total elapsed time

	// Arrange to call displayNextFrame() every timePerFrame milliseconds.
	// This will display each of the frames of the animation.
	var intervalId = setInterval(displayNextFrame, timePerFrame);

	// The call to animateCSS() returns now, but the previous line ensures that 
	// the following nested function will be invoked once for each frame
	// of the anumation.
	function displayNextFrame() {
		if (frame >= numFrames) {			// Fisrt see if we're done
			clearInterval(intervalId)		// If so, stop calling ourselves
			if (whendone) whendone(element); // Invoke whendone function
			return;							// And we're finished
		}
		// Now loop through all properties in the animation object
		var imag = imageChange(frame, time);
		img.setAttribute("src", imag);
		img.setAttribute("alt", imag);
		frame++;				// Increment the frame number
		time += timePerFrame;	// Increment the elapsed time
	}

}


