var galleryId = 'gallery'; /* change this to the ID of the gallery list */
var gallery; /* this will be the object reference to the list later on */
var galleryImages; /* array that will hold all child elements of the list */
var currentImage; /* keeps track of which image should currently be showing */
var previousImage;
var stop = true;
var fadeInitTimer;
var preInitTimer;
var crossfadeTimeout1;
var crossfadeTimeout2;


function preInit() {
  // an inspired kludge that - in most cases - manages to initially hide the
  // image gallery list before even onload is triggered (at which point it's
  // normally too late, and the whole list already appeared to the user before
  // being remolded)
  if ((document.getElementById)&&(gallery=document.getElementById(galleryId))) {
    gallery.style.visibility = "hidden";
    clearTimeout(preInitTimer);
  }
  else {
    preInitTimer = setTimeout("preInit()",2);
  }
}


function fader(imageNumber,opacity) {
  // helper function to deal specifically with images and the cross-browser
  // differences in opacity handling 
  var obj=galleryImages[imageNumber];
  if (obj.style.MozOpacity!=null) {  
    // Mozilla's pre-CSS3 proprietary rule
    obj.style.MozOpacity = (opacity/100) - .001;
  }
  if (obj.style.KhtmlOpacity!=null) {
    // KHTML's pre-CSS3 proprietary rule
    obj.style.KHTMLOpacity = (opacity/100) - .001;
  }
  else if (obj.style.opacity!=null) {
    // CSS3 compatible
    obj.style.opacity = (opacity/100) - .001;
  }
  else if (obj.style.filter!=null) {
    // IE's proprietary filter
    obj.style.filter = "alpha(opacity="+opacity+")";
  }
}


function fadeInit() {
  if (document.getElementById) {
    // shouldn't be necessary, but IE can sometimes get ahead of itself and
    // trigger fadeInit first
    preInit();

    // get all child nodes...yes, lazy, as i should really check that they're
    // the "proper" type of child nodes (i.e. filter out duff text only
    // nodes, such as white space)
    galleryImages = gallery.childNodes;
    for (i = 0; i < galleryImages.length; i++) {
      // loop through all these child nodes and set up their styles
      galleryImages[i].style.position='absolute';
      galleryImages[i].style.top=0;
      galleryImages[i].style.zIndex=0;
      galleryImages[i].style.display = 'block';
      // set their opacity to transparent
      fader(i,0);
    }
    // make the list visible again
    gallery.style.visibility = 'visible';

    // initialise a few parameters to get the cycle going 
    currentImage=0;
    previousImage=galleryImages.length-1;
    opacity=100;
    fader(currentImage,0);
  }
}

function crossfade(opacity) {
  if (opacity < 100) {
    // current image not faded up fully yet...so increase its opacity
    fader(currentImage,opacity);

    fader(previousImage,100-opacity);
    opacity += 10;
    crossfadeTimeout1 = setTimeout("crossfade("+opacity+")", 30);
  }
  else {
    // make the previous image - which is now covered by the current one
    // fully - transparent
    fader(previousImage,0);
    fader(currentImage,100);

    // current image is now previous image, as we advance in the list of
    // images 
    previousImage=currentImage;
    currentImage+=1;
    if (currentImage>=galleryImages.length) {
      // start over from first image if we cycled through all images in the
      // list
      currentImage=0;
    }

    // make sure the current image is on top of the previous one
    galleryImages[previousImage].style.zIndex = 0;
    galleryImages[currentImage].style.zIndex = 100;

    // and start the crossfade after a second's pause
    opacity=0;
    if (!stop) {
      crossfadeTimeout2 = setTimeout("crossfade("+opacity+")", 3000);
    }
    else {
      clearTimeout(crossfadeTimeout2);
      clearTimeout(crossfadeTimeout1);
    }
  }
}


// 3rd party helper functions

// addEvent handler for IE and other browsers
function addEvent(elm, evType, fn, useCapture) {
  // addEvent and removeEvent
  // cross-browser event handling for IE5+,  NS6 and Mozilla
  // By Scott Andrew
  if (elm.addEventListener){
    elm.addEventListener(evType, fn, useCapture);
    return true;
  }
  else if (elm.attachEvent) {
    var r = elm.attachEvent("on"+evType, fn);
    return r;
  }
}


// control functions

function playSlides() {
  if (stop) {
    fadeInitTimer = setTimeout("crossfade(0)", 10);
    stop = false;
  }
}

function stopSlides() {
  if (!stop) {
    stop = true;
  }
}


function nextSlide() {
  playSlides();
  stopSlides();
}

function prevSlide() {
  // hide old next image
  oldNextImage=currentImage+1;
  if (oldNextImage > galleryImages.length) {
    oldNextImage = 0;
  }
  fader(currentImage, 0);

  // set new previous image
  previousImage=currentImage-1;
  if (previousImage < 0) {
    previousImage = galleryImages.length - 1;
  }

  // set new current image
  currentImage-=2;
  if (currentImage < 0) {
    currentImage = galleryImages.length + currentImage;
  }
  if (stop) {
    stopSlides();
    playSlides();
  }
  stopSlides();
}


function deleteSlideshow() {
  stop = true;
  if (fadeInitTimer) {
    clearTimeout(fadeInitTimer);
  }
  if (preInitTimer) {
    clearTimeout(preInitTimer);
  }
  if (crossfadeTimeout1) {
    clearTimeout(crossfadeTimeout1);
  }
  if (crossfadeTimeout2) {
    clearTimeout(crossfadeTimeout2);
  }
} 
