/**
 * SlideDown Menu
 */
var Menu = Class.create({
  /**
   * Menu
   *
   * @var Element
   */
  menu: null,

  /**
   * Save menu and bind events
   *
   * @param menu_id
   */
  initialize: function (menu_id)
  {
    this.menu = $(menu_id);
    this.bindEvents();
  },

  /**
   * Bind mouseover, mouseout events
   */
  bindEvents: function ()
  {
    var mouseover = this.mouseover.bind(this), mouseout = this.mouseout.bind(this), clearQueue = this.clearQueue.bind(this);

    var offset = this.menu.positionedOffset(), style = {
      'left': offset.left + 'px',
      'top': (offset.top + this.menu.getHeight()) + 'px'
    };

    this.menu.select('a ~ div').each(function (element)
    {
      element.previous('a').observe('mouseover', mouseover.curry(element)).observe('mouseout', mouseout.curry(element));
      element.setStyle(style).observe('mouseover', clearQueue.curry(element)).observe('mouseout', mouseout.curry(element));
    });
  },

  /**
   * Clear queued effects and show the menu
   *
   * @param div
   */
  mouseover: function (div)
  {
    this.clearQueue(div);

    if (div.visible())
      return;

    new Effect.SlideDown(div, {
      'beforeSetup': function () { div.previous('a').addClassName('hover') },
      'queue': {
        'scope': div.identify()
      },
      'delay': 0.5,
      'duration': 0.5
    });
  },

  /**
   * Close the menu
   *
   * @param div
   */
  mouseout: function (div)
  {
    new Effect.SlideUp(div, {
      'beforeSetup': function () { div.previous('a').removeClassName('hover') },
      'afterFinish': function () { div.setStyle({'height': 'auto'}) },
      'queue': {
        'scope': div.identify()
      },
      'delay': 1,
      'duration': 0.3
    });
  },

  /**
   * Clear queued effects
   *
   * @param div
   */
  clearQueue: function (div)
  {
    Effect.Queues.get(div.identify()).invoke('cancel');
  }
});
