(function($) {
  $.fn.mycarousel = function(o) {
        return this.each(function() {
            new $mc(this, o);
        });
    };

    var defaults = {
        offset: 1,
        size: 10,
        elementWidth: 90,
        elementHeight: 90,
        elementPadding: 5,
        viewableItems: 3,
        items: null,
        itemStart: 1,
        animation: 'normal',
        easing: 'swing',
        nextButton : null,
        prevButton : null,
        fetchMoreCallback : null,
        fetchChunk: 24,
        current: -1
    };

    $.mycarousel = function(e, o) {
        this.container = $(e);
        this.container.hide ();
        this.pendingMore = 0;
        this.options    = $.extend({}, defaults, o || {});
        this.current = this.options.offset;
        this.width = (this.options.size * this.options.elementWidth) +
                     (this.options.size * this.options.elementPadding);
        this.nextButton = $('#' + this.options.nextButton);
        this.prevButton = $('#' + this.options.prevButton);
        var carousel = this;
        this.nextButton.click (function() {
           carousel.next();
           return false;
        });
        this.prevButton.click (function() {
           carousel.prev();
           return false;
        });

        var w = (this.options.viewableItems * this.options.elementWidth) +
                     ((this.options.viewableItems) * this.options.elementPadding);
        this.container.css ("width", w);
        this.container.css ("height", this.options.elementHeight);
        this.container.css ("display", "block");
        this.container.append ("<div class=\"mycarousel-clip\"></div>");
        this.clip = $('.mycarousel-clip', this.container);
        this.clip.css ("overflow", "hidden");
        this.clip.css ("width", w);
        this.clip.css ("position", "relative");
        this.clip.css ("padding", "0px");
        this.clip.css ("margin", "0px");
        this.clip.css ("height", this.options.elementHeight);
        this.addItems (this.options.items, this.options.itemStart);
        
        this.togglePrevNext ();
        this.container.show ();
   };
    
   var $mc = $.mycarousel;
   $mc.fn = $mc.prototype = {
        mycarousel: '0.1'
    };
   $mc.fn.extend = $mc.extend = $.extend;

   $mc.fn.extend({
       
        addItems: function (items, itemStart) {
         if (this.pendingMore != 0) {
            if ((this.pendingMore < itemStart) ||
                (this.pendingMore > (itemStart + items.length - 1)))
            {
               return;
            }
         }
         $(".mycarousel-list", this.container).remove ();
         this.clip.append ("<div class=\"mycarousel-list\"></div>");
         this.list = $('.mycarousel-list', this.clip);
         this.list.css ("position", "relative");
         this.list.css ("padding", "0px");
         var i = itemStart;
         var carousel = this;
         $.each (items, function () {
             if (i <= carousel.options.size) {
               carousel.list.append ("<div id=\"el" + i + "\">" + this + "</div>");
               el = $("#el" + i, carousel.list);
               el.css ("float", "left");
               el.css ("top", "0px");
               el.css ("width", carousel.options.elementWidth + "px");
               el.css ("margin-right", carousel.options.elementPadding + "px");
               if (i == carousel.options.current) {
                  el.addClass("carousel-current");
               }
               i = i + 1;
             }
          });
          carousel.itemStart = itemStart;
          carousel.itemLast = itemStart + items.length - 1;
          var width = items.length * (this.options.elementWidth + this.options.elementPadding);
          carousel.list.css ("width", width + "px");
          carousel.list.css ("left", this.getpos (carousel.current) + "px");
          if (this.pendingMore != 0) {
            this.current = this.pendingMore;
            this.doanimate (); carousel.list.css ("left", this.getpos (carousel.current) + "px");
          }
        },
        getpos: function (i) {
          return  -((i - this.itemStart) * (this.options.elementWidth + this.options.elementPadding));
        },
        fetchMore: function(i,p) {
          this.pendingMore = i;
          this.options.fetchMoreCallback (this, this.current - 
                 (p ? (this.options.fetchChunk - this.options.viewableItems) : 0), this.options.fetchChunk);
        },
        next: function () {
          if (this.current >= this.options.size) {
             return;
          }
          var n = this.current + this.options.viewableItems;
          var lastNext = this.options.size - this.options.viewableItems + 1;
          if (lastNext < 0) {
             lastNext = 1;
          }
          if (n > lastNext) {
             n = lastNext;
          }
          var l = n + this.options.viewableItems - 1;
          if (l > this.options.size) {
             l = this.options.size;
          }
          if (l > this.itemLast) {
             this.fetchMore (n, false);
             return;
          }
          this.current = n;
          this.doanimate ();
        },
        prev: function () {
           if (this.current <= 1) {
             return;
          }
          var p = this.current - this.options.viewableItems;
          if (p < 1) {
             p = 1;
          }
          if (p < this.itemStart) {
             this.fetchMore (p, true);
             return;
          }
          this.current = p;
          this.doanimate ();
        },
        togglePrevNext: function () {
           if (this.current > 1) {
              this.prevButton.fadeIn();
           } else {
              this.prevButton.fadeOut();
           }
           if ((this.current + this.options.viewableItems - 1) < this.options.size) {
              this.nextButton.fadeIn();
           } else {
              this.nextButton.fadeOut();
           }
        },
        doanimate: function () {
          var carousel = this;
          var scrolled = function() {
             carousel.togglePrevNext ();
          };
          var p = this.getpos (this.current);
          this.list.animate({'left': p}, this.options.animation, this.options.easing, scrolled);
        }
   });
})(jQuery);


