(function($) {
  $.carousel = function(element, options) {
  
    var $element = $(element),
        element = element;
    
    var defaults = {
      scroll: 4,
      speed: 500,
      auto: false,
      autoTimeout: 5000,
      nav: true,
      navPosition: "before",
      page: 1,
      childType: "li",
      data: $element.attr("data-url"),
      length: $element.attr("data-length") ? parseInt($element.attr("data-length"),10) : 50
    }
    var plugin = this;
    plugin.settings = {}
    
    plugin.init = function() {
      plugin.settings = $.extend({}, defaults, options);
      
      // Setting/retrieving extra options
      plugin.settings.scroll = ($element.attr("data-scroll")) ? $element.attr("data-scroll") : plugin.settings.scroll;
      plugin.settings.margin = {
        left: parseInt($element.children(plugin.settings.childType).css("margin-left"),10),
        right: parseInt($element.children(plugin.settings.childType).css("margin-right"),10)
      };
      plugin.settings.children = $element.children(plugin.settings.childType);
      plugin.settings.current = plugin.settings.page;
      plugin.settings.maxPage = Math.ceil(plugin.settings.length/plugin.settings.scroll);

      // Construct container and overflow
      $element.wrap("<div class='carousel_container'><div class='carousel_overflow' style='overflow: hidden;'><div class='carousel_scroller' /></div></div>");
      plugin.settings.container = $element.closest(".carousel_container");
      plugin.settings.scroller = $element.closest(".carousel_scroller");
      
      // Construct nav if we need one
      if(plugin.settings.nav === true && plugin.settings.length > plugin.settings.scroll) {
        var nav = $("<ul class='carousel_nav'><li><a href='#' class='carousel_prev inactive'>Prev</a></li><li><a href='#' class='carousel_next'>Next</a></li></ul>");
        if(plugin.settings.navPosition == "before") {
          plugin.settings.container.prepend(nav);
        } else {
          plugin.settings.container.append(nav);
        }
        
        $(".carousel_prev,.carousel_next",plugin.settings.container).click(function() {
          if($(this).hasClass("carousel_next")) {
            plugin.moveTo("next");
          } else if($(this).hasClass("carousel_prev")) {
            plugin.moveTo("prev");
          }
          return false;
        });
      }
      
      setWidth();
    }

    plugin.moveTo = function(page) {
      var next_page = plugin.settings.page+1;
      var prev_page = plugin.settings.page-1;
      var scroll;
      
      if(page == "next" && next_page <= plugin.settings.maxPage) {
        
        $(".carousel_prev",plugin.settings.container).removeClass("inactive");
        if(next_page == plugin.settings.maxPage) {
          var amountOnLastPage = plugin.settings.length-((plugin.settings.maxPage-1)*plugin.settings.scroll);
          scroll = scrollAmount(prev_page)+plugin.settings.children.outerWidth()*amountOnLastPage+(plugin.settings.margin.left+plugin.settings.margin.right)*amountOnLastPage;
          $(".carousel_next",plugin.settings.container).addClass("inactive");
        } else {
          scroll = scrollAmount(plugin.settings.page);
        }
        
        if($element.find("[data-page='"+next_page+"']").length <= 0) {
          var ajaxValues = {
            page: next_page,
            items: plugin.settings.scroll
          }
          if($element.attr("data-ids")) { 
            var idArray = $element.attr("data-ids").toString().split(",");
            ajaxValues.item_ids = idArray; 
          }
          if($element.attr("data-trend-id")) {
            ajaxValues.trend_id = $element.attr("data-trend-id");
          }
          $.get(plugin.settings.data, ajaxValues, function(data) {
            data = $(data);
            
            data.filter("li").attr("data-page",next_page);
            if($element.attr("data-ids")) {
              data.filter("li").each(function() {
                if($(this).attr("data-id")) {
                  idArray.push($(this).attr("data-id"));
                }
              });
              $element.attr("data-ids",idArray);
            }
            
            $element.append(data);
            setWidth();
            animate(scroll);
          });
        } else {
          animate(scroll);
        }
        plugin.settings.page = next_page;
        
      } else if(page == "prev" && prev_page >= 1) {
        scroll = scrollAmount(prev_page-1);
        $(".carousel_next",plugin.settings.container).removeClass("inactive");
        animate(scroll);
        plugin.settings.page = prev_page;
        
        if(prev_page == 1) {
          $(".carousel_prev",plugin.settings.container).addClass("inactive");
        }
      }
    }
    
    var animate = function(scroll) {
      plugin.settings.scroller.animate({
        marginLeft: -scroll
      },plugin.settings.speed);
    }
    
    var scrollAmount = function(page) {
      var scroll = page*plugin.settings.children.outerWidth()*plugin.settings.scroll+((plugin.settings.margin.left+plugin.settings.margin.right)*plugin.settings.scroll*(page));
      return scroll;
    }
    
    var setWidth = function() {
      carousel_width = getWidth();
      $element.css({
        width: carousel_width,
        overflow: "hidden"
      });
    }
    
    var getWidth = function() {
      var children = $element.children(plugin.settings.childType);
      var carousel_width = (plugin.settings.children.outerWidth()*children.length)+((plugin.settings.margin.left+plugin.settings.margin.right)*children.length);
      return carousel_width;
    }

    plugin.init();

  }

  $.fn.carousel = function(options) {

    return this.each(function() {
      if (undefined == $(this).data('carousel')) {
        var plugin = new $.carousel(this, options);
        $(this).data('carousel', plugin);
      }
    });

  }

})(jQuery);
