/**
 * File: animation0.js
 *
 * An Animation object.
 *
 * Usage:
 *   <script type="text/javascript" src="http://www.bgsu.edu/scripts/animation0.js">
 *   </script>
 *
 * Example:  animation0Test1.html
 *   <!-- load animation0.js -->
 *   <script type="text/javascript" src="http://www.bgsu.edu/scripts/animation0.js">
 *   </script>
 *   <!-- a juggler -->
 *   <script type="text/javascript">
 *     var juggler = new Animation( 4 );  // number of frames = 4
 *     juggler.frames[0] = "http://www.bgsu.edu/scripts/juggler0.gif";
 *     juggler.frames[1] = "http://www.bgsu.edu/scripts/juggler1.gif";
 *     juggler.frames[2] = "http://www.bgsu.edu/scripts/juggler2.gif";
 *     juggler.frames[3] = "http://www.bgsu.edu/scripts/juggler3.gif";
 *     juggler.setDelay( 200 );  // delay in milleseconds
 *     juggler.animate();
 *   </script>
 *
 * Example:  animation0Test2.html
 *   <!-- load animation0.js -->
 *   <script type="text/javascript" src="http://www.bgsu.edu/scripts/animation0.js">
 *   </script>
 *   <!-- a fast juggler, counterclockwise -->
 *   <script type="text/javascript">
 *     var jugglerLeft = new Animation( 4 );  // no. of frames
 *     jugglerLeft.frames[0] = "http://www.bgsu.edu/scripts/juggler0.gif";
 *     jugglerLeft.frames[1] = "http://www.bgsu.edu/scripts/juggler1.gif";
 *     jugglerLeft.frames[2] = "http://www.bgsu.edu/scripts/juggler2.gif";
 *     jugglerLeft.frames[3] = "http://www.bgsu.edu/scripts/juggler3.gif";
 *     jugglerLeft.setDelay( 25 );  // delay in milleseconds
 *     jugglerLeft.animate();
 *   </script>
 *   <!-- a slow juggler, counterclockwise -->
 *   <script type="text/javascript">
 *     var jugglerLeft = new Animation( 4 );  // no. of frames
 *     jugglerLeft.frames[0] = "http://www.bgsu.edu/scripts/juggler0.gif";
 *     jugglerLeft.frames[1] = "http://www.bgsu.edu/scripts/juggler1.gif";
 *     jugglerLeft.frames[2] = "http://www.bgsu.edu/scripts/juggler2.gif";
 *     jugglerLeft.frames[3] = "http://www.bgsu.edu/scripts/juggler3.gif";
 *     jugglerLeft.setDelay( 400 );  // delay in milleseconds
 *     jugglerLeft.animate();
 *   </script>
 *   <!-- a stationary juggler -->
 *   <img src="http://www.bgsu.edu/scripts/juggler1.gif">
 *   <!-- a slow juggler, clockwise -->
 *   <script type="text/javascript">
 *     var jugglerRight = new Animation( 4 );  // no. of frames
 *     jugglerRight.frames[0] = "http://www.bgsu.edu/scripts/juggler3.gif";
 *     jugglerRight.frames[1] = "http://www.bgsu.edu/scripts/juggler2.gif";
 *     jugglerRight.frames[2] = "http://www.bgsu.edu/scripts/juggler1.gif";
 *     jugglerRight.frames[3] = "http://www.bgsu.edu/scripts/juggler0.gif";
 *     jugglerRight.setDelay( 400 );  // delay in milleseconds
 *     jugglerRight.animate();
 *   </script>
 *   <!-- a fast juggler, clockwise -->
 *   <script type="text/javascript">
 *     var jugglerRight = new Animation( 4 );  // no. of frames
 *     jugglerRight.frames[0] = "http://www.bgsu.edu/scripts/juggler3.gif";
 *     jugglerRight.frames[1] = "http://www.bgsu.edu/scripts/juggler2.gif";
 *     jugglerRight.frames[2] = "http://www.bgsu.edu/scripts/juggler1.gif";
 *     jugglerRight.frames[3] = "http://www.bgsu.edu/scripts/juggler0.gif";
 *     jugglerRight.setDelay( 25 );  // delay in milleseconds
 *     jugglerRight.animate();
 *   </script>
 *
 */

/**
 * A static array of <em>all</em> Animation objects.
 *
 */
Animation.animations = new Array();

/**
 * An Animation object constructor.
 *
 */
function Animation( numFrames ) {

  // validate argument and initialize frames array:
  var regexp = /^\d+$/;
  if ( regexp.test( numFrames ) ) {
    this.frames = new Array( numFrames );
  } else {
    window.alert( "Invalid argument to Animation constructor: " + numFrames );
    return;
  }

  // initialize the properties of this Animation object:
  this.delay = 200;  // default delay
  this.numImagesLoaded = 0;  // counter for onload handler

  // store this Animation object in the animations array:
  this.animationID = Animation.animations.length;
  Animation.animations[ this.animationID ] = this;

}

/**
 * A setter method for the delay property of
 * this Animation object.
 *
 */
Animation.prototype.setDelay = function( delay ) {

  // validate argument and set delay property:
  var regexp = /^\d+$/;
  if ( regexp.test( delay ) ) {
    this.delay = delay;
  } else {
    window.alert( "Invalid argument to setDelay method: " + delay);
  }

}

/**
 * A method to initiate the animation of
 * this Animation object.
 *
 */
Animation.prototype.animate = function() {

  // compute index into images array (for recursive method):
  this.imageID = document.images.length;

  // write img tag into the current document:
  //window.alert( "this.images[0].width = " + this.images[0].width );
  //window.alert( "this.images[0].height = " + this.images[0].height );
  //this.width = this.images[0].width;
  //this.height = this.images[0].height;
  document.write( '<img src="' + this.frames[0] + '"' );
  //document.write( ' width="' + this.width + '" height="' + this.height + '"' );
  document.write( ' alt="animations[' + this.animationID + ']"' );
  document.write( '>' );

  // initialize images array:
  var n = this.frames.length;
  this.images = new Array( n );

  // load images array:
  for ( var i = 0; i < n; i++ ) {
    this.images[i] = new Image();
    this.images[i].animation = this;
    this.images[i].onload = countImages;
    this.images[i].src = this.frames[i];
  }

}

/**
 * An image onload handler.
 *
 */
function countImages() {
  var numImagesLoaded = ++this.animation.numImagesLoaded;
  var numImages = this.animation.images.length;
  if ( numImagesLoaded == numImages ) {
    var width = this.animation.images[0].width;
    var height = this.animation.images[0].height;
    for ( var i = 1; i < numImages; i++ ) {
      if ( width != this.animation.images[i].width || height != this.animation.images[i].height ) {
        window.alert( "Images have incompatible dimensions!" );
        break;
      }
    }
    // initiate recursion:
    var id = this.animation.animationID;
    Animation.animations[ id ].displayNextFrame( 1 );
  }
}

/**
 * A recursive method that displays the next frame of
 * this Animation object.
 *
 */
Animation.prototype.displayNextFrame = function( n ) {
  n %= this.images.length;
  document.images[ this.imageID ].src = this.images[ n ].src;
  var id = this.animationID;
  var codeStr = "Animation.animations[" + id + "].displayNextFrame(" + (n+1) + ")";
  setTimeout( codeStr, this.delay );
}