/**
 * 
 * Element that slides up in increments rotating back to beginning when out of view 
 */

Ah.Rotator = new Class({
  
  Implements: [Options],
  
  el: null,
  sprite: null,
  periodical: null,
  el_height: null,
  sprite_height: null,
  item_height: null,
  increment: null,
  effect: null,
  no_of_items: 0,
  
  options: {
      items_in_view: 3,
      interval: 10000,
      duration: 1500
  },
  
  initialize: function(el, options){
      this.el = $(el);
      this.setOptions(options || {});
      this.sprite = el.getFirst();
      this.increment = this.normaliseItemHeights();
      this.sprite_height = this.sprite.getSize().y;
      // set el height to only show however many are in the options
      if(this.no_of_items < this.options.items_in_view){
          this.el_height = this.increment * this.no_of_items;
          this.el.setStyle('height', this.el_height);
      }else{
          this.el_height = this.increment * this.options.items_in_view;
          this.el.setStyle('height', this.el_height);
          this.effect = new Fx.Tween( this.sprite, 'top', {link: 'cancel', duration: this.options.duration} );
          this.el.addEvent( 'mouseenter', this.stop.bind(this));
          this.el.addEvent( 'mouseleave', this.queue.bind(this));
          this.start();
      }
  },
  
  // normalises the height of each item (or in the case of dt and dd - both together are treated as an item)
  // as the same as that of the largest item, so we can make the increment the same throughought 
  // and not have to worry about differences in text size settings would cause problems if a height was set purely in the stylesheet
  normaliseItemHeights: function(){
      var current_largest = 0;
      var current_largest_dd = 0;
      var children = this.sprite.getChildren();
      // find the largest heights
      children.each(function(child){
         var height = child.getSize().y;
         if(child.nodeName.toLowerCase() == 'dd' && height > current_largest_dd){
             current_largest_dd = height;
         }else if(child.nodeName.toLowerCase() != 'dd' &&height > current_largest){
             current_largest = height;
         }
         // keep track of the number of items
         if(child.nodeName.toLowerCase() != 'dd') this.no_of_items++;
      }, this);
      // normalise the heights
      children.each(function(child){
         var height = (child.nodeName.toLowerCase() == 'dd') ? current_largest_dd : current_largest;
         child.setStyle('height', height);
      }, this);
      // return the height the increment should be based on the normalised items
      if(current_largest_dd){
          return current_largest + current_largest_dd;
      }else{
          return current_largest;
      }
  },
  
  
  queue: function(){
      this.stop();
      this.periodical = this.start.delay(this.options.interval, this);
      return this;
  },
  
  start: function(){
      this.stop();
      this.periodical = this.moveUp.periodical(this.options.interval, this);
      return this;
  },
  
  stop: function(){
      $clear(this.periodical);
      return this;
  },
  
  checkIfOutOfView: function(){
      var current = this.sprite.getStyle('top').toInt();
      if((current + this.sprite_height) <= 0){
          this.stop();
          this.effect.start( this.el_height, 0).chain( this.queue.bind(this) );
      }
  },
  
  moveUp: function(){
      var current = this.sprite.getStyle('top').toInt();
      var to = current - this.increment;
      this.effect.start( to ).chain( this.checkIfOutOfView.bind(this) );
      return this;
  }
  
  
});