/**
 *  Basic slider
 *  Author : Antoine Brault
 *  Version: 2.1
 */
(function($){

  var defaults = {
    currentPosition : 0,
    numberOfSlidesDisplay : 2,
    isRightToLeft : true,
    slideSize : 200, // px
    isSizeFixed : true,
    isOppositeSizeFixed: true,
    fixScrollSize : 80, // px
    lazyLoadImages : true, // take "original" attr and move to src
    insertControls: true,
    pager: null,
    onBeforeMove: null,  // function(index, slide)
    onAfterMove: null,  // function(index, slide)
    animate: true,
    autoPlay: false,
    autoSpeed: 3500
  };

  var methods = {
    init : function( o ) {
        return this.each(function(){
            var isInit = $.data(this, 'basicslider');
            var options = $.extend({}, defaults, o || {});

            if(isInit){
                $.data(this, 'basicslider', $.extend($.data(this, 'basicslider'), options || {}));
            } else {
                 var $this = $(this);
                 var initData = {
                    size : options.isRightToLeft?'width':'height',
                    oppositeSize : options.isRightToLeft?'height':'width',
                    slideshow : $this,
                    slideshowContainer: $this.find('.slidesContainer'),
                    slides : null,
                    numberOfSlides : 0
                };
                initData.slides = $this.find('.slide');
                initData.numberOfSlides = initData.slides.length;
                $this.data('basicslider', initData);

                var data = $.extend($.data(this, 'basicslider'), options || {});

                var css =   {overflow : 'hidden',
                             position: 'relative'};
                css[data.size] = $this.css(data.size);

                if(data.slideshowContainer.length == 0){
                    data.slideshowContainer = $this;
                }
                data.slideshowContainer.css(css);

                if(data.numberOfSlides == 0){
                    data.slideshowContainer.append('<div class="slideInner"></div>')
                } else {
                    data.slides.wrapAll('<div class="slideInner"></div>');
                    data.slides.css(data.size, data.slideSize);
                }

                var sliderInner = $this.find('.slideInner');
                sliderInner.css({top : '0',
                                left : '0',
                                position: 'relative'});

                if(data.pager){
                    data.pagerElem = $(data.pager);

                    for(var i = 0; i < (data.numberOfSlides / data.numberOfSlidesDisplay); i++){
                        var link = $("<a href='#'>"+(i+1)+"</a>");

                        link.click((function(j){
                            return function(){
                                $this.basicSlider("move", j, true);
                                return false;
                            }
                        })(i));
                        data.pagerElem.append(link);
                    }
                }

                if(data.isSizeFixed){
                    // Set #slideInner width equal to total width of all slides
                    sliderInner.css(data.size, data.slideSize * data.numberOfSlides);
                } else {
                    data.slides = $this.find('.slide');

                    var size = 0;
                    var images = data.slides.find("img");
                    var imgCount = images.length;
                    if(imgCount > 0){
                        // if there is images, wait for the images to load and set the size afterwards.
                        var count = 0;
                        images.one("load", function(){
                            count++;
                            if(imgCount == count){
                                data.slides.each(function(){
                                    if(data.isRightToLeft)
                                        size += $(this).outerWidth(true);
                                    else
                                        size += $(this).outerHeight(true);
                                });
                                sliderInner.css(data.size, size);
                            }
                        }).one("error",function(){
                            count++;
                        }).each(function(){
                            if(this.complete || (jQuery.browser.msie && parseInt(jQuery.browser.version) == 6))
                                $(this).trigger("load");
                        });
                    } else {
                        data.slides.each(function(){
                            if(data.isRightToLeft)
                                size += $(this).outerWidth(true);
                            else
                                size += $(this).outerHeight(true);
                        });
                        sliderInner.css(data.size, size);
                    }
                }

                if(data.insertControls){
                    data.controlsInserted = true;
                    // Insert controls in the DOM
                    $this.prepend('<div class="prevControl"></div>').append('<div class="nextControl"></div>');
                }

                // Create event listeners for .controls clicks
                $this.find('.prevControl').bind('click', function(){
                    $this.basicSlider("prev", true);
                    return false;
                });
                $this.find('.nextControl').bind('click', function(){
                    $this.basicSlider("next", true);
                    return false;
                });

                var pos = data.currentPosition;
                data.currentPosition = -1;
                $this.basicSlider("move", pos);

                if(data.autoPlay){
                    data.timer = setInterval(function(){
                        if(data.currentPosition == data.numberOfSlides - 1){
                            $this.basicSlider("move", 0);
                        } else {
                            $this.basicSlider("next");
                        }
                    }, data.autoSpeed);
                }
            }
        });
    },
    add : function( slide, index ) {
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('basicslider');
            if(data){
                if(slide && slide.length > 0){
                    var sliderInner = $this.find('.slideInner');
                    var slideCleaned = slide.filter("div");

                    slideCleaned.css("display", "none");
                    slideCleaned.addClass("slide");
                    sliderInner.append(slideCleaned);
                    slideCleaned.show();

                    data.numberOfSlides = data.numberOfSlides + slideCleaned.length;

                    $this.basicSlider("refresh");
                }
            }
        });
    },
    remove : function( slide ) {
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('basicslider');
            if(data){
                if(slide && slide.length > 0){
                    slide.remove();
                    data.numberOfSlides = data.numberOfSlides - slide.length;

                    $this.basicSlider("refresh");
                }
            }
        });
    },
    refresh : function() {
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('basicslider');
            if(data){
                var sliderInner = $this.find('.slideInner');

                if(data.isSizeFixed){
                    // Set #slideInner width equal to total width of all slides
                    sliderInner.css(data.size, data.slideSize * data.numberOfSlides);
                    $this.basicSlider("move", data.currentPosition);
                } else {
                    data.slides = $this.find('.slide');
                    var size = 0;
                    var images = data.slides.find("img");
                    var imgCount = images.length;
                    if(imgCount > 0){
                        var count = 0;
                        images.one("load", function(){
                            count++;
                            if(imgCount == count){
                                data.slides.each(function(){
                                    if(data.isRightToLeft)
                                        size += $(this).outerWidth(true);
                                    else
                                        size += $(this).outerHeight(true);
                                });
                                sliderInner.css(data.size, size);
                            }
                        }).one("error",function(){
                            count++;
                        }).each(function(){
                            if(this.complete || (jQuery.browser.msie && parseInt(jQuery.browser.version) == 6))
                                $(this).trigger("load");
                        });
                    } else {
                        data.slides.each(function(){
                            if(data.isRightToLeft)
                                size += $(this).outerWidth(true);
                            else
                                size += $(this).outerHeight(true);
                        });
                        sliderInner.css(data.size, size);
                    }

                    if( (data.isRightToLeft && size > data.slideshowContainer.innerWidth())
                            || (!data.isRightToLeft && size > data.slideshowContainer.innerHeight()) ) {
                        $this.find('.nextControl').removeClass("disabled");
                    } else {
                        $this.find('.nextControl').addClass("disabled");
                    }

                    if(data.autoPlay){
                        if(data.timer){
                            clearInterval(data.timer);
                        }

                        data.timer = setInterval(function(){
                            if(data.currentPosition == data.numberOfSlides - 1){
                                $this.basicSlider("move", 0);
                            } else {
                                $this.basicSlider("next");
                            }
                        }, data.autoSpeed);
                    }
                }
            }
        });
    },
    move : function(position, clicked) {
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('basicslider');
            if(data && data.currentPosition != position){
                var sliderInner = $this.find('.slideInner');
                clicked = clicked ? clicked : false;

                if(data.onBeforeMove){
                    data.onBeforeMove(position, sliderInner.find(".slide").eq(position), clicked);
                }

                // Hide left arrow if position is first slide
                if(position <=0){ position = 0; $this.find('.prevControl').addClass("disabled"); } else { $this.find('.prevControl').removeClass("disabled"); }
                // Hide right arrow if position is last slide
                if(position>=data.numberOfSlides-data.numberOfSlidesDisplay){ position = data.numberOfSlides-data.numberOfSlidesDisplay; $this.find('.nextControl').addClass("disabled"); } else { $this.find('.nextControl').removeClass("disabled"); }

                if(data.pagerElem){
                    data.pagerElem.each(function(){
                        $(this).children().eq(data.currentPosition).removeClass("activeSlide");
                        $(this).children().eq(position).addClass("activeSlide");
                    });
                }

                position = position < 0 ? 0 : position;
                data.currentPosition = position;

                if(!data.isOppositeSizeFixed){
                    sliderInner.css(data.oppositeSize, data.slides.slice(data.currentPosition, data.currentPosition+data.numberOfSlidesDisplay).css(data.oppositeSize));
                    data.slideshowContainer.css(data.oppositeSize, data.slides.slice(data.currentPosition, data.currentPosition+data.numberOfSlidesDisplay).css(data.oppositeSize));
                }

                if(data.lazyLoadImages){
                    data.slides.slice(data.currentPosition, data.currentPosition+data.numberOfSlidesDisplay).find("img").each(function(){
                        var $this = $(this);
                        var original = $this.attr("original");
                        if(original != null && original.length > 0){
                            $this.attr("src", original);
                        }
                    });
                }

                // Move slideInner using margin
                if(data.animate){
                    if(data.isRightToLeft){
                        sliderInner.animate({ 'left' : data.slideSize*(-data.currentPosition) });
                    } else {
                        sliderInner.animate({ 'top' : data.slideSize*(-data.currentPosition) });
                    }
                } else {
                    if(data.isRightToLeft){
                        sliderInner.css({ 'left' : data.slideSize*(-data.currentPosition) });
                    } else {
                        sliderInner.css({ 'top' : data.slideSize*(-data.currentPosition) });
                    }
                }

                if(data.onAfterMove){
                    data.onAfterMove(position, sliderInner.find(".slide").eq(position), clicked);
                }
            }
        });
    },
    select : function(slide) {
        if(slide){
            return this.each(function(){
                var $this = $(this);
                var data = $this.data('basicslider');
                if(data){
                    if(slide){
                        var i = $this.find('.slide').index(slide);
                        if(i != -1){
                            $this.basicSlider("move", i);
                        }
                    }
                }
            });
        } else {
            return this.find('.slide').eq(this.data('basicslider').currentPosition);
        }
    },
    prev : function(clicked) {
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('basicslider');
            if(data){
                clicked = clicked ? clicked : false;

                if(data.isSizeFixed){
                     $this.basicSlider("move", data.currentPosition - 1, clicked);
                } else {
                    var sliderInner = $this.find('.slideInner');
                    if(data.isRightToLeft){
                        var scroll = parseInt(sliderInner.css("left").replace("px", "")) + data.fixScrollSize;

                        $this.find('.prevControl, .nextControl').removeClass("disabled");
                        if(scroll+5 > 0){
                            scroll = 0;
                            $this.find('.prevControl').addClass("disabled");
                        }
                        sliderInner.animate({ 'left' : scroll });
                    } else {
                        var scroll = parseInt(sliderInner.css("top").replace("px", "")) + data.fixScrollSize;

                        $this.find('.prevControl, .nextControl').removeClass("disabled");
                        if(scroll+5 > 0){
                            scroll = 0;
                            $this.find('.prevControl').addClass("disabled");
                        }
                        sliderInner.animate({ 'top' : scroll });
                    }
                }
            }
        });
    },
    next : function(clicked) {
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('basicslider');
            if(data){
                clicked = clicked ? clicked : false;
                if(data.isSizeFixed){
                     $this.basicSlider("move", data.currentPosition + 1, clicked);
                } else {
                    var sliderInner = $this.find('.slideInner');
                    if(data.isRightToLeft){
                        var left = parseInt(sliderInner.css("left").replace("px", ""));
                        var scroll =  left - data.fixScrollSize;
                        var maxScroll = sliderInner.outerWidth(true) - data.slideshowContainer.innerWidth();

                        $this.find('.prevControl, .nextControl').removeClass("disabled");
                        if(scroll-5 < -maxScroll){
                            scroll = -maxScroll;
                            $this.find('.nextControl').addClass("disabled");
                        }
                        sliderInner.animate({ 'left' : scroll });
                    } else {
                        var top = parseInt(sliderInner.css("top").replace("px", ""));
                        var scroll = top - data.fixScrollSize;
                        var maxScroll = sliderInner.outerHeight(true) - data.slideshowContainer.innerHeight();

                        $this.find('.prevControl, .nextControl').removeClass("disabled");
                        if(scroll-5 < -maxScroll){
                            scroll = -maxScroll;
                            $this.find('.nextControl').addClass("disabled");
                        }

                        sliderInner.animate({ 'top' : scroll });
                    }
                }
            }
        });
    },
    play : function() {
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('basicslider');
            if(data){
                data.autoPlay = true;

                if(data.timer){
                    clearInterval(data.timer);
                }

                data.timer = setInterval(function(){
                    if(data.currentPosition == data.numberOfSlides - 1){
                        $this.basicSlider("move", 0);
                    } else {
                        $this.basicSlider("next");
                    }
                }, data.autoSpeed);
            }
        });
    },
    stop : function() {
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('basicslider');
            if(data){
                data.autoPlay = false;

                if(data.timer){
                    clearInterval(data.timer);
                }
            }
        });
    },
    destroy : function() {
        return this.each(function(){
            var $this = $(this);
            var data = $this.data('basicslider');
            if(data){
                if(data.insertControls){
                    $this.find('.prevControl,.nextControl').remove();
                } else {
                    $this.find('.prevControl,.nextControl').unbind('click')
                }
                if(data.timer){
                    clearInterval(data.timer);
                }

                if(data.pagerElem){
                    data.pagerElem.children().remove();
                }
                var sliderInner = $this.find('.slideInner');
                data.slideshowContainer.append(sliderInner.children());
                sliderInner.remove();
                data.slideshowContainer.removeAttr("style");
                $this.removeData('basicslider');
            }
        });
    }
  };

  $.fn.basicSlider = function( method ) {
    // Method calling logic
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.basicSlider' );
    }
  };
})( jQuery );

