/**
* jQuery Slideshow
* Author: Savut Sang
*
* Usage:
* Ex: jQuery("#slides").slideshow();
* Ex: jQuery("#slides").slideshow( {'speed': 300, 'auto': false, 'transition' : 'slideUp'} );
* Ex: jQuery("#slides").slideshow( {'speed': 900} );
*
* Pause animation:  jQuery("#slides").slideshow( "pause" );
* Resume animation: jQuery("#slides").slideshow( "resume" );
*
* Change default values for all instance:
* ex: jQuery.slideshow.defaults.speed = 900;
* ex: jQuery.slideshow.defaults.auto = false;
*
* FYI: $e represente tous le temps une instance individuel des selectors, donc equivalent du $(this) dans le each() loop.
* FYI: $t represente tous le temps les tabs du container current.
* FYI: $s represente tous le temps les slides du container current.
*/
(function($) {
    $.slideshow = {
        // default options
        defaults: {
            speed: 500,     /* (Integer) animation speed */
            auto: true,     /* [true|false] change slides automatically */
            timeout: 3000,  /* (Integer) milliseconds pour le auto scroll */
            transition: "fade",  /* ["slideUp"|"slideLeft"|"slideRight"|"slideHorizontal"|"fade"] */
            tabsSelector: ".slideshow-tabs",
            slidesSelector: ".slideshow-slides",
            startIndex: 0,
            step: 1,        /* (Integer) number of items to slide at the time (use only for slideHorizontal for the moment) */
            showItems: 3,   /* (Integer) number of items to show at the time */
            navigation: false,
            navigationPrevButton: '&lt;',
            navigationNextButton: '&gt;'
        },

        setOptions: function($e, options) {
            $e.data("jQuerySlideshowOptions", options);
        },

        getOptions: function($e) {
            return $e.data("jQuerySlideshowOptions");;
        },

        clearTimer: function($e){
            var opts = this.getOptions($e);
            clearTimeout(opts.timer);
        },

        startTimer: function($e){
            var opts = this.getOptions($e);
            this.clearTimer($e); // dans le cas ou il nous reste un timer en cour, on veut le clear parce on restart un nouveau.

            opts.timer = setTimeout(function(){
                $.slideshow.timerHit($e);
            }, opts.timeout);
        },

        timerHit: function($e) {
            this.changeSlideNext($e);
            this.startTimer($e);
        },

        changeSlidePrev: function($e) {
            var opts = this.getOptions($e);

            var nextIndex = opts.currentIndex - opts.step;

            if (opts.circular) {
                if (nextIndex < 0) {
                    nextIndex = opts.countSlides - 1;
                }
                this.changeSlide($e, nextIndex);
            } else {
                if (opts.currentIndex > 0) {
                    if (nextIndex < 0) {
                        nextIndex = 0;
                    }
                    this.changeSlide($e, nextIndex);
                    this.disabledOffsetNavigation($e);
                }
            }
        },

        changeSlideNext: function($e) {
            var opts = this.getOptions($e);

            var nextIndex = opts.currentIndex + opts.step;

            if (opts.circular) {
                if (nextIndex >= opts.countSlides) {
                    nextIndex = 0;
                }
                this.changeSlide($e, nextIndex);
            } else {
                var lastVisibleOffset = opts.countSlides - opts.showItems;
                if (opts.currentIndex < lastVisibleOffset) {
                    if (nextIndex > lastVisibleOffset) {
                        nextIndex = lastVisibleOffset;
                    }
                    this.changeSlide($e, nextIndex);
                    this.disabledOffsetNavigation($e);
                }
            }
        },

        disabledOffsetNavigation: function($e){
            var opts = this.getOptions($e);
            var $bp = $(".slideshow-prev", $e);
            var $bn = $(".slideshow-next", $e);

            $bp.removeClass('slideshow-prev-disabled');
            $bn.removeClass('slideshow-next-disabled');

            var lastVisibleOffset = opts.countSlides - opts.showItems;
            
            if (opts.currentIndex <= 0) {
                $bp.addClass('slideshow-prev-disabled');
            }
            if (opts.currentIndex >= lastVisibleOffset) {
                $bn.addClass('slideshow-next-disabled');
            }
        },

        changeSlide: function($e, index) {
            var opts = this.getOptions($e);
            opts.currentIndex = index;

            var $t = $(".slideshow-tabs", $e);
            var $s = $(".slideshow-slides", $e);

            // Gestion des tabs et change le current index a celui qui est clique
            $t.find(">li").removeClass("active");
            $t.find(">li:eq("+index+")").addClass("active");

            switch (opts.transition) {
                case 'slideUp':
                    var topPosition = opts.slideHeight * -1;

                    $s.append("<li>" + opts.items[index] + "</li>");
                    $s.animate({'top': topPosition}, opts.speed, function(){
                        $s.find(">li:first").remove();
                        $s.css('top', 0);
                    });
                    break;

                case 'slideLeft':
                    leftPosition = opts.slideWidth * -1;

                    $s.append("<li>" + opts.items[index] + "</li>");
                    $s.animate({'left': leftPosition}, opts.speed, function(){
                        $s.find(">li:first").remove();
                        $s.css('left', 0);
                    });
                    break;

                case 'slideRight':
                    leftPosition = 0;

                    $s.css('left', opts.slideWidth * -1);
                    $s.prepend("<li>" + opts.items[index] + "</li>");
                    $s.animate({'left': leftPosition}, opts.speed, function(){
                        $s.find(">li:last").remove();
                        $s.css('left', 0);
                    });
                    break;

                case 'slideHorizontal':
                    var pos = $s.find(">li:eq("+index+")").position();
                    leftPosition = pos.left * -1;
                    $s.width(opts.slideWidth * opts.countSlides);
                    $s.animate({'left': leftPosition}, opts.speed);
                    break;

                case 'fade':
                    $s.find("li:visible").fadeOut(opts.speed);
                    $s.find(">li:eq("+index+")").fadeIn(opts.speed);
                    break;
            }

            // restart the timer if auto (keep going)
            if (opts.auto == true) {
                this.startTimer($e);
            }
        },

        saveSlidesToItems: function($e) {
            var opts = this.getOptions($e);
            var $s = $(".slideshow-slides", $e);

            opts.items = new Array;
            $s.find(">li").each(function(index){
                opts.items.push( $(this).html() );
                if (index != opts.startIndex) {
                    $(this).remove();
                }
            });
        }
    }


    /**
     * params peut etre un objet pour l'initialisation
     * ou un string pour une commande
     */
    $.fn.slideshow = function(params) {
        if (typeof params == 'string') {

            return this.each(function() {
                var $e = $(this);

                switch (params) {
                    case "pause":
                        $.slideshow.clearTimer($e);
                        break;

                    case "resume":
                        $.slideshow.startTimer($e);
                        break;
                }
            });

        } else {

            // Continue pour creation
            var options = $.extend({}, $.slideshow.defaults, params);

            // selector options
            return this.each(function() {
                var $e = $(this);

                // instance options
                var opts = $.extend({}, options, {
                    timer: null,
                    items: null,
                    currentIndex: 0,
                    circular: true,
                    countSlides: $(options.slidesSelector, $e).find(">li").length,
                    slideHeight: $(options.slidesSelector, $e).find(">li:first").outerHeight(),
                    slideWidth: $(options.slidesSelector, $e).find(">li:first").outerWidth()
                });

                if (opts.startIndex < 0) {
                    opts.startIndex = 0;
                }

                // On sauvegarde l'options dans l'objet mere, cela permet d'appeler encore l'objet et d'avoir access a ses options
                $.slideshow.setOptions($e, opts);

                var $t = $(opts.tabsSelector, $e);
                var $s = $(opts.slidesSelector, $e);


                /**
                 * Ajoute les elements et les classes necessaire au bon fonctionnement du plugin
                 */
                
                if ($(".slideshow-wrapper", $e).length == 0) {
                    var $tempWrapper = $("<div />").addClass('slideshow-wrapper');
                    $s.wrap($tempWrapper);
                }

                if (opts.navigation) {
                    if ($('.slideshow-next', $e).length == 0) {
                        $e.prepend("<a class='slideshow-next'>"+ opts.navigationNextButton +"</a>");
                    }
                    if ($('.slideshow-prev', $e).length == 0) {
                        $e.prepend("<a class='slideshow-prev'>"+ opts.navigationPrevButton +"</a>");
                    }
                }

                // Ajouter les classes
                if (!$e.hasClass("slideshow")) {$e.addClass("slideshow");}
                if (!$t.hasClass("slideshow-tabs")) {$t.addClass("slideshow-tabs");}
                if (!$s.hasClass("slideshow-slides")) {$s.addClass("slideshow-slides");}
                
                var $w  = $(".slideshow-wrapper", $e);
                var $bp = $(".slideshow-prev", $e);
                var $bn = $(".slideshow-next", $e);



                // Transition effect between slide
                switch (opts.transition) {
                    case 'slideUp':    // circular
                        $s.addClass("slideshow-slides-vertical");
                        $.slideshow.saveSlidesToItems($e);
                        break;
                    case 'slideLeft': // circular
                        $s.addClass("slideshow-slides-horizontal");
                        $s.width( opts.slideWidth * 2 );
                        $.slideshow.saveSlidesToItems($e);
                        break;
                    case 'slideRight': // circular
                        $s.addClass("slideshow-slides-horizontal");
                        $s.width( opts.slideWidth * 2 );
                        $.slideshow.saveSlidesToItems($e);
                        break;

                    case 'slideHorizontal':    // non circular
                        $s.addClass("slideshow-slides-horizontal");
                        opts.circular = false;
                        $s.width( opts.slideWidth * opts.countSlides );
                        $s.css('left', opts.slideWidth * opts.startIndex * -1);
                        break;
                    case 'fade': // circular
                        $s.addClass("slideshow-slides-absolute");
                        $s.find(">li:eq("+opts.startIndex+")").show();
                        break;
                }


                // Ajoute les events pour les tabs, quand on click sur un tabs, ca affiche le content
                // et ca clear le timer automatic rotation
                var tabIndex = 0;
                $t.find(">li").unbind('click');
                $t.find(">li").each(function(){
                    $(this)
                        .data("jSlideshowTabIndex", tabIndex)
                        .click(function(){
                            $.slideshow.changeSlide($e, $(this).data("jSlideshowTabIndex"));
                        });
                    tabIndex++;
                });

                $bp.unbind('click');
                $bn.unbind('click');
                $bp.click(function(){$.slideshow.changeSlidePrev($e);});
                $bn.click(function(){$.slideshow.changeSlideNext($e);});


                /**
                 * Initial
                 */
                opts.currentIndex = opts.startIndex;
                
                if ($w.width() == 0)  {$w.css('width', opts.slideWidth);}
                if ($w.height() == 0) {$w.css('height', opts.slideHeight);}

                $t.find(">li").removeClass("active");
                $t.find(">li:eq("+opts.currentIndex+")").addClass("active");
                $.slideshow.disabledOffsetNavigation($e);

                // Demarre le timer pour Auto
                if (opts.auto == true) {
                    $.slideshow.startTimer($e);
                }
            });

        }
    };

})(jQuery);
