// WB's Fading Slideshow
// Copyright (c) 2010 Broomfield Associates

// Object to maintain a fading image set
// See wbfade.txt for how to use, more parameter details and some implementation notes
function Fader(containerdiv, imgclass, imglist, delay, delta, speed) {

    this.fadedelay = delay;         // Delay between slides
    this.fadedelta = delta;         // Fade increment (range >0 - <1.0)
    this.fadespeed = speed;         // Speed of fade in milliseconds

    this.fadepics = new Array();    // To contain the slideshow images for fading
    this.fadeval = 1.0;             // Current opacity setting
    this.fadepic = 1;               // Image being faded up
    this.fademax = -1;              // Highest index in the fadepics array

    // Locate the container and get its children
    fc = document.getElementById(containerdiv);
    if(typeof(fc) == "undefined") return;
    fch = fc.childNodes;

    // Find the first (and only) child with specified class
    for(i = 0; i < fch.length; i++) {
        if(fch[i].className == imgclass) break;
    };
    if(i == fch.length) return;
    img1 = fch[i];

    // Parse image names and add the images as new children in the container
    if(typeof(imglist) == "undefined") return;
    imgarray = imglist.split(";");
    n = 1;
    for(i = 0; i < imgarray.length; i++) {
        if(imgarray[i].length == 0) continue;
        imgnew = new Image(img1.width, img1.height);
        imgnew.src = imgarray[i];
        imgnew.className = imgclass;
        fc.appendChild(imgnew);
    };

    // Add in the initially supplied image as the last child to aid in cyclic fading
    imgnew = new Image(img1.width, img1.height);
    imgnew.src = img1.src;
    imgnew.className = imgclass;
    fc.appendChild(imgnew);

    // Extract again all of the imgclass items and store in the object
    // (this removes any spurious "text" or "comments" in the container)
    // and make them all transparent
    for(i = 0; i < fch.length; i++) {
        if(fch[i].className == imgclass) {
            this.fadepics[++this.fademax] = fch[i];
            fadeopacity(this.fadepics[this.fademax], 0.0);
        };
    };

    // Check that we still have a set of images to fade,
    // select the last image (which is the same as the first)
    // and start the fade sequence with this image on full opacity
    if(this.fademax > 0) {
        this.fadepic = this.fademax;        
        fadenext(this);
    };

}

// Next stage of fading for the passed Fader object
// Sets the timer to re-invoke itself repeatedly to cycle within a fade and also from slide to slide
function fadenext(fadeobj) {
    
/*
    // Perhaps needed in some cases to ensure all images loaded before starting the sequence?
    // Not yet required in tests to date
    for(i = 0; i <= fadeobj.fademax; i++) {
        if(!(fadeobj.fadepics[i]).complete) {
            setTimeout(function(){fadenext(fadeobj)}, fadeobj.fadespeed);
            return;
        }
    }
*/

    // Set the preprepared opacity for the current image in the requested object 
    fadeopacity(fadeobj.fadepics[fadeobj.fadepic], fadeobj.fadeval);

    // Increment the opacity value in preparation for the next clock cycle
    // If reached full opacity on this image,
    // hide the previous image, which has just been covered up, and
    // select the next image in the sequence starting with opacity zero
    fadeobj.fadeval += fadeobj.fadedelta;
    if(fadeobj.fadeval > 1.0) {

        fadeopacity(fadeobj.fadepics[fadeobj.fadepic - 1], 0.0);
        fadeobj.fadepic++;
        fadeobj.fadeval = 0.0;

        // However, if this is the last image (which is identical to the first),
        // unhide the first, and hide the last (should be seamless)
        // and then start the cycle again at the beginning
        if(fadeobj.fadepic > fadeobj.fademax) {
            fadeopacity(fadeobj.fadepics[0], 1.0);
            fadeopacity(fadeobj.fadepics[fadeobj.fademax], 0.0);
            fadeobj.fadepic = 1;
        }

        // Trigger for next slide after delay to allow viewing
        setTimeout(function(){fadenext(fadeobj)}, fadeobj.fadedelay);

    } else {

        // If still fading an image, trigger for next opacity increment 
        setTimeout(function(){fadenext(fadeobj)}, fadeobj.fadespeed);

    }

}
    
// Set opacity of elem to value op
// Takes account of IE v CSS "standard"
function fadeopacity(elem, op) {
    elem.style.opacity = op; opn = 100.0 * op;
    elem.style.filter = 'alpha(opacity=' + opn + ')';
}