/**
 * Based on innerfade.js by Torsten Baldes http://medienfreunde.com
 * 
 * author Arjay Aquino
 * 
 * This Plugin adds callbacks and a Widget-like plugin architecture to the existing innerfade.js
 * Other features: Ability to pause slideshow when user hovers on slide, and can auto rotate the slides 
 * how ever many times it is set to.
 * 
 * Sample Usage with Callbacks:
 * 		$('#slideshowCont').slideshow({
 *			speed             : 1400,
 *			timeout           : 6000,
 *			type              : 'sequence',
 *			containerheight   : 'auto',
 *			autoRotate        : true,
 *			maxRotateCount    : 0, //how many times the slide show will auto rotate. 0 is infinite
 *			pauseOnHover      : false, //if true, the slideshow will pause if mouse hovers on slideshow
 *			slideDesc         : 'banner-desc',
 *			slideshowNav      : 'banner-menu',
 *			slideChangeStart  : function(args){ onSlideChangeStart(args); }, //called when slide is called to show
 *			slideChangeEnd    : function(args){ onSlideChangeEnd(args); }    //called when slide is done showing
 *		});
 *
 * Each call back passes in an args object. The object keys are: slideID, cause, tagName, count
 * 
 * To call a public function for this plugin do this:
 * 		$("elementname").data("SlideShow").publicMethod(args);
 * 
 */

(function($) {

    /**
    * PLUGIN CONSTRUCTOR
    */
    $.fn.slideshow = function(options) {

        return this.each(function() {
            new SlideShow(this, options);
        });
    }


    /**
    * PLUGIN CLASS
    * 
    * This plugin uses a Class pattern. An instance of this class will be attached to the HTML Element which 
    * allows for calling public methods on a specific INSTANCE.
    * 
    * init() method is called on SlideShow creation.
    */
    var SlideShow = function(element, options) {

        var PLUGIN_NAME = "SlideShow";

        element = $(element);
        element.data(PLUGIN_NAME, this); //store reference to SlideShow object in the element

        var counter = 0; //keeps track of how many times the slides have reached the end
        var isPlaying = false; //play state
        var currentSlideID = 0;    //reference to slide that needs to show
        var oldSlideID = currentSlideID; //reference to slide that needs to hide
        var changeCause = "Auto"; //what causes the slides to change.. 
        //can be 'Click' for clicking on the nav or 'Auto' for auto rotation

        var options, slideList, slideDescList, slideInterval;

        /**
        * PUBLIC METHODS
        */
        this.togglePause = function() {
            pausePlay();

            /*
            * added so that pause on hover doesnt toggle the slideshow to play when 
            * the slideshow has been paused intentionally by something else
            */
            if (isPlaying)
                options.pauseOnHover = true;
            else
                options.pauseOnHover = false;
        }

        this.setHoverOnPause = function(value) {
            options.pauseOnHover = value; //true or false
        }


        /**
        * SLIDE SHOW
        */
        /**
        * Hide the slides and give them appropriate z index.
        * Show the first Slide.
        */
        var setUpSlideShow = function() {

            if (slideList.length > 1) {
                for (var i = 0; i < slideList.length; i++) {
                    $(slideList[i]).css('z-index', String(slideList.length - i)).css('position', 'absolute').hide();

                    if (options.slideDesc != null)
                        $(slideDescList[i]).css('z-index', String(slideDescList.length - i)).css('position', 'absolute').hide();
                }
            }

            if (options.type == "sequence") {

                showFirstSlide();

                if (options.autoRotate)
                    setUpTimer();

            } else {
                alert('Innerfade-Type must either be \'sequence\', \'random\' or \'random_start\'');
            }
        }


        /**
        * Display the first slide and its description.
        */
        var showFirstSlide = function() {

            $(slideList[0]).show();

            if (options.slideDesc != null)
                $(slideDescList[0]).show();
//alert($(slideDescList[0])); first start
            if (options.slideShowNav != null) {
                $("#" + options.slideShowNav + " li").removeAttr("id");
                $("#" + options.slideShowNav + " .slide_0").attr("id", "button_selected");
            }
        }


        /**
        * Shows the new slide using the updated ids.
        * Hide the old slide before showing the new one.
        */
        var showSlide = function() {

            initiateCallBack("start");
 //alert(options.animationtype); 
            switch (options.animationtype) {
                case "fade":
                    //fade out the old slide before fading in the new one
                    $(slideList[oldSlideID]).fadeOut(options.speed);
                    if (options.slideDesc != null)
                        $(slideDescList[oldSlideID]).fadeOut(options.speed);

                    //fade in the new slide
                    $(slideList[currentSlideID]).fadeIn(options.speed, function() {
                        removeFilter($(this)[0]);
                        initiateCallBack("end");
                    });
                    if (options.slideDesc != null) {
                        $(slideDescList[currentSlideID]).fadeIn(options.speed, function() {
                            removeFilter($(this)[0]);
                        });
                    }
                    break; //end fade
            }

            //update nav items
            if (options.slideShowNav != null) {
                $("#" + options.slideShowNav + " li").removeAttr("id");
                $("#" + options.slideShowNav + " .slide_" + currentSlideID).attr("id", "button_selected");
            }
        }


        /**
        * Updates the current slide id and keeps a reference to the last id.
        * These will be used by showSlide method.
        */
        var nextSlide = function() {

            changeCause = "Auto";

            /*
            * if it is not at the end, show the next one otherwise show the first one
            * and keep a reference to the last id
            */
            if (currentSlideID < (slideList.length - 1)) {
                oldSlideID = currentSlideID;
                currentSlideID += 1;
                //var biTagNameAuto 	= $('.slide_'+currentSlideID).attr("name");   
                //crmEvent4({"num":currentSlideID+1, "placement":"Auto", "name":biTagNameAuto, "pageType":biPageType, "flashHTML":biPageType});
            } else {
                oldSlideID = currentSlideID;
                currentSlideID = 0;
                counter += 1; //count everytime the slide reaches the end

            }

            //stop auto rotating if max rotate count is reached
            if (counter == options.maxRotateCount) {
                stopTimer();
            }

            //show the slide using the updated ids
            showSlide();
        }


        var pausePlay = function() {
            //make sure it's set to auto rotate before toggling
            if (options.autoRotate) {
                if (isPlaying) {

                    if (options.slideShowPauseBTN != null) {
                        $("#" + options.slideShowPauseBTN + " span").html("play");
                        $("#" + options.slideShowPauseBTN).attr("class", "paused_button");
                    }

                    stopTimer();

                } else {

                    if (options.slideShowPauseBTN != null) {
                        $("#" + options.slideShowPauseBTN + " span").html("pause");
                        $("#" + options.slideShowPauseBTN).attr("class", "pause_button");

                    }

                    setUpTimer(); //load next slide
                }
            }
        }


        /**
        * Attach a click even to the nav items and grab the id from them.
        */
        var setUpNavButtons = function() {

            var buttonClass, splitButtonClassString, buttonClassString;

            $("#" + options.slideShowNav + " li").each(function() {

                $(this).click(function() {

                    if (options.slideShowPauseBTN != null) {
                        $("#" + options.slideShowPauseBTN + " span").html("play");
                        $("#" + options.slideShowPauseBTN).attr("class", "paused_button");
                    }

                    buttonClass = $(this).attr("class");
                    splitButtonClassString = buttonClass.split("_");
                    buttonClassString = splitButtonClassString.pop();
                    oldSlideID = currentSlideID;
                    currentSlideID = parseFloat(buttonClassString);

                    //var biTagName 			 = $(this).attr("name");
                    //crmEvent4({"num":currentSlideID+1, "placement":"Number", "name":biTagName, "pageType":biPageType, "flashHTML":biPageType});

                    changeCause = "Click";

                    options.autoRotate = false; //turns off auto rotate



                    stopTimer();
                    showSlide();
                });

            }); //each
        }


        /**
        * If there's a pause button, attach click to it
        */
        var setUpPauseButton = function() {

            var pauseButton = $(options.slideShowPauseBTN);

            pauseButton.click(function() {
                togglePause();
            });
        }


        /**
        * If slide desc is available use that for the hover on pause,
        * otherwise use the slide itself.
        */
        var setUpPauseOnHover = function() {

            if (options.slideDesc != null) {
                slideDescList.hover(function() {
                    if (options.pauseOnHover)
                        pausePlay();
                });
            } else {
                slideList.hover(function() {
                    if (options.pauseOnHover)
                        pausePlay();
                });
            }
        }


        /**
        * UTILS
        */
        var getDefaults = function() {

            return { animationtype: 'fade',
                speed: 'normal',
                type: 'sequence',
                timeout: 5000,
                containerheight: 'auto',
                autoRotate: false,
                maxLoopCount: 0,
                pauseOnHover: false,
                slideDesc: null,
                slideShowNav: null,
                slideShowPauseBTN: null,
                slideChangeStart: null,
                slideChangeEnd: null
            };
        }

        var setUpTimer = function() {
            isPlaying = true;
            slideInterval = setInterval(nextSlide, options.timeout);
        }

        var stopTimer = function() {
            isPlaying = false;

            if (slideInterval != null) {
                clearInterval(slideInterval);
                slideInterval = null;
            }
        }

        /**
        * remove Opacity-Filter in ie
        */
        var removeFilter = function(target) {
            if (target.style.removeAttribute) {
                target.style.removeAttribute('filter');
            }
        }


        /**
        * Call the callback methods and pass in information so that it can be used by the listener.
        */
        var initiateCallBack = function(name) {

            var slideTagName;

            /**
            * Grab the name of the slide from the nav items if there are any
            * otherwise use the id from the slide elements
            */
            if (options.slideShowNav != null) {
                slideTagName = $('.slide_' + currentSlideID).attr("name");
            } else {
                slideTagName = $(slideList[currentSlideID]).attr("id");
            }

            var callbackArgs = { slideID: currentSlideID,
                cause: changeCause,
                tagName: slideTagName,
                count: counter
            };

            switch (name) {
                case "start":
                    $.isFunction(options.slideChangeStart) && options.slideChangeStart.call(this, callbackArgs);
                    break;
                case "end":
                    $.isFunction(options.slideChangeEnd) && options.slideChangeEnd.call(this, callbackArgs);
                    break;
            }
        }


        /**
        * INIT
        */
        var init = function() {

            var defaults = getDefaults();
            options = $.extend(defaults, options);

            element.css({ position: "relative",
                height: options.containerheight
            })
				   .addClass(PLUGIN_NAME);

            slideList = element.children();

            if (options.slideDesc != null)
                slideDescList = $("ul#" + options.slideDesc + " li");

            if (options.slideShowNav)
                setUpNavButtons();

            if (options.slideShowPauseBTN)
                setUpPauseButton();

            if (options.pauseOnHover)
                setUpPauseOnHover();

            setUpSlideShow();
        }
        init();


    } //slideshow class


})(jQuery);


