/***********************************************************************\
* File:     MoJoGridSlideshow.js                                        *
* Date:     March 30, 2010                                              *
* Author:   James Carpenter                                             *
* Purpose:  To create a slideshow that uses multiple images per slide   *
*           and positions them in a simple grid.  Handles the more      *
*           complex items such as X,Y position and Layering.            *
*                                                                       *
* Usage:    $('#mojoForm').mojoForm( {                                  *
*			    action  : '/inc/MoJoMailer06.asp',                      *
*               method  : 'POST',                        // default     *
*               button  : '#btnSubmit',                  // default     *
*               validate: function() { return true; }    // default     *
*			});                                                         *
\***********************************************************************/


// define a constant to be used below in calculations
var blockWidth = 111;
var animationInMs = 1200;
var animationOutMs = 300;
var delayBetweenSlides = 4500;

jQuery.fn.mojoGridSlideShow = function() {
    // create a new slide object
    var oSlideShow = $('<div>');

    oSlideShow.data('slides', new Array());
    oSlideShow.data('curSlide', -1);
    oSlideShow.data('playing', false);

    // create an AddSlide function... just keep a handle to the slide
    oSlideShow.addSlide = function(oSlide) {
        oSlideShow.data('slides').push(oSlide);
    }

    // create an StartSlideShow function... Handles playing of one slide to the next
    oSlideShow.startSlideShow = function() {
        // if we are not already started and there are slides to play
        if (oSlideShow.data('playing') == false && oSlideShow.data('slides').length > 1) {
            // get a quick handle to the current and next slide
            var curSlide = oSlideShow.getCurSlide();
            var nextSlide = oSlideShow.getNextSlide();

            // start the slide
            oSlideShow.data('slides')[curSlide].showSlide(oSlideShow);
        }
    }


    oSlideShow.showNextSlide = function() {
        // get a quick handle to the current and next slide
        var curSlide = oSlideShow.getCurSlide();
        var nextSlide = oSlideShow.getNextSlide();

        // hide the current and show the next slide
        oSlideShow.data('slides')[curSlide].hideSlide(oSlideShow.data('slides')[nextSlide], oSlideShow);

        // increment the current slide 
        oSlideShow.incrementCurSlide();
    }


    /**********************************\
    * CurSlide Getter/Setter/Increment *
    \**********************************/
    oSlideShow.getCurSlide = function() {
        // get a quick handle to the current slide
        var curSlide = oSlideShow.data('curSlide');

        // default to beginning if this is first start
        if (curSlide == -1 || curSlide == oSlideShow.data('slides').length)
            curSlide = 0;

        // return result
        return curSlide;

    }
    oSlideShow.setCurSlide = function(curSlide) {
        oSlideShow.data('curSlide', curSlide);
    }
    oSlideShow.incrementCurSlide = function() {
        // just use the getters & setters to handle all the logic
        oSlideShow.setCurSlide(oSlideShow.getNextSlide());
    }

    /******************\
    * NextSlide Getter *
    \******************/
    oSlideShow.getNextSlide = function() {
        // get a handle to the next slide and provide loop-around logic
        var nextSlide = oSlideShow.getCurSlide() + 1;
        if (nextSlide >= oSlideShow.data('slides').length)
            nextSlide = 0;

        // return result
        return nextSlide;
    }



    // finally, return the ss object
    return oSlideShow;
}

jQuery.fn.mojoGridSlide = function(titleImgScr) {
    // create a new slide object
    var oSlide = $('<div>');

    // assign it a slides object
    oSlide.data('titleImgScr', titleImgScr);
    oSlide.data('photos', new Array());

    // add title image to preloader div
    $('#imgHolder').append('<img src="' + titleImgScr + '" />');

    // create an AddPhoto function... just store all the new slide data
    oSlide.addPhoto = function(src, x, y, depth) {
        oSlide.data('photos').push({ 'src': src, 'x': x, 'y': y, 'depth': depth });
        // add to image holder (to preload the image)
        $('#imgHolder').append('<img src="' + src + '" />');
    }

    // clear out all old data and create new 
    oSlide.initSlide = function() {
        // clear out the wrapper
        $('#imgWrapper').html('');
        $('#featImgTitleWrapper').html('');

        for (var i = 0; i < oSlide.data('photos').length; i++) {
            // add the image inside imgWrapper, position it, set its class for z-index, and give it an ID based on index
            $('#imgWrapper').append(
                        $('<img src="' + oSlide.data('photos')[i].src + '" id="featImg' + i + '" />')
                            .css({
                                'left': (oSlide.data('photos')[i].x * blockWidth) + 'px',
                                'top': (oSlide.data('photos')[i].y * blockWidth) + 'px'
                            })
                            .attr('class', 'layer' + oSlide.data('photos')[i].depth)
                    );
        }

        // add the title image to the "featImgTitle" div
        $('#featImgTitleWrapper').append(
                    $('<img src="' + oSlide.data('titleImgScr') + '" id="featImgTitle" />').css('opacity', '0')
                );
    }

    // create a showSlide function to handle all the animation
    oSlide.showSlide = function(oSlideShow) {
        // init the current slide
        oSlide.initSlide();

        var numPhotos = oSlide.data("photos").length;

        // time the pics to fade in one after the other
        for (var i = 0; i < numPhotos; i++) {
            setTimeout("$('#featImg" + i + "').fadeIn(" + animationInMs + ");", (i + 1) * animationInMs);
        }

        // defaut width to 180 if we can read it from the image
        var imgWidth = $('#featImgTitle').width();
        imgWidth = (imgWidth == 0) ? 180 : imgWidth;
        
        // fade in the title immediaty (make it visible AND position it based on its width and its containers width)
        $('#featImgTitle').animate(
                    {
                        right: ($('#featImgTitleWrapper').width() - imgWidth) + 'px',
                        opacity: 1
                    },
                    animationInMs);


        // add initial animation time into transition delay
        var fadeInDelay = numPhotos * animationInMs;

        // Set the ShowNextSlide function to fire every delayBetweenSlides
        setTimeout(oSlideShow.showNextSlide, fadeInDelay + delayBetweenSlides);
    }

    // create a hide slide that takes the next slide as an argument... will kick off the next animation
    oSlide.hideSlide = function(nextSlide, oSlideShow) {
        var len = oSlide.data("photos").length;
        // time the pics to fade in one after the other
        for (var i = len - 1; i >= 0; i--) {
            setTimeout("$('#featImg" + i + "').fadeOut(" + animationOutMs + ");", (len - i) * animationOutMs);
        }

        // fade out slower than the rest
        $('#featImgTitle').animate({ opacity: 0 }, (len + 1) * animationOutMs)

        // set a timeout for the show next slide function, preserving the handle to the slideshow
        setTimeout(
            function() { nextSlide.showSlide(oSlideShow); },
            (len + 1) * animationOutMs);
    }


    // finally, pass the slide object back
    return oSlide;
};
