/*
** Ultimate Fade-In Slideshow (v1.5) Dynamic Drive (http://www.dynamicdrive.com)
** This notice MUST stay intact for legal use Visit http://www.dynamicdrive.com/
** for this script and 100s more. Updated for better Safari & Opera 9+
** Compliance and modified for a LightBox 2.0 tie in by jscheuer1 in
** http://www.dynamicdrive.com/forums

** This code has been both heavily refactored and "mooified" (ala mootools,
** http://docs.mootools.net/) by Michael Owens. Also, the previous code that
** attempted to cope with older browsers has been completely removed. This
** version makes no pretense about it: if you are still using IE 5 or less,
** then, well, sorry.
*/

var Linterra = Linterra || {};

// From Douglass Crockford
String.prototype.supplant = function (o) {
    return this.replace(/{([^{}]*)}/g,
        function (a, b) {
            var r = o[b];
            return typeof r === 'string' || typeof r === 'number' ? r : a;
        }
    );
};

var fadebgcolor = "#ffffff";
 
// Set flag when preloaded image is loaded
function imageLoaded()
{
    // console.log('imageLoaded(): ' + this.src)
    this.loaded = true;
}

/* Two important differences here in the constructor. First is takes a name,
** meaning you must name the slideshow. This is not too much work for you. It's
** just cleaner this way. 

** Second, it takes a parentId, which is the name of an element to install the
** slideshow into. The reason we do it this way is that is can cause problems in
** IE if you try to install this in the div before the div has been close. The
** problem is that when the timer goes off and the code tries to load an image,
** it calls innerHTML, which modifies the div. IE does NOT like this and will
** throw a nasty 'Cannot load site...operation aborted.'

** So to do it correctly, you must call new fadeshow() outside of the div you
** want to install it into, and pass that div's id into the constructor. Then
** you avoid the 'operation aborted' problem in IE. Take the following example
** where you want to load a slideshow in a div with the id="frame". You would do
** the following:

<div id="frame"></div>

<script type="text/javascript">
var fadeimages = new Array();
 ... load image urls into fadeimages ...
new fadeshow("slideshow", "frame", fadeimages, 256, 192, 0, 3000, 1);
</script>
*/

Linterra.Fadeshow = function ( name, parentId, images, 
                               fadewidth, fadeheight, borderwidth, 
                               delay, pause, displayorder )
{
    // The name of this object (id of div)
    this.name = name;

    // The name of the currently visible canvas (the one that is on top).
    this.canvas = this.canvasName(1);

    // The index of the currently visible image. The first rotateImage() call
    // will set this to 0.
    this.imageIndex = -1;

    // The array containing the urls and descriptions of images.
    this.urls = images;

    // The time for the fade effect to transition
    this.fadeTime = 750;

    // The time to wait between fades
    this.transitionTime = 3000;

    // The time to wait when in pause mode
    this.pauseTime = 1000;

    // The array containing the preloaded images.
    this.images = [];

    // The border width of the slideshow
    this.border = parseInt(borderwidth);

    // These two attributes manage pausing the slideshow on mouseover.
    this.pausecheck = pause;
    this.mouseovercheck = 0;

    // Preload images
    for(i = 0; i < images.length; i++)
    {
        this.images[i]        = new Image();
        this.images[i].src    = this.urls[i][0];
        this.images[i].loaded = false;
        this.images[i].onload = imageLoaded;
    }
 
    fadewidth  = fadewidth  + this.border*2;
    fadeheight = fadeheight + this.border*2;

    // Opening of lightbox div
    var html = '<div style="display:none;">';
 
    for(var i_tem = 0; i_tem < this.urls.length; i_tem++)
    {
        html += '<a title="' + this.urls[i_tem][2] +  
                '" href="' + this.urls[i_tem][1] +  
                '" rel="lightboxhighres"> </a>';
    }

    // Closing of lightbox div
    html += '</div>';

    // This first div is the main frame which contains the two 
    // convas divs below.

    var text = '<div id="{id}" style="position:relative;width:{width}px;' +
               'height:{height}px;overflow:hidden;">';

    var params = { id:     this.name, 
                   width:  fadewidth, 
                   height: fadeheight };

    html += text.supplant(params);

    // First canvas div
    text = '<div id={id} style="position:absolute;width:{width}px;'      + 
           'height:{fadeheight}px;top:0;left:0;'                         +
           'filter:progid:DXImageTransform.Microsoft.alpha(opacity=10);' +
           'opacity:10;-moz-opacity:10;-khtml-opacity:10;'               + 
           'background-color:{color}"></div>';

    params = { id:     this.canvasName(0), 
               width:  fadewidth, 
               height: fadeheight,
               color:  fadebgcolor };

    html += text.supplant(params);

    // Second canvas div
    text = '<div id={id} style="position:absolute;width:{width}px;'      + 
           'height:{fadeheight}px;top:0;left:0;'                         +
           'filter:progid:DXImageTransform.Microsoft.alpha(opacity=10);' + 
           'opacity:10;-moz-opacity:10;'                                 +
           'background-color:{color}"></div>';

    params = { id:     this.canvasName(1), 
               width:  fadewidth, 
               height: fadeheight,
               color:  fadebgcolor };

    // Add and close frame div
    html += text.supplant(params) + '</div>';
    
    // Put the html in the parent element.
    $(parentId).innerHTML = html;

    // Start the animation.
    this.startit();
};

// Function to centrally define the canvass names in one place.
Linterra.Fadeshow.prototype.canvasName = function(num)
{
    return this.name + 'canvas' + num;
};

// Set the this.imageIndex to the index of the next loaded 
// image in the images array.
Linterra.Fadeshow.prototype.nextImage = function()
{
    // Records the last know good image index.
    var idx = this.imageIndex;

    // Keeps count of the number of images tested.
    var count = 0;

    while(1)
    {
        // Move to next successive image index
        this.imageIndex = this.imageIndex < this.images.length - 1 ? 
            this.imageIndex += 1 : 0;

        // Break if its image is loaded.
        if(this.images[this.imageIndex].loaded === true)
        {
            break;
        }

        count += 1;

        // If we have iterated over all of the images and none of them are loaded
        if(count >= this.images.length)
        {
            // If the current index is valid (not the -1 set on construction)
            if(this.imageidex >= 0)
            {
                // Reset index to the last known loaded image
                this.imageIndex = idx;
            }
            else
            {
                // There are no images loaded. So punt and use the first.
                this.imageIndex = 0;
            }

            break;
        }
    }
};

Linterra.Fadeshow.prototype.loadNext = function(canvas)
{
    // Get the next loaded image
    this.nextImage();

    // Get the next canvas name
    this.canvas = (this.canvas.slice(-1) == '1') ? 
        this.canvasName(0) : this.canvasName(1);
    
    // Use idx var for concision
    idx = this.imageIndex;

    // The HTML needed to display the new image, which we are going to generate
    var html = "";

    // Wrap with <a> if the image has an associated link
    if(this.urls[idx][1] !== "")
    {
        html = '<a title="' + this.urls[idx][2] + 
               '" href="' + this.urls[idx][1] + 
               '" rel="lightboxhighres">';
    }

    // Create the img element
    html += '<img src="' + this.images[idx].src + 
            '" border="' + this.border + 'px" alt="' + 
            this.urls[idx][2] + '">';

    // Close the <a> tag if used above
    if(this.urls[idx][1] !== "") 
    {
        html += '</a>';
    }

    // Reassign its contents with the html we just generated
    $(this.canvas).innerHTML = html;
};

// Example of using a closure to create a fade effect
function fade(id, start, end, increment, interval)
{
    var level = start;
    
    function step () {

        console.log('step() : ' + end + ' ' + level + ' ' + increment);

        $(id).setOpacity(level);

        // Adjust the level up
        level += increment;

        // If we have not reached 1, then keep iterating
        if(level < end)
        {
            setTimeout(step, interval);
        }
    }

    // Start the effect
    setTimeout(step, interval);
}

Linterra.Fadeshow.prototype.rotateImage = function()
{
    // If pause onMouseover is enabled
    if(this.pausecheck == 1 && this.mouseovercheck == 1)
    {
        // Set the state to pause mode.
        this.paused = true;

        // Tune timer to react faster so that when mouse moves off of the image
        // the slideshow will quickly respond by loading the next image.

        // Clear to current timer
        $clear(this.timer);

        // Set with a much shorter interval to increase the check frequency.
        this.timer = this.rotateImage.periodical(this.pauseTime, this);

        // Nothing left to do. Keep looping until mouse moves off.
        return;
    }
    else
    {
        // We have to make this pass to check the mouseout event and reset the
        // timer back to normal slideshow mode if we are moving out of a paused
        // state..
        if(this.paused === true)
        {
            this.paused = false;

            $clear(this.timer);

            // Reset timer to load subsequent images
            this.timer = this.rotateImage.periodical(this.transitionTime, this);
        }
    }

    // Load the next image
    this.loadNext();

    // Increase the z-index of the current canvas
    $(this.canvas).style.zIndex++;

    // console.log( "rotate() : Fading in " + this.canvas + ':' 
    //              + this.imageIndex + ". zindex=" 
    //              + $(this.canvas).style.zIndex );

    //fade(this.canvas, 0, 1, 0.1, 10)

    // Create a style effect to fade in the image.
    effect = new Fx.Tween( this.canvas, 
                           { property: "opacity", duration: this.fadeTime, 
	                         transition: Fx.Transitions.Cubic.easeOut
                           } ).set(0);

    // Fade in by given increment
    effect.start(0,1);
};
  
// Starts the slideshow
Linterra.Fadeshow.prototype.startit = function()
{
    var self = this;
    var slideShowDiv = $(this.name);

    if(this.pausecheck == 1)
    { 
        slideShowDiv.onmouseover = function()
        { 
	    Slimbox.scanPage();
            self.mouseovercheck = 1;
        };
        
        slideShowDiv.onmouseout = function()
        {
            self.mouseovercheck = 0;
        };
    }

    // Load the first image
    this.rotateImage();

    // Set timer to load subsequent images
    this.timer = this.rotateImage.periodical(5000, this);
};

