Navigation = Class.create({
  element: null,
  animations: {},

  initialize: function(element) {
    this.element = $(element);
    if (!this.element) return;

    this.build();
    this.setupObservers();
  },

  build: function() {
    this.dimensions = this.element.getDimensions();
    this.subNavigatables = this.element.select('.with-subsections');
  },

  setupObservers: function() {
    document.observe('navigation:hide', function() {
      if (this.currentTopLevel) this.hideSubnavigation(this.currentTopLevel);
    }.bind(this));

    this.subNavigatables.each(function(topLevel) {
      topLevel.down('a').observe('click', function(e) {
        this.showSubnavigation(topLevel);
        e.stop();
      }.bind(this));
    }.bind(this));
  },

  showSubnavigation: function(topLevel) {
    if (this.animations[topLevel.id]) {
      if (this.animations[topLevel.id][0] == 'show') return;
      else this.animations[topLevel.id][1].cancel();
    }

    if (this.currentTopLevel && this.currentTopLevel != topLevel) {
      this.hideSubnavigation(this.currentTopLevel);
    }

    this.currentTopLevel = topLevel;
    var subnavigation = topLevel.down('.subnavigation');

    this.animations[topLevel.id] = [
      'show',
      new Effect.Morph(subnavigation, {
        style: {width: '200px'},
        transition: Effect.Transitions.easeFromTo,
        duration: .25,
        beforeStart: function() {
          subnavigation.setStyle({
            opacity: '1',
            display: 'block',
            width: '0px',
            top: (topLevel.positionedOffset().top - 13) + 'px'
          });
        }.bind(this)
      })
    ];
  },

  hideSubnavigation: function(topLevel) {
    if (this.animations[topLevel.id]) {
      if (this.animations[topLevel.id][0] == 'hide') return;
      else this.animations[topLevel.id][1].cancel();
    }

    var subnavigation = topLevel.down('.subnavigation');

    this.animations[topLevel.id] = [
      'hide',
      new Effect.Morph(subnavigation, {
        style: {width: '0px', opacity: '0'},
        duration: .50,
        transition: Effect.Transitions.easeFromTo,
        afterFinish: function() {
          this.animations[topLevel.id] = false;
        }.bind(this)
      })
    ];
  }
});
