// Image rotator v1.02
// Rotates through a list of images using various transitions
//
// To make an imade gradually fade up on init set control visibility to hidden (css or style)
// Controls (img&div) can be set up with style properties using CSS 
// Changes:
//      1.01 - Slide transitions (can be in any direction or random),
//      1.02 - In random mode, first image is random as well as concurrent ones
//           - Start-up timings revised 
//           - All images load dynamically
// Inputs:
//      image_control_ID = ID of the html image control
//      div_control_ID = ID of the html text control set to "" if not required
//      image_filenames_s = Semi-colon seperated image filenames
//      image_htmltext_s = Semi-colon seperated html text
//      random - if equal to 1 images are randomised if 0 they are in order given
//      trans_type - 0=fade transition, 1=slide left, 2=slide right, 3=slide up, 4=slide down, 5=slide random

// User can change the following settings:
//    transitionSteps - Levels of transition
//    transitionTime - Seconds
//    pauseTime - Seconds
//    pictureIndex - Start image
//    random - if equal to 1 images are randomised if 0 they are in order given
//    trans_type - 0=fade transition, 1=slide left, 2=slide right, 3=slide up, 4=slide down, 5=slide random


function ImageRotator(parentId, imageFilenames, imageHtmlText, imageClass, textClass, random, transitionType )
{
    // ********************************* User variables *************************************
    // Image settings var
    while (true) { if (imageFilenames.substr(imageFilenames.length - 2,1) != ";") break; imageFilenames=imageFilenames.substr(0,imageFilenames.length - 2); }
    this.transitionSteps = 20;  // Graduation of transition
    this.transitionTime = 1;    // Seconds
    this.pauseTime = 2;         // Seconds
    this.initDelay = 1000;       // Pause for page controls to load
    // *********************************** Private variables ********************************
    var imageFilenamesArr = imageFilenames.split(';');         // Array of filenames
    var imageHtmlTextArr = imageHtmlText.split(';');           // Array of htmltext
    var step = 1;                           // start with increment
    var timerIndex = -1;                   // starts at zero (pre-incremented)

    if (random == 0) this.pictureIndex = 0;      // Start image
    else this.pictureIndex = Math.floor((imageFilenamesArr.length * Math.random())); //random start image 
    
    var image1;         // Control objects          
    var image2;         // '   
    var text1=null;     // '  
    var text2;          // '   
    var timer;          // Interval timer object   
    var imgs;           // Image preload variable

    // *********************************** Initial sizes ********************************
    var imageWidth;
    var imageLeft;
    var imageHeight;
    var imageTop;
    var dirh = 1; // For random slides
    var dirv = 0;
    var initTrans = 1; // Makes first transition a fade-up
    var thisObj = this;   
       
    // *********************************** User functions ************************************
    
    // Preload images
    if( document.images )
    {
        imgs = new Array();
        for (var i = imageFilenamesArr.length-1; i >= 0 ; i--) {
            imgs[i] = new Image();
            imgs[i].src = imageFilenamesArr[i];
        }
    }
    //window.onload = function() { thisObj.init() };
    window.setTimeout( function() { thisObj.init() }, 300);
    
    // Creates additional controls for smooth transition and start the interval timer
    this.init = function() {

        // Create image control 
        image1 = document.createElement('img');
        image1.src = imageFilenamesArr[this.pictureIndex % imageFilenamesArr.length];
        image1.className = imageClass;
        image1.id = "imgrot1";
        // Create another image control 
        image2 = document.createElement('img');
        image2.src = imageFilenamesArr[(this.pictureIndex + 1) % imageFilenamesArr.length];
        image2.className = imageClass;
        image2.id = "imgrot2";

        document.getElementById(parentId).appendChild(image1);
        document.getElementById(parentId).appendChild(image2);

        // Get main text control
        if (imageHtmlText != null) {
            // Create text control with style properties
            text1 = document.createElement('div');
            text1.innerHTML = imageHtmlTextArr[this.pictureIndex % imageFilenamesArr.length];
            text1.className = textClass;
            text1.id = "txtrot1";

            // Create another text control with sample style properties
            text2 = document.createElement('div');
            text2.innerHTML = imageHtmlTextArr[(this.pictureIndex + 1) % imageFilenamesArr.length];
            text2.className = textClass;
            text2.id = "txtrot2";

            document.getElementById(parentId).appendChild(text1);
            document.getElementById(parentId).appendChild(text2);

            // Set default position and width for transitions that need it
            imageWidth = image1.offsetWidth;
            imageLeft = image1.offsetLeft;
            imageHeight = image1.offsetHeight;
            imageTop = image1.offsetTop;
        }
    }  


    // Set a delay for the page to load
    // Start the rotation
    this.start = function() {
            window.setTimeout(function() {
                thisObj.timer = window.setInterval(function() { thisObj.imageTransition() }, thisObj.transitionTime * 1000 / thisObj.transitionSteps);
            }, this.initDelay);
    }

    // Stop the rotation
    this.stop = function(timeout) {
        window.setTimeout(function() {
            window.clearInterval(thisObj.timer);
        }, timeout*1000);
    }
    
    
    // Controls the transition and pause times of the images
    this.imageTransition = function() {
        // Controls the indexes to determine the transition and pause images of the images
        if (timerIndex > this.transitionSteps + (this.transitionSteps * this.pauseTime / this.transitionTime)) // Max index val
        {
            if (random == 1) {
                var pi = Math.floor((imageFilenamesArr.length * Math.random()));
                this.pictureIndex = (pi + (this.pictureIndex == pi)) % imageFilenamesArr.length;
            }
            else this.pictureIndex = (this.pictureIndex + 1) % imageFilenamesArr.length; // cycle the picture index  
            step = -1;                                                          // @ max value change to decriment index
            image2.src = imageFilenamesArr[this.pictureIndex];                   // Change picture
            if (text1 != null) text2.innerHTML = imageHtmlTextArr[this.pictureIndex];               // Change text
        }
        if (timerIndex < -(this.transitionSteps * this.pauseTime / this.transitionTime))  // Min index val 
        {
            if (random == 1) {
                var pi = Math.floor((imageFilenamesArr.length * Math.random()));
                this.pictureIndex = (pi + (this.pictureIndex == pi)) % imageFilenamesArr.length;
            }
            else this.pictureIndex = (this.pictureIndex + 1) % imageFilenamesArr.length; // cycle the picture index  
            step = 1;                                                           // @ min value change to increment index
            image1.src = imageFilenamesArr[this.pictureIndex];                   // Change picture
            if (text1 != null) text1.innerHTML = imageHtmlTextArr[this.pictureIndex];               // Change text
        }
        // Sets the image to appear gradually (up fade)
        // visibility must be set to hidden in css or control style
        if (timerIndex == (this.transitionSteps / 2)) {
            image1.style.visibility = "visible";
            image2.style.visibility = "visible";
            if (text1 != null) {
                text1.style.visibility = "visible";
                text2.style.visibility = "visible";
            }
        }

        timerIndex = timerIndex + step;    // inc/dec index

        // Convert index to fade values
        var img1_tran = timerIndex * ((timerIndex > 0) & (timerIndex < this.transitionSteps)) +
                          this.transitionSteps * (timerIndex >= this.transitionSteps);
        var neg_timerIndex = (this.transitionSteps) - timerIndex;
        var img2_tran = neg_timerIndex * ((neg_timerIndex > 0) & (neg_timerIndex < this.transitionSteps)) +
                          this.transitionSteps * (neg_timerIndex >= this.transitionSteps);

        // On init to slide tranitions there is a fade up 
        if (initTrans == 1 && transitionType != 0) {
            this.fadeTransition(image1.id, (img1_tran / this.transitionSteps));
            this.fadeTransition(image2.id, (img2_tran / this.transitionSteps));
            if (text1 != null) {
                this.fadeTransition(text1.id, (((img1_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                this.fadeTransition(text2.id, (((img2_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
            }
            if (timerIndex > this.transitionSteps) {
                initTrans = 0;
                this.fadeTransition(image1.id, 1);
                this.fadeTransition(image2.id, 1);
            }
        }
        // Execute transition depending on type
        switch (transitionType) {
            case 0:
                {
                    this.fadeTransition(image1.id, (img1_tran / this.transitionSteps));
                    this.fadeTransition(image2.id, (img2_tran / this.transitionSteps));
                    if (text1 != null) {
                        this.fadeTransition(text1.id, (((img1_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                        this.fadeTransition(text2.id, (((img2_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                    }
                    break;
                }
            case 1:
                {
                    this.slideTransition(image1.id, (img1_tran / this.transitionSteps), 1, step > 0);
                    this.slideTransition(image2.id, (img2_tran / this.transitionSteps), 1, step < 0);
                    if (text1 != null) {
                        this.fadeTransition(text1.id, (((img1_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                        this.fadeTransition(text2.id, (((img2_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                    }
                    break;
                }
            case 2:
                {
                    this.slideTransition(image1.id, (img1_tran / this.transitionSteps), 1, step < 0);
                    this.slideTransition(image2.id, (img2_tran / this.transitionSteps), 1, step > 0);
                    if (text1 != null) {
                        this.fadeTransition(text1.id, (((img1_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                        this.fadeTransition(text2.id, (((img2_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                    }
                    break;
                }
            case 3:
                {
                    this.slideTransition(image1.id, (img1_tran / this.transitionSteps), 0, step > 0);
                    this.slideTransition(image2.id, (img2_tran / this.transitionSteps), 0, step < 0);
                    if (text1 != null) {
                        this.fadeTransition(text1.id, (((img1_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                        this.fadeTransition(text2.id, (((img2_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                    }
                    break;
                }
            case 4:
                {
                    this.slideTransition(image1.id, (img1_tran / this.transitionSteps), 0, step < 0);
                    this.slideTransition(image2.id, (img2_tran / this.transitionSteps), 0, step > 0);
                    if (text1 != null) {
                        this.fadeTransition(text1.id, (((img1_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                        this.fadeTransition(text2.id, (((img2_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                    }
                    break;
                }
            case 5:
                {
                    if (Math.abs(timerIndex) == (this.transitionSteps * this.pauseTime / this.transitionTime)) {
                        dirh = Math.round(Math.random());
                        dirv = Math.round(Math.random());
                    }
                    this.slideTransition(image1.id, (img1_tran / this.transitionSteps), dirv == 1, dirh == 1);
                    this.slideTransition(image2.id, (img2_tran / this.transitionSteps), dirv == 1, dirh == 0);
                    if (text1 != null) {
                        this.fadeTransition(text1.id, (((img1_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                        this.fadeTransition(text2.id, (((img2_tran / this.transitionSteps) * 1.5) - 0.5) * 0.75);
                    }
                    break;
                }

        }
    }
    
    // Set the fade/opacity for a control
    this.fadeTransition = function( ID, opacity )
    {
        var browser="unknown";    
        var userAgent = navigator.userAgent.toLowerCase();      
        if (userAgent.indexOf("konqueror") > -1)        
            document.getElementById(ID).style.KhtmlOpacity = opacity; 
        else if (userAgent.indexOf("firefox") > -1)        
            document.getElementById(ID).style.MozOpacity = opacity;     
        else if (userAgent.indexOf("opera") > -1)        
            document.getElementById(ID).style.opacity = opacity;     
        else if (userAgent.indexOf("msie") > -1)
            document.getElementById(ID).style.filter = "alpha(opacity="+(opacity*100)+");";
        else
        {     
            document.getElementById(ID).src = banner[j].src;
            document.getElementById(ID).style.opacity = opacity;  
        }  
    }

    // Set the slide transition for each image control
    this.slideTransition = function(ID, trans, horizontal, anchor) {
        ctl = document.getElementById(ID);

        if (horizontal == 1) {
            if (anchor == 0) {
                ctl.style.width = "" + (imageWidth * trans) + "px";
                ctl.style.left = imageLeft + "px";
                ctl.style.height = imageHeight + "px";
                ctl.style.top = imageTop + "px";
            }
            else {
                ctl.style.width = "" + (imageWidth * trans) + "px";
                ctl.style.left = imageLeft + (imageWidth * (1 - trans)) + "px";
                ctl.style.height = imageHeight + "px";
                ctl.style.top = imageTop + "px";
            }
        } else {
            if (anchor == 0) {
                ctl.style.height = "" + (imageHeight * trans) + "px";
                ctl.style.top = imageTop + "px";
                ctl.style.width = imageWidth + "px";
                ctl.style.left = imageLeft + "px";
            }
            else {
                ctl.style.height = "" + (imageHeight * trans) + "px";
                ctl.style.top = imageTop + (imageHeight * (1 - trans)) + "px";
                ctl.style.width = imageWidth + "px";
                ctl.style.left = imageLeft + "px";
            }
        }
    }
}
