/**
 * Slide show.
 * Version: 2.1
 *
 * The use of this script is strictly forbidden without prior written
 * consent. You must obtain permission before copying, modifying, 
 * redistributing, deriving or selling any part of this program.
 *
 * Copyright © 2005 HYPERZOID
 * All Rights Reserved
 */

// An array of slide images, of size NUM_OF_SLIDES
var images;

// Front IMG element
var frontImageElement;

// Rear IMG element
var rearImageElement;

// An array of button images
var buttons;

// Button IMG element
var buttonElement;

// An array of slide captions, of size NUM_OF_SLIDES
var captions;

// Slide caption DIV element
var captionElement;

// Index of the next slide to display, 0 <= nextSlide < NUM_OF_SLIDES
var nextSlide;

// Timer for triggering slide show events
var slideTimer;

// The amount of opacity to increase for every transition timer event
var increment;

// The current opacity of the front image
var frontImageOpacity;

// The maximum opacity value
var maximumOpacity;

// The time interval (in milliseconds) between two consecutive transistion timer events
var TRANSITION_TIMER_INTERVAL = 100;

// IMG ID for the front image
var IMAGE1_ID = "slide1";

// IMG ID for the rear image
var IMAGE2_ID = "slide2";

// Button IMG ID
var BUTTON_ID = "button";

// Total number of slides in this slide show
var NUM_OF_SLIDES;

// Number of seconds to wait before transitioning to the next slide
var SECONDS_PER_SLIDE = 2;

// Number of seconds needed to perform a transition
var SECONDS_PER_TRANSITION = 0.7;

// Number of milliseconds in one second
var MILLISECONDS_PER_SECOND = 1000;

// Whether to loop the slide show or stop after one cycle
var LOOP_SLIDES = true;


/**
 * Displays the next slide.
 */
function changeSlide() {
    clearTimeout(slideTimer);
    if (nextSlide == 0 && !LOOP_SLIDES) { // Stop the slide show after 1 cycle
        stop();
        return;
    }
    // Update slide caption
    nextSlide = ++nextSlide % NUM_OF_SLIDES;
    frontImageElement.style.visibility = "visible";
    if (slideTimer != null) { // Slide show is not paused
        slideTimer = setInterval("fadeIn()", TRANSITION_TIMER_INTERVAL);
    }
}


/**
 * Performs the fade-in transition.
 */
function fadeIn() {
    if (frontImageOpacity < maximumOpacity) { // Continue to fade in
        frontImageOpacity += increment;
        if (document.all) { // IE browsers
            frontImageElement.filters.alpha.opacity = frontImageOpacity;
        } else { // Gecko browsers
            frontImageElement.style.MozOpacity = frontImageOpacity;
        }
    } else { // Front image has faded in completely
        // Stop the transition
        clearInterval(slideTimer);
        // Update the rear image and bring it to the front
        rearImageElement.style.visibility = "hidden";
        rearImageElement.src = images[nextSlide].src;
        if (document.all) { // IE browsers
            rearImageElement.filters.alpha.opacity = 0;
        } else { // Gecko browsers
            rearImageElement.style.MozOpacity = 0.0;
        }
        frontImageOpacity = 0;
        rearImageElement.style.zIndex = eval(frontImageElement.style.zIndex) + 1;
        maintainStackOrder();
        // Display the next slide
        setTimeout("changeSlide()", SECONDS_PER_SLIDE * MILLISECONDS_PER_SECOND);
    }
}


/**
 * Performs initialization for the slide show.
 * @param prefix The prefix of slide filenames.
 */
function init(prefix) {
    // Preload images
    images = new Array(NUM_OF_SLIDES);
    for (i = 0; i < NUM_OF_SLIDES; i++) {
        images[i] = new Image();
        images[i].src = prefix + '' + i + '.jpg';
    }

    // Initialize image elements and their z-index ordering
    frontImageElement = document.getElementById(IMAGE2_ID);
    rearImageElement  = document.getElementById(IMAGE1_ID);
    rearImageElement.style.zIndex = 0;
    frontImageElement.style.zIndex = 1;
    
    // Initialize opacity related values for different browsers    
    if (document.all) { // IE browsers, 0 <= alpha <= 100
        maximumOpacity = 100;
        frontImageElement.filters.alpha.opacity = 0;
        rearImageElement.filters.alpha.opacity = maximumOpacity;
    } else { // Gecko browsers, 0.0 <= alpha <= 0.9
        maximumOpacity = 0.9;
        frontImageElement.style.MozOpacity = 0;
        rearImageElement.style.MozOpacity = maximumOpacity;
    }
    frontImageOpacity = 0;
    increment = maximumOpacity / ((SECONDS_PER_TRANSITION * MILLISECONDS_PER_SECOND) / TRANSITION_TIMER_INTERVAL);

    // Next rear image to display
    nextSlide = 1;
}


/**
 * Loads a slideshow for a specific page.
 * @param numOfSlides The number of slides in the slideshow.
 * @param prefix The prefix of slide filenames.
 */
function load(numOfSlides, prefix) {
    NUM_OF_SLIDES = numOfSlides;
    init(prefix);
}


/**
 * Maintains the image ordering.
 * Postcondition:
 *     frontImageElement is the image element with a higher z-index
 *     when this function was called.
 *     rearImageElement is to the image element with a lower z-index
 *     when this function was called.
 */
function maintainStackOrder() {
    if (frontImageElement.style.zIndex > rearImageElement.style.zIndex) {
        return;
    }
    // Current order is not correct, so reverse it
    if (frontImageElement.id == IMAGE1_ID) {
        frontImageElement = document.getElementById(IMAGE2_ID);
        rearImageElement = document.getElementById(IMAGE1_ID);
    } else {
        frontImageElement = document.getElementById(IMAGE1_ID);
        rearImageElement = document.getElementById(IMAGE2_ID);
    }
    rearImageElement.style.zIndex  = 0;
    frontImageElement.style.zIndex = 1;
}


/**
 * Starts the slide show.
 */
function playSlideshow() {
    if (slideTimer != null) { // Already playing
        return;
    }

    if (frontImageOpacity == 0) { // Start playing prior to a transition
        slideTimer = setTimeout("changeSlide()", SECONDS_PER_SLIDE * MILLISECONDS_PER_SECOND);
    } else { // Start playing in the middle of a transition
        slideTimer = setInterval("fadeIn()", TRANSITION_TIMER_INTERVAL);
    }
}


/**
 * Handles button events.
 */
function pressed() {
    if (slideTimer == null) { // Slide show is not playing, start it and display the pause button
        playSlideshow();
    } else { // Slide show is playing, stop it and display the play button
        stopSlideshow();
    }
}


/**
 * Stops the slide show.
 */
function stopSlideshow() {
    if (slideTimer != null) {
        clearInterval(slideTimer);
    }
    slideTimer = null;
}

 
