/* 
 * small- movie.js
 *  
 *  This script implements a JavaScrip-based movie player that plays a
 *  movie whose frames are individual files, in any format understood by
 *  the browser.  The player includes buttons for playing the movie,
 *  stepping the movie forward or backward, or stopping the movie. 
 *  Multiple movies can appear on a single page.  The movie frames can be
 *  timed so that they change at a given rate when the movie is played. 
 *  The image load time is taken into account with this timing, and the
 *  frames are cached so that the movie will run at "full speed" on
 *  subsequent playings.
 *  
 *  Written by Davide P. Cervone in August 2000.
 *  Updated by dpvc in April 2003 to add the caching and improve performance.
 *  Updated by dpvc in September 2003 to reduce button sizes and number, and to add
 *    speed control
 *  
 *  Copyright 2000-2003 by Davide P. Cervone.  All rights reserved.
 * 
 */
 
version = "2.2";


/****************************************************************************************/

/* 
 *  This returns an IMG tag for a button.  You may need to adjust the SRC to
 *  point to the buttons.  If you change the images, you may also need to
 *  adjust the HEIGHT and WIDTH.
 */

moviedir = '../movie';

function Button(name,alt,size) {
  if (size == null) {size = 15;}
  return '<IMG SRC="'+moviedir+'/buttons/'+name+'" ALT="['+alt+']" BORDER="0" HEIGHT="'+size+'" WIDTH="'+size+'" ALIGN="CENTER">';
}

/* 
 *  This tells where to find the frames.  The frame number and type will be appended
 *  to this value.  It should be relative to the page containing the movie.
 */

function MovieName(name,type) {return '';}

/****************************************************************************************/
/*                  You should not need to change anything below this                   */
/****************************************************************************************/

/*
 *  The state information is stored in arrays so that we can have more than one movie
 *  per page.  (Probably should be redone as objects, but it works.)
 */
 
id = new Array(); running = new Array(); frame = new Array();
max = new Array(); play = new Array(); delay = new Array();
movieType = new Array(); imageID = new Array();
cache = new Array(); frametime = new Array();

n = 0; id[0] = ''; running[0] = 0; frame[0] = 1;


/****************************************************************************************/

/*
 *  These set the position to the beginning or ending frame, or step the frame.
 */
 
function Start(k) {NewFrame(k,1);}
function End(k) {NewFrame(k,max[k]);}
function NextImage(k) {NewFrame(k,frame[k]+1);}
function PrevImage(k) {NewFrame(k,frame[k]-1);}

/*
 *  Increase or decrease the speed
 */

function Slower(k) {
  delay[k] = Math.floor(1.25*delay[k]);
}

function Faster(k) {
  delay[k] = Math.floor(.8*delay[k]);
  if (delay[k] < 1) (delay[k] = 1);
}


/* 
 *  If the movie is already running, go to the next frame, looping at the end.
 *  Otherwise, go to the beginning if necessary, and start running.
 */
function PlayForward(k) {
  play[k] = 'PlayForward('+k+');';
  if (running[k]) {
    NextImage(k);
  } else {
    running[k] = 1;
    if (frame[k] == max[k]) {Start(k);} else {NextImage(k);}
  }
}
/*
 *  Similarly for playing backwards.
 */
function PlayBackward(k) {
  play[k] = 'PlayBackward('+k+');';
  if (running[k]) {
    PrevImage(k);
  } else {
    running[k] = 1;
    if (frame[k] == 1) {End(k);} else {PrevImage(k);}
  }
}

/* 
 *  Cancel any pending frames and stop running.
 */
function Stop(k) {
  clearTimeout(id[k]);
  running[k] = 0;
}

/****************************************************************************************/

/* 
 *   This is the heart of the matter.
 *   First, make sure the frame number is valid.
 *   Save the time that we started (so we know how long it takes to load the image).
 *   If we haven't already cached this image:
 *     Pad the image number with zeros (for the file name of the next frame).
 *     Create a new image object for the frame
 *     Load the frame, and call ShowFrame when done
 *   Otherwise, show the existing frame
 */
function NewFrame(k,m) {
  if (m < 1) {m = 2; play[k] = 'PlayForward('+k+');'}
  if (m > max[k]) {m = max[k] - 1; play[k] = 'PlayBackward('+k+');'}
  frame[k] = m;
  frametime[k] = (new Date).getTime();
  if (cache[k][m] == null) {
    var mm = m;
    if (mm < 10) {mm = '0'+mm;}
    cache[k][m] = new Image();
    cache[k][m].onload = function () {ShowFrame(k,m)};
    cache[k][m].src = mm + movieType[k];
  } else {
    ShowFrame(k,m);
  }
}

/* 
 *  Display the cached frame and go on to the next frame if the
 *  movie is currently running.
 */
function ShowFrame(k,m) {
  document.images[imageID[k]].src = cache[k][m].src;
  if (running[k]) {Continue(k);}
}
/* 
 *  Determine how long it took to load the frame, and
 *  subtract that from the delay time.  Then play the
 *  next frame after the appropriate delay.
 */
function Continue(k) {
  var time = (new Date).getTime() - frametime[k];
  time = delay[k]-time; if (time < 1) {time = 1}
  id[k] = setTimeout(play[k],time);
}

/****************************************************************************************/

/* 
 *  This saves the state data for the movie and prints the HTML needed for the
 *  buttons and movie image.  Then the first frame is loaded.
 *  The global 'n' counts how many movies are on the page, so that we can store
 *  state for multiple movies.
 */
function Movie(type,frames,del,startframe,link) {
  if (del == 1) {del = 80;}
  movieType[n] = '.' + type.toLowerCase();
  max[n] = frames;
  if (startframe == null) {startframe = 1}
  if (del == 1 || del == null) {del = 300}
  delay[n] = del; play[n] = "";
  frame[n] = startframe; id[n] = ""; running[n] = 0;
  imageID[n] = document.images.length;
  cache[n] = new Array(frames);
  
  if (startframe < 10) {startframe = '0'+startframe}

  document.write('<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="0" ALIGN="CENTER">\n');
  document.write('<TR><TD ALIGN="CENTER">');
  document.write('<TABLE BORDER="1" CELLPADDING="0" CELLSPACING="2" ALIGN="CENTER">\n');
  document.write('<TR><TD><IMG SRC="'+startframe+movieType[n]+'" NAME="movie'+n+'"></TD></TR>\n');
  document.write('</TABLE>');
  document.write('</TD></TR>\n');
  document.write('<TR><TD HEIGHT="3"></TD></TR>\n');  
  document.write('<TR VALIGN="MIDDLE">\n');
  document.write('<TD NOWRAP="NOWRAP" ALIGN="CENTER">');
  document.write('&nbsp;&nbsp;');
  document.write('<A HREF="javascript:Stop('+n+');Start('+n+');" onDblClick="Stop('+n+');Start('+n+');" onMouseOver="return true;">'+Button('start.gif','Go to Start')+'</A>');
  document.write('<A HREF="javascript:Stop('+n+');PrevImage('+n+');" onDblClick="Stop('+n+');PrevImage('+n+');" onMouseOver="return true;">'+Button('prev.gif','Step Backward')+'</A>');
  document.write('<A HREF="javascript:Stop('+n+');NextImage('+n+');" onDblClick="Stop('+n+');NextImage('+n+');" onMouseOver="return true;">'+Button('next.gif','Step Forward')+'</A>');
  document.write('<A HREF="javascript:Stop('+n+');End('+n+');" onDblClick="Stop('+n+');End('+n+');" onMouseOver="return true;">'+Button('end.gif','Go to End')+'</A>');
  document.write('&nbsp;');
  document.write('<A HREF="javascript:Stop('+n+');PlayBackward('+n+');" onMouseOver="return true;">'+Button('playback.gif','Play Backward')+'</A>');
  document.write('<A HREF="javascript:Stop('+n+');" onMouseOver="return true;">'+Button('stop.gif','Stop')+'</A>');
  document.write('<A HREF="javascript:Stop('+n+');PlayForward('+n+');" onMouseOver="return true;">'+Button('play.gif','Play Forward')+'</A>');
  document.write('&nbsp;');
  document.write('<A HREF="javascript:Slower('+n+');" onMouseOver="return true;">'+Button('minus.gif','Slower')+'</A>');
  document.write('<A HREF="javascript:Faster('+n+');" onMouseOver="return true;">'+Button('plus.gif','Faster')+'</A>');
  document.write('&nbsp;');
  document.write('<A HREF="'+moviedir+'/help.html" TARGET="_blank">'+Button('help.gif','Help',10)+'</A>');
  document.write('</TD></TR>\n');
  if (link != null) {
    document.write('<TR><TD HEIGHT="1"></TD></TR>\n');  
    document.write('<TR><TD ALIGN="CENTER"><SMALL><A HREF="'+link+'">About this movie</A></SMALL></TD></TR>\n');
  }
  document.write('</TABLE>\n');
  n++;
}


