Navigation = Class.create({
  element: null,

  initialize: function(element) {
    this.element = $(element);
    if (!this.element) return;

    this.build();
    this.setupObservers();
  },

  build: function() {
    this._container = this.element.up('#navigation_container');
    this._utility = this._container.down('#utility');
    this._subnavigation = this.element.up('#control').down('#subnavigation');

    if (!this._activeMarker) {
      this._activeMarker = new Element('div', {'id': 'navigation_active_marker'});
      this._container.insert({top: this._activeMarker});
    }
    this.moveActiveMarker(this.element.down('li.active'), true);
  },

  setupObservers: function() {
    Event.observe(document, 'interface:transition', function(event) {
      var options = event.memo || {};
      if (options['containerElement'] != this.element) {
        //this.deselectActive();
        this.hideSubnavigation();
      }
    }.bind(this));

    this.element.select('a').each(function(anchor) {
      anchor.observe('click', function(event) {
        event.stop();
        anchor.blur();
        if (!document._transitioning) {
          var li = anchor.up('li');
          if (li.hasClassName('has-subnavigation')) {
            this.showSubnavigationFor(li);
          } else {
            if (!li.hasClassName('active')) this.moveActiveMarker(li);
            this.hideSubnavigation();
            Event.fire(document, 'interface:transition', {containerElement: this.element, url: anchor.href});
          }
        }
      }.bind(this));
    }.bind(this));

    this._container.down('li#dealer_locator a').observe('click', function(event) {
      event.stop();
      var element = Event.element(event);
      //$('zipcode').focus();
      this.showSubnavigationFor(element.up('li'));
    }.bind(this));

    this._container.down('li#music_player a').observe('click', function(event) {
      event.stop();
      var element = Event.element(event);
      mainInterface.player.mp3player.swf.setStyle({top: 0});
      this.showSubnavigationFor(element.up('li'));
    }.bind(this));

    this._subnavigation.select('.item a').each(function(anchor) {
      anchor.observe('click', function(event) {
        event.stop();
        anchor.blur();
        if (anchor.hasClassName('with-items')) {
          this.loadItems(anchor.up('.subnavigation-list').down('.items'), anchor);
        } else {
          this.toggleSubnavigationItem(anchor)
        }
      }.bind(this));
    }.bind(this));

    this._subnavigation.down('a.close-button').observe('click', function(event) {
      event.stop();
      this.hideSubnavigation();
    }.bind(this));
  },

  loadItems: function(element, anchor) {
    new Effect.BlindUp(element, {
      queue: {position: 'end', scope: 'load_items', limit: 1},
      duration: .25,
      transition: Effect.Transitions.easeTo,
      afterFinish: function() {
        anchor.siblings().each(function(sibling) { sibling.removeClassName('active'); });
        anchor.addClassName('active');
        element.innerHTML = '<div class="clear"><br clear="both"/></div>';
        new Ajax.Request(anchor.href, {
          method: 'get',
          onSuccess: function(transport) {
            element.innerHTML = transport.responseText;
            this.makeItemsUsable(element);
            new Effect.BlindDown(element, {
              queue: {position: 'end', scope: 'load_items', limit: 1},
              duration: .25,
              transition: Effect.Transitions.easeFrom
            });
          }.bind(this)
        });
      }.bind(this)
    });
  },

  makeItemsUsable: function(element) {
    element.select('.subitem').each(function(item) {
      var tip = item.down('.tip');
      item.down('img').title = '';
      var anchor = item.down('a');
      anchor.observe('click', function(event) {
        event.stop();
        anchor.blur();
        this.moveActiveMarker(this._lastHighlighted);
        this.hideSubnavigation();
        Event.fire(document, 'interface:transition', {containerElement: this.element, url: anchor.href});
      }.bind(this));
      item.observe('mousemove', function(event) {
        tip.setStyle({position: 'absolute', display: 'block', top: (event.clientY - tip.getHeight() - 4) + 'px', left: event.clientX + 'px', 'z-index': 11});
      });
      item.observe('mouseout', function(event) {
        tip.setStyle({display: 'none'});
      });
    }.bind(this));
  },

  deselectActive: function() {
    if (!this._lastActive) return;

    this._lastActive.removeClassName('active');
    this._activeMarker.setStyle({display: 'none', left: '0'});
    this._lastActive = null;
  },

  selectFromPath: function(path) {
    path = Array.from($H(path));
    if (path[path.length - 2]) {
      var navItem = this.element.down('#nav_' + path[path.length - 2][0]);
      if (navItem) {
        if (this._lastActive != navItem) this.moveActiveMarker(navItem);
      } else {
        this.deselectActive();
      }
    } else {
      this.deselectActive();
    }
  },

  moveActiveMarker: function(element) {
    if (!element) return;
    instant = (this._lastActive) ? false : true;

    if (this._moveActiveMarkerAnimation) this._moveActiveMarkerAnimation.cancel();
    this._activeMarker.style.backgroundPosition = '-' + Math.floor((Math.random(1) * 100)) + 'px center';
    this._moveActiveMarkerAnimation = new Effect.Morph(this._activeMarker, {
      style: {left: (element.positionedOffset().left - 1) + 'px', width: (element.getWidth() + 2) + 'px'},
      transition: Effect.Transitions.swingFrom, //.easeFrom,
      duration: instant ? 0 : .25,
      beforeStart: function() {
        if (this._lastActive) this._lastActive.removeClassName('active');
        element.addClassName('active');
        this._lastActive = element;
      }.bind(this),
      afterFinish: function() {
        this._activeMarker.show();
      }.bind(this)
    });
  },

  showSubnavigationFor: function(element) {
    if (this._lastHighlighted) {
      if (this._lastHighlighted == element) return;
      this._lastHighlighted.removeClassName('highlighted');
    }

    element.addClassName('highlighted');
    this._lastHighlighted = element;

    mainInterface.mask();

    this._showSubnavigationAnimation = new Effect.Morph(this._subnavigation, {
      style: {top: '0px'},
      transition: Effect.Transitions.easeFromTo,
      duration: .5,
      beforeStart: function() {
        if (this._activeSubnavigation) {
          if (this._activeSubnavigation.hasClassName('placed')) {
            this._activeSubnavigation.setStyle({visibility: 'hidden', height: '1px'});
          } else {
            this._activeSubnavigation.hide();
          }
        }
        this._activeSubnavigation = this._subnavigation.down('#sub' + element.id);
        this._activeSubnavigation.setStyle({display: 'block', visibility: 'visible', height: 'auto'});
        this._subnavigation.setStyle({top: -this._subnavigation.getHeight() + 'px'})
      }.bind(this)
    });
  },

  toggleSubnavigationItem: function(element) {
    var siblings = element.nextSiblings();
    if (!siblings || !siblings[0].hasClassName('item')) return;

    var subitem = siblings[0];
    if (subitem.visible()) {
      this.hideSubnavigationItem(subitem, element);
    } else {
      this.showSubnavigationItem(subitem, element);
    }
  },

  showSubnavigationItem: function(element, anchor) {
    if (this._subitemShowAnimation) this._subitemShowAnimation.cancel();
    var sizer = element.down('.sizer');
    element.show(); var width = sizer.getWidth(); element.hide();
    element.setStyle({width: '0px', overflow: 'hidden', display: 'block'});

    if (this._subitemShowing && this._subitemShowing[0] != element) this.hideSubnavigationItem(this._subitemShowing[0], this._subitemShowing[1]);
    element.siblings().each(function(sibling) {
      if (sibling != element) sibling.addClassName('dim');
    });
    

    anchor.addClassName('active');
    this._subitemShowAnimation = new Effect.Morph(element, {
      style: {width: width + 'px'},
      transition: Effect.Transitions.swingTo,
      duration: .50,
      afterFinish: function() {
        this._subitemShowing = [element, anchor];
      }.bind(this)
    });
  },

  hideSubnavigationItem: function(element, anchor) {
    if (this._subitemHideAnimation) this._subitemHideAnimation.cancel();
    anchor.removeClassName('active');
    this._subitemHideAnimation = new Effect.Morph(element, {
      style: {width: '0px'},
      transition: Effect.Transitions.easeFromTo,
      duration: .25,
      afterFinish: function() {
        element.setStyle({width: 'auto', display: 'none'});
        element.select('a').each(function(child) { child.removeClassName('active'); });
        this._subitemShowing = [null, null];
      }
    });
  },

  hideSubnavigation: function() {
    mainInterface.unMask();

    if (this._lastHighlighted) this._lastHighlighted.removeClassName('highlighted');
    this._lastHighlighted = null;

    this._hideSubnavigationAnimation = new Effect.Morph(this._subnavigation, {
      style: {top: -this._subnavigation.getHeight() + 'px'},
      transition: Effect.Transitions.easeFromTo,
      duration: .5,
      afterFinish: function() {
        this._subnavigation.setStyle({top: '-10000px'});
        if (this._activeSubnavigation) {
          if (this._activeSubnavigation.hasClassName('placed')) {
            this._activeSubnavigation.setStyle({visibility: 'hidden', height: '1px'});
          } else {
            this._activeSubnavigation.hide();
          }
        }
        this._activeSubnavigation = null;
      }.bind(this)
    });
  }
});
