(function($) {
  
  $.shingles = {
    defaults: {
      delay:        3000,
      fxSpeed:      'slow',
      hoverPause:   true,
      direction:    'up'
    }
  }; 
  
  $.fn.shingles = function(settings){
    $(this).each(
      function(){
        var self = this;

        // combine default options with settings
        self.options = $.extend({}, $.shingles.defaults, settings);
        
        $(self).addClass('jqueryshingles');
        
        if($('>li:eq(0)>:eq(0)', self).is('.handle') ){
          self.options.direction = 'down';
        }
        
        //$('li',self).eq(i).css('top', 0);
        
        $('>li',self).each(
          function() {
            var i = $('>li',self).index(this);
            var size = $('>li',self).size();
            var max = size - 1;
              
            if(self.options.direction == 'up'){
              $(this).css('z-index', size - i);
              if(i > 0){
                // low is very dependent on the previous item
                var prev = $('>li',self).eq(i-1)[0];
                this.low = parseInt($(prev).css('top')) + $(prev).outerHeight() - $(this).outerHeight() + $('.handle',this).outerHeight();
              }else{
                // low is always 0 for the top element.
                this.low = 0;
              }
              // high is basically the low value plus the height of current minus the handle
              this.high = this.low - $(this).outerHeight() + $('.handle',this).outerHeight();
              $(this).css('top', this.low);
            }else{
              $(this).css('z-index', i);
              if(i > 0){
                // low is very dependent on the previous item
                var prev = $('>li',self).eq(i-1)[0];
//                this.low = parseInt($(prev).css('top')) + $(prev).height();
                // high is basically the low value plus the height of current minus the handle
//                this.high = this.low - $(this).height() + $('.handle',prev).height();
                this.high = prev.high + $('.handle', prev).outerHeight();
                this.low = prev.high + $(prev).outerHeight();
              }else{
                // low is always 0 for the top element.
                this.low = 0;
                this.high = 0;
              }
              $(this).css('top', this.high);
            }      
            
          }
        );
        
        $(self).css('height', $('>li:last',self).outerHeight() + parseInt($('>li:last',self).css('top')) + 'px');
        
        position(0, self);
        
        if(jQuery.fn.hoverIntent){
          $('.handle', self).hoverIntent(
            function(){
              slide($('>li',self).index($(this).parent()[0]), self);
            }, 
            function(){}
          );
        }else{        
          $('.handle', self).hover(
            function(){
              slide($('>li',self).index($(this).parent()[0]), self);
            }, 
            function(){}
          );
        }

      }
    );
  }
  
  function position(current, self){
    $('.handle.active',self).removeClass('active');
    $('li>.handle',self).eq(current).addClass('active');
    
    if(self.options.direction == 'up'){
      $('>li',self).not(':last').each(
        function(){
          var i = $('>li',self).index(this);
          $(this).css({top: ((i >= current) ? this.low : this.high) });
        }
      );    
    }else{
      $('>li',self).not(':first').each(
        function(){
          var i = $('>li',self).index(this);
          $(this).css({ top: ((i > current) ? this.low : this.high) });
        }
      );    
    }    
  }
  
  function slide(current, self){
    $('.handle.active',self).removeClass('active');
    $('li>.handle',self).eq(current).addClass('active');
    
    $('>li',self).each(
      function(){
        var i = $('>li',self).index(this);
        var next = 0;
        if(self.options.direction == 'up'){
          next = (i >= current) ? this.low: this.high;
        }else{
          next = (i > current) ? this.low: this.high;
        }
        if(parseInt($(this).css('top')) != next){
          $(this).animate({top: next}, 'slow');
        }
      }
    );

/*    
    if(self.options.direction == 'up'){
      $('>li',self).not(':last').each(
        function(){
          var i = $('>li',self).index(this);
          $(this).animate(
            { top: ((i >= current) ? this.low : this.high) },
            'slow'
          );
        }
      );    
    }else{
      $('>li',self).not(':first').each(
        function(){
          var i = $('>li',self).index(this);
          $(this).animate(
            { top: ((i > current) ? this.low : this.high) },
            'slow'
          );
        }
      );    
    }    
    */
  }
    
})(jQuery);

$(document).ready(
  function(){
    $('ul.shingles').shingles();
  }
);