/**
 *  jQarousel — jQuery plugin to create a carousel-esque widget to navigation content.
 *
 *  http://steffanwilliams.co.uk/projects/jquery/jqarousel/   
 *
 * Version: 1.0
 */

;(function($) {
  $.fn.jqarousel = function(options) {
    var opts = $.extend({}, $.fn.jqarousel.defaults, options);
    
    return this.each(function() {
      
      if ($(this).children().length <= opts.scroll) return;
      
      $(this).wrap('<div class="jqarousel"><div class="carousel-outer-container" style="margin:0;padding:0;position:relative;overflow:hidden;"><div class="carousel-container"><div class="carousel-wrapper" style="position:relative;"/></div></div></div>');
      
      var $this = $(this);                                            // Storing "this" for later reference       
      var o = $.meta ? $.extend({}, opts, $this.data()) : opts;       // Support for the Metadata Plugin
      var $items = $this.children();                                  // Allows for any HTML setup. ul/li; div/div etc                              
      var $wrapper = $this.parent();                                  // div with class of carousel-wrapper
      var $container = $wrapper.parent();                             // div with class of carousel-container
      var $outerContainer = $container.parent();                      // div with class of carousel-outer-container
      var itemCount = $items.size();                                  // Number of items in the carousel
      var wrapperWidth = $wrapper.width();                            // Storing original width - pre .css() calls
      var start = o.start ? o.start : 1;                              // Element to start the carousel at (1 is first)
      var current = o.start - 1;                                      // Scale starts at 0; as this is eq based
      var animating = false;                                          // Stores animated state of carousel
      var maxSize = o.vertical ? height($items) : width($items);      // Max width or height of carousel item
      var actualVisible = Math.floor($outerContainer.width() / $items.width()); // Calculates the actual number of items visible in the carousel at a given time
      var offsetLeft = 0;
      var lcm = 0;
      var count = 0;
      

      if (o.loop == "circular") {
        
        lcm = LCM(o.scroll, itemCount);
        
        actualVisible = Math.ceil((($outerContainer.width() - $items.width()) / 2) / $items.width()) * 2 + 1;

        if (lcm >= itemCount) { count = Math.floor(lcm / itemCount); } 
        else {
          count = 1;
          lcm = Math.ceil(lcm / 2);
        }

        for (i = 0; i < count; i++) {
          $this.prepend($items.slice(-(itemCount)).clone().addClass("clone"))
               .append($items.slice(0, itemCount).clone().addClass("clone"));
        }
        
        
        start += count * itemCount;                                     // Increase start position
        count = lcm % itemCount;                                        // Re-use count to work out any left over clones that need adding.
        
        //console.log(lcm, itemCount, count);
        
        if (count > 0) {
          $this.prepend($items.slice(-(count)).clone().addClass("clone"))
               .append($items.slice(0, count).clone().addClass("clone")); 
          start += count;                                               // Increase start position
        }

        $items = $this.children();
        //itemCount = itemCount + lcm;
        
        
        start = start - o.start;
        //start = Math.floor(start) + (Math.floor(actualVisible / 2) - 1) - o.start;
      }
      
      
      $outerContainer.parent().append('<ul class="controls"><li class="prev"><a href="#prev">Previous</a></li><li class="next"><a href="#next">Next</a></li></ul>');

      offsetLeft = (maxSize * start);
      //if (o.align == "left") { offsetLeft -= (maxSize / 2); }
      
      //console.log(maxSize);
      //console.log(offsetLeft);
      
      /* Initial CSS setup */
      $this.css({           width   :     maxSize * $this.children().size() });        
      $outerContainer.css({ width   :     wrapperWidth+"px" });
      $container.css({      width   :     wrapperWidth+"px",  marginLeft  :   "-"+ offsetLeft +"px" });        
      $wrapper.css({        width   :     maxSize });
      $items.css({          width   :     $items.width() }).addClass('carousel-item');
      
      $this.data('current', 0);
      
      if (o.align == "center") $wrapper.css({ margin: "0 auto" });      
      
      $this.animate({   marginLeft  :     -(maxSize * (o.start - 1)) +"px" });
      
      $('.next a', $outerContainer.parent()).click(function(e){ e.preventDefault(); return go($this.data('current') + o.scroll); });
      $('.prev a', $outerContainer.parent()).click(function(e){ e.preventDefault(); return go($this.data('current') - o.scroll); });        

      
      function go(to) {
        
        if (!animating) {
          //console.log(to, itemCount, $this.data('current'));
          
          if (o.loop == "circular") {
            if (to <= -(itemCount)) {
              //console.log('here');
              //current = -(-(to) - itemCount);
              
              
              $this.data('current', 0 + (to % itemCount));
              /*
              if (current <= -(itemCount)) {
                //current = 0 + (to % itemCount);
                //current = ;
                current = to % -(itemCount);
              }*/
              
              $this.css("margin-left", -((o.scroll + $this.data('current')) * maxSize)+"px");
            } else if (to >= itemCount) {
              
              //console.log('here2');
              $this.data('current', 0 + (to % itemCount));

              
              $this.css('margin-left', -((to % itemCount) - o.scroll) * maxSize);
              //$this.css("margin-left", -((0 - o.scroll + current) * maxSize));
            } else {
              //console.log('here3');
              $this.data('current', to);
            }
            
            //console.log(current);
            
            var left = $items.eq($this.data('current')).offset().left - $items.eq($this.data('current')).prevAll(".clone").width();
            animating = true;
            
            
            $this.animate({
              marginLeft : -($this.data('current') * maxSize)
            }, o.speed, o.easing, function(){
              animating = false;
            });
          }

        }
        return false;
      }
    });
    
    
    function height($items) {
        var max = 0;
        $items.each(function(i){
            max = $(this).outerHeight() > max ? $(this).outerHeight() : max;
        }); 
        return max;
    }
    
    function width($items) {
        var max = 0, itemWidth;
        $items.each(function(i){
            $(this).css("float", "left");
            $(this).css('position', 'relative');
            itemWidth = $(this)[0].offsetWidth + parseInt($(this).css('margin-left')) + parseInt($(this).css('margin-right'));
            max = itemWidth > max ? itemWidth : max;

        });
        return max;
    }
    
    function LCM(x, y){
      var i = 1;
      while ((y * i) % x != 0) {
       i++;
       y = y * i;
      }
      return y;
    }
    
  };

  // default options
  $.fn.jqarousel.defaults = {
      controlsNext:   null,
      controlsPrev:   null,
      speed:          1000,
      easing:         null,
      vertical:       false,
      loop:           "circular",
      start:          1,
      scroll:         4,
      align:          "center"
  };

  })(jQuery);
