/*************************************************************\
| slideshow.js                     v 0.9 (c)oded 20071116 JHe |
|   Display one or more slideshows using fading transitions   |
|   Tested on IE (5.5 6.0 7.0) FF (1.8 2.0)                   |
\*************************************************************/

// assert - error handling utility
var where = "";
function assert(val,msg){
    if (!val){
        alert(where+msg);
        return false;
    } else {
        return true;
    }
}

// gEl,crEl,crTx - DOM utilities
function gEl(idStr){
    return document.getElementById(idStr);
}
function crEl(strTag){
    return document.createElement(strTag);
}
function crTx(strTxt){
    return document.createTextNode(strTxt);
}

///////////////////////////////////////////////////////////////////////////
// setOpacity - fade in/out utility

function setOpacity(oElm,nOpa){
    if (typeof oElm.style.filter != "undefined"){
        oElm.style.filter = "progid:DXImageTransform.Microsoft.BasicImage(opacity = "+nOpa+")";
    } else {
        oElm.style.opacity = nOpa;
    }
}

var showsAry = [];

var current = -1, nextShow = 0;

//*******************************************************************************
// startSlides - ENTRY: Used to start the show using defined slides
//*******************************************************************************

function startSlides(){
    where = "startSlides() "
    if (!assert(showsAry.length, "no shows defined")) return;
    showsAry[nextShow].startShow();
}

//*******************************************************************************
// stopSlides - ENTRY: Used to toggle show running
//*******************************************************************************

function stopSlides(){
    if (current<0) startSlides()
    else showsAry[current].stopShow();
}

//*******************************************************************************
// SlideShow - CONSTRUCTOR: Used to create one slideshow - multibles supported
//*******************************************************************************
//   args         - object containing named arguments:
//   -------------------------------------------------
//     top       ( string )            * - CSS location       
//     left      ( string )            * - CSS location       
//     width     ( string )              - CSS location       
//     height    ( string )              - CSS location       
//     attr      ( string )              - HTML IMG tag Attributes 
//     ----------                                            
//     fadeInc   ( integer, >=0, <1 )    - Fractional change  
//     fadeDly   ( integer [mSec] )      - Fading step Delay  
//     stepDly   ( integer [mSec] )      - Image change delay 
//     ----------                                            
//     imgs      ( array of string [n] ) - imagenames         
//     baseHref  ( string )              - common link base   
//     href      ( array of string [n] ) - links for each img 
//     desc      ( array of string [n] ) - text  for each img (alt + title)
//*******************************************************************************
// returns:
// -------
//   newly created object (may be discarded as it is appended to showsAry)
//
// output:
// -------
//   writes containing IMG tags using document.write()
//   modifies containing elements href (if it is an A tag) as set by baseHref+href 
//*******************************************************************************

function SlideShow(args){
    var stepDly = args.stepDly ? args.stepDly : 5000;
    var attr = args.attr ? args.attr : "";

    where = "SlideShow() ";
    if (!assert(args.imgs && args.imgs.length, "imgs must be array (of img files)")) return null;
    var imgs = args.imgs;

    if (!assert(args.top, "top must be specified")) return null;
    var top = args.top;

    if (!assert(args.left, "left must be specified")) return null;
    var left = args.left;

    var fadeInc = args.fadeInc ? args.fadeInc : 0.02;
    var fadeDly = args.fadeDly ? args.fadeDly : 10;

    var runningStep = false;
    var runningFade = false;
    var fadeFrac = 0;
    var fadeFront = 0;
    var imageIndex= 1;

    var idx = showsAry.length;
    showsAry[idx]=this;
    var imgId = "show"+idx;
    // Create IMG elements for front & back
    document.write("<img id='"+imgId+"_0' src='"+imgs[0]
        +"' style='position:absolute; z-index:0; top:"+top+"; left:"+left
        +(args.width?"; width:"+args.width:"")
        +(args.height?"; height:"+args.height:"")
        +"' "+attr+
        +" alt='"+args.desc[0]+"'"
        +" title='"+args.desc[0]+"'"
        +">");
    document.write("<img id='"+imgId+"_1' src='"+imgs[0]
        +"' style='position:absolute; z-index:1; top:"+top+"; left:"+left
        +(args.width?"; width:"+args.width:"")
        +(args.height?"; height:"+args.height:"")
        +"' "+attr+
        +" alt='"+args.desc[0]+"'"
        +" title='"+args.desc[0]+"'"
        +">");
    var frontImg, backImg;

    //  private function fadeTo
    var fadeTo = function (nOpa){
        setOpacity(frontImg,nOpa);
    }
    // ------------------------------
    //  private function startFadeTo
    var startFadeTo = function (){
        runningStep = false;
        var cont = frontImg.parentNode;
        if (!!cont && cont.tagName=="A") cont.href=args.baseHref+args.href[imageIndex];
        with (frontImg) {
            alt = args.desc[imageIndex];
            title = args.desc[imageIndex];
            style.zIndex = 1;
        }
        backImg.style.zIndex = 0;
        runningFade = setTimeout(stepFade,fadeDly);
    }
    // -------------------------------------------
    //  private function stepFade - timer handler
    var stepFade = function (){
        fadeFrac += fadeInc;
        if (fadeFrac<1){
            fadeTo(fadeFrac);
            runningFade = setTimeout(stepFade,fadeDly);
        } else {
            showsAry[ current  ].stopShow();
            showsAry[ nextShow ].startShow();
        }
    }
    // *************************
    // public function stopShow
    // *************************
    this.stopShow = function (){
        if (runningFade) {
            clearTimeout(runningFade);
            runningFade = false;
            fadeTo(0.999);
        }
        if (runningStep) {
            clearTimeout(runningStep);
            runningStep = false;
        }
        current = -1;
        nextShow = (idx+1)%showsAry.length;
        imageIndex++;
        imageIndex %= imgs.length;
    }
    // **************************
    // public function startShow
    // **************************
    this.startShow = function (){
        
        nextShow = current;
        current = idx;
        
        if (runningFade){
            clearTimeout(runningFade);
            runningFade = false;
            fadeTo(1)
        }
        var fadeBack = fadeFront;
        fadeFront = fadeFront ? 0: 1;
        frontImg = gEl(imgId+"_"+fadeFront);
        backImg =  gEl(imgId+"_"+fadeBack);
        fadeTo(fadeFrac=0);
        // Preload next image
        frontImg.setAttribute("src", imgs[imageIndex]);
        runningStep = setTimeout(startFadeTo, stepDly);
    }
    return this;
}

