// the Flickable mootools plugin is a creation of Jenna “Blueberry” Fox! Who
// releases it as public domain as of the 18th of August, 2007. More info and
// up to date downloads and demo's at: http://creativepony.com/journal/scripts/flickable/
// version: 1.3
var Flickable = new Class({
  options: {
    miniHeight: 50, // the amount of pixels from the bottom of each element to show when miniturized
    maxiHeight: null, // if null, figure to normal height of elements, otherwise, specify in pixels
    activeClass: 'active', // class to add to item which is active
    activationEvent: 'mousemove', // you can make this “click” if you like
    effect: { // options for effect used to animate movements, see Fx.Base in mootools docs
      wait: false,
      transition: Fx.Transitions.Bounce.easeOut
    }
  },
  elements: null,
  current: null,
  fx: null,
  
  
  initialize: function(element, options) {
    this.elements = $(element).getChildren();
    this.setOptions(options);
    this.fx = new Fx.Elements(this.elements, this.options.effect);
    this.current = this.elements[0];
    this.current.addClass(this.options.activeClass);
    this.elements.each(function (element, index) {
      element.setStyle('position', 'relative');
      element.setStyle('z-index', (this.elements.length - index) + 100);
      element.addEvent(this.options.activationEvent, this.flickToEventHandler.bindWithEvent(this, element));
    }.bind(this));
    this.update();
  },
  
  
  flickTo: function(element) {
    if (this.elements.indexOf(this.current) == -1)
      throw new Error("Tried to flick to something which isn't an element within the flickable element");
    this.current.removeClass(this.options.activeClass);
    this.current = $(element);
    this.current.addClass(this.options.activeClass);
    this.update();
  },
  
  // ensures mouse was over visible section of page dealie
  flickToEventHandler: function(event, attachedElement) {
    if (event.target == this.current) return;
    var coordinates = attachedElement.getCoordinates();
    var start = coordinates.top + (attachedElement.offsetHeight - this.options.miniHeight);
    var range = this.options.miniHeight;
    if (event.page.y >= start && event.page.y <= start + range) {
      this.flickTo(attachedElement);
    }
  },
  
  // updates view
  update: function() {
    //var foo = this.elements[0].getParent().getCoordinates().top;
    var changes = new Object();
    
    this.elements.each(function(element, index) {
      foo = element.offsetHeight - this.getVisibleHeight(element);
      changes[index.toString()] = {'margin-top': -foo};
    }.bind(this));
    
    this.fx.start(changes);
  },
  
  // returns the visible (eg, not always true) height of the element
  getVisibleHeight: function(element) {
    if (element == this.current) {
      return (this.options.maxiHeight || element.offsetHeight);
    } else {
      return this.options.miniHeight;
    }
  }
});

Flickable.implement(new Options);
