//
// Slideshow, Diashow
// (c) Marco Vieth, 2000
// http://www.benchmarko.de/
//
// 0.01  29.10.2000  first tests
// 0.02  07.11.2000  corrected for NE
// 0.03  04.03.2001  image index for change_image is optional (set the first time)
//       04.06.2001  inserted some comments
// 0.04  23.09.2001  all global variables start with g_sshow_*, functions with sshow_*;
//                          new functions sshow_add_image[s](), sshow_change_image_abs()
// 0.05  26.11.2001  no need for form 'Navigate' on page
// 0.06  19.01.2002  new object-oriented design
//       20.01.2002  do not use unnamed functions, prototypes -> useful for old browsers with Javascript 1.1
// 0.07  22.01.2003  debug code separated in debug.js; NGS: check also for Image object,...
// 0.08  17.06.2003  use class Timer for timer handling
// 0.09  20.06.2003  precaching corrected (need to always create a new timer object because arg0 is changing);
//                   forward and backward precaching; forward and backward automatic;
//                   methods renamed: change_image -> change_image_rel; change_image_random, change_image_auto
// 0.10  22.06.2003  use callback function Sshow_set_image to set image, index description;
//                   Staroffice 5.2 does not like isNaN(undefined), so use other method to check for defined...
// 0.11  29.11.2003  Netscape 4: does not like argument '+1'; Sshow_set_image_func: don't use last image index if arg=null
//                   push images in array is very slow, so don't create new array
// 0.12  05.12.2003  compare with "null" to check for defined value


// - Needed for change_image_auto and precaching: timer1.js
// - Needed for debugging: debug1.js
//
var g_debug = null; // maybe changed later...


// -----------------------------


// Constructor for class Sshow
function Sshow(images, descrs, set_image_cback, precache_sec) {
  // attributes
  this.set_image_cback = (set_image_cback) ? set_image_cback : Sshow_set_image_func; // image callback function

  if (precache_sec != null) { // if defined
    this.precache_sec = precache_sec; // timeout to precache next image (sec)
  } else {
    this.precache_sec = 2; // default
  }

  this.img_idx = 0;      // current image index
  //this.timer = null;   // timer object for image preloading
  //this.itimer = null;  // interval timer object
  //this.arg = window.document.images.length - 1;  // argument (image index) in change_image_x()
  this.addval = 1;       // standard addval

  if (images) {
    this.inames = images; // take array with images
  } else {
    this.inames = new Array(); // image names
  }
  if (descrs) {
    this.idescr = descrs; // take descriptions
  } else {
    //this.idescr = new Array(); // descriptions
  }

  this.cimgs = new Array();  // cached images

  // methods
  if (!Sshow.prototype) { // old browsers get the methods directly into the object...
    this.add_image = Sshow_add_image;
    this.add_images = Sshow_add_images;
    this.set_options = Sshow_set_options;
    this.prepare_image = Sshow_prepare_image;
    this.prepare_all_images = Sshow_prepare_all_images;
    this.change_image_abs = Sshow_change_image_abs;
    this.change_image_rel = Sshow_change_image_rel;
    this.change_image_random = Sshow_change_image_random;
    this.change_image_auto = Sshow_change_image_auto;
  }

  //if (images) {
  //  this.add_images(images, descrs);
  //}
}


//
// normally we would create unnamed functions here but for old browsers...
// Sshow.prototype.add_image = function(image, descr) { ... }
//

// For new browsers (JS 1.2) set the prototypes...
new Sshow(); // force old browsers to create prototype
if (Sshow.prototype) {
  Sshow.prototype.add_image = Sshow_add_image;
  Sshow.prototype.add_images = Sshow_add_images;
  Sshow.prototype.set_options = Sshow_set_options;
  Sshow.prototype.prepare_image = Sshow_prepare_image;
  Sshow.prototype.prepare_all_images = Sshow_prepare_all_images;
  Sshow.prototype.change_image_abs = Sshow_change_image_abs;
  Sshow.prototype.change_image_rel = Sshow_change_image_rel;
  Sshow.prototype.change_image_random = Sshow_change_image_random;
  Sshow.prototype.change_image_auto = Sshow_change_image_auto;
}


// debugging?
//function debug_check_complete(img_obj, idx) {
//  var str = "";
//  if (img_obj && (img_obj.complete == true)) {
//    str += "image "+ idx +" loaded\n";
//  } else {
//    str += "image "+ idx +" not loaded\n";
//  }
//  alert(str +", src="+ ((img_obj) ? img_obj.src : "???"));
//}


// Sshow_add_image - add image to slide show
// in:  <image> <description>
// out: 1=OK
function Sshow_add_image(image, descr) {
  // IE 5.x seems to have no push(), so we simulate it...
  this.inames[this.inames.length] = image;
  if (descr) {
    if (!this.idescr) { // create description array, if not yet done
      this.idescr = new Array();  // image descriptions (optional)
    }
    this.idescr[this.idescr.length] = descr;
  }
}

function Sshow_add_images(images, descrs) {
  for (var i = 0; i < images.length; i++) {
    this.add_image(images[i], (descrs) ? descrs[i] : null);
  }
}


// Sshow_set_options - set options for display
// IN:  ...
// OUT:
//
function Sshow_set_options(set_image_cback, precache_sec) {
  if (set_image_cback) {
    this.set_image_cback = set_image_cback;
  }
  if (precache_sec != null) { // if defined
    this.precache_sec = precache_sec; // timeout to precache next image (sec)
  } else {
    this.precache_sec = 2;
  }
}


//
// sshow_prepare_image - prepare an image (make it available)
// IN:  idx = image index
// OUT: <image> = image name
function Sshow_prepare_image(idx) {
  if (g_debug) { g_debug.writeln("prepare_image: idx="+ idx); }
  if (this.timer) { // preloading timer still active?
    this.timer.close(); // stop & close
    this.timer = null;
  }
  if ((!this.cimgs[idx]) && (idx < this.inames.length)) { // image not prepared yet?
    if (window.document.images) { // check for NGS
      this.cimgs[idx] = new Image();
      this.cimgs[idx].src = this.inames[idx];
    }
    // else { this.cimgs[idx] = new Object();  }
    if (g_debug) { g_debug.writeln("prepare_image: new image prepared: idx="+ idx); }
  }
  //debug_check_complete(this.cimgs[idx], idx); // debug
  return (this.cimgs[idx]) ? this.cimgs[idx].src : "";
}


// if you want to prepare all images onload...
function Sshow_prepare_all_images() {
  for (var i = 0; i < this.inames.length; i++) {
    this.prepare_image(i);
  }
}


// default set image function (example) (not in class)
// optional arg is not used.
function Sshow_set_image_func(img, idx, descr, arg) {
  var windoc = window.document;
  if (windoc.images) {
    if (arg != null) { // if defined
      windoc.images[arg].src = img;
    }
  }
  if (windoc.Navigate) {
    if (windoc.Navigate.Index) {
      windoc.Navigate.Index.value = idx;
    }
    if (windoc.Navigate.description) {
      windoc.Navigate.description.value = descr;
    }
  }
}


// change image absolute
function Sshow_change_image_abs(img_idx, arg) {
  if (g_debug) { g_debug.writeln("change_image_abs: img_idx="+ img_idx +", arg="+ arg); }

  if ((img_idx >= 0) && (img_idx < this.inames.length)) {
    this.img_idx = img_idx;
  }

  if (arg != null) {
    this.arg = arg;
  } else {
    arg = this.arg;
  }
  var prep_img = this.prepare_image(this.img_idx);
  //if (this.img_obj) {
  //  this.img_obj.src = prep_img; // set image
  //}
  if (this.set_image_cback) {
    this.set_image_cback(prep_img, this.img_idx + 1, (this.idescr && this.idescr[this.img_idx]) ? this.idescr[this.img_idx] : this.inames[this.img_idx], arg);  }

  if (this.precache_sec) { // preloading allowed?
    if (this.timer) { // preloading timer still active?
      this.timer.close(); // stop & close
      this.timer = null;
    }
    var preload_idx = -1; // unused
    if ((this.addval >= 0) && (this.img_idx < (this.inames.length - 1))) { // forward caching?
      preload_idx = this.img_idx + 1;
    } else if ((this.addval < 0) && (this.img_idx > 0)) { // backward caching?
      preload_idx = this.img_idx - 1;
    }
    if ((typeof Timer != "undefined") && (preload_idx >= 0) && (!this.cimgs[preload_idx])) {
      this.timer = new Timer(this, 'prepare_image', preload_idx);
      this.timer.setTimeout(this.precache_sec * 1000); // cache next image after timeout
    }
  }

  return(this.img_idx);
}


//
// change_image_rel - change an image relative
// IN:  <addval> = value to compute new index, [<img>] = image index (optional)
// OUT: <img_idx>
// Add <addval> to the current image index.
// If <img> is (or was already) specified, set the new image to "img.src".
// Also set 'Navigate.Index.value' to the current img_idx +1 and
// 'Navigateimg_idx +1 and
// 'Navigate.description.value' to the description idescr[] or the name from inames[].
// Return the (new) index <img_idx>.
//
function Sshow_change_image_rel(addval, arg) {
  if (g_debug) { g_debug.writeln("change_image_rel: addval="+ addval); }

  //alert("DDD: change_image: addval="+ addval +", img_obj="+ img_obj);
  if (addval != null) { // use if defined (including 0)
    this.addval = addval;
  }

  var new_idx = this.img_idx + this.addval;
  return this.change_image_abs(new_idx, arg)
}


function Sshow_change_image_random(arg) {
  var new_idx = Math.floor(Math.random() * this.inames.length);
  if (g_debug) { g_debug.writeln("change_image_random: new_idx="+ new_idx); }
  return this.change_image_abs(new_idx, arg)
}


//
// auto_change_image - automatically change (image)
// IN:  <delay>, [<callfunc>]
// OUT: -
// Stop a running interval timer and restart it with <delay> seconds to change image automatically.
// Use delay=0 to switch the timer off.
// Note: Before using this function call "change_image()" with an image parameter.
// If specified, <obj>.<method> is called instead of "this.change_image(1)", with optional argument <arg0>.
//
function Sshow_change_image_auto(delay_sec, obj, method, arg0) {
  if (g_debug) { g_debug.writeln("change_image_auto: delay_sec="+ delay_sec +", obj="+ obj +", method="+ method); }

  if (this.itimer) {
    this.itimer.close(); // stop & close
    this.itimer = 0;
  }

  if (!obj) {
    obj = this;
  }
  if (!method) {
    method = 'change_image_rel'; // does not require arguments
  }
  
  // arg0 not needed.
  
  if ((typeof Timer != "undefined") && (delay_sec)) {
    this.itimer = new Timer(obj, method, arg0);
    this.itimer.setInterval(delay_sec * 1000);
  }
}

// end

