(function($){  
    $.fn.rotator = function(options){
      
        function setAutoRotate(){
          clearTimeout(timeout);
          timeout  = setTimeout(function(){
             $(obj).find(options.next).click();
             setAutoRotate();
          },options.interval);
        }

         function getMaxIndex(){
          var tempIndex = 0;
          $(obj).find(options.item).each(function(){
             if($(this).attr("index") > tempIndex){
               tempIndex = $(this).attr("index");
             }
          });
          return tempIndex;
        }
      
        var defaults = {
            showDelay: 1000,
            showFadeTime: 1000,
            item: "ul li",
            previous: ".previous",
            next: ".next",
            fade: true,
            fadeTo: 0,
            duration: 500,
            distance: 50,
            auto: true,
            interval: 5000,
            change: function(item){},
            changeEnd: function(item){}
        }
        
        var options = $.extend(defaults, options);
        
        var index = 0;
        var timeout;
        var obj = this;
        if(!options.fade){
            options.fadeTo = 1;
        }
      
      $(obj).find(options.item).each(function(){
        $(this).attr("index", index++);
      });
        
        $(obj).find(options.previous).click(function(){
            index = ((index - 1) < 0) ? getMaxIndex() : (index - 1);
          
           var items = $(obj).find(options.item);
           if(items.length <= 1)
             return false;

           items.each(function(){
             if($(this).hasClass("current")){
               var elem = this;
               $(this).removeClass("current");
               $(this).css({left: "0", opacity: "1", display: "block"});
               $(this).animate({"left": options.distance, "opacity": options.fadeTo}, {queue: false, duration: options.duration, complete: function(){
                 if(!$(elem).hasClass("current")){
                    $(elem).css("display","none");
                 }
               }});
             }
             if($(this).attr("index") == index){
               var elem = this;
               $(this).css("left", -(options.distance)).css("display","block").css("opacity",options.fadeTo);
               $(this).animate({"left": "0", "opacity": "1"},{queue: false, duration: options.duration, complete: function(){
                 if($.isFunction(options.changeEnd)){
                     options.changeEnd($(elem));
                 }
               }});
               if($.isFunction(options.change)){
                   options.change($(elem));
               }
               $(this).addClass("current");
             }
           });
          setAutoRotate();
          return false;
        });
        $(obj).find(options.next).click(function(){
           index = ((index + 1) > getMaxIndex()) ? 0 : (index + 1);
           var items = $(obj).find(options.item);
           if(items.length <= 1)
             return false;
           items.each(function(){
             if($(this).hasClass("current")){
               var elem = this;
               $(this).removeClass("current");
               $(this).css({left: "0", opacity: "1", display: "block"});
               $(this).animate({"left": -(options.distance), "opacity": options.fadeTo}, {queue: false, duration: options.duration, complete: function(){
                if(!$(elem).hasClass("current")){
                    $(elem).css("display","none");
                  }
                }});
             }
             if($(this).attr("index") == index){
               var elem = this;
               $(this).css("left", options.distance).css("display","block").css("opacity",options.fadeTo);
               $(this).animate({"left": "0", "opacity": "1"},{queue: false, duration: options.duration, complete: function(){
                 if($.isFunction(options.changeEnd)){
                     options.changeEnd($(elem));
                 }
               }});
               if($.isFunction(options.change)){
                   options.change($(elem));
               }
               $(this).addClass("current");
             }
           });
            setAutoRotate();
            return false;
        });
        index = 0;
        $(obj).find(options.item).each(function(){
          if($(this).attr("index") == index){
            var elem = this;
            $(this).delay(options.showDelay).fadeIn(options.showFadeTime, function(){
              if($.isFunction(options.changeEnd)){
                  options.changeEnd($(elem));
              }
            });
            if($.isFunction(options.change)){
                options.change($(elem));
            }
            $(this).addClass("current");
          }
        });
        setAutoRotate();
    }
})(jQuery);
