/**
  * Navigation Widget.
  * @TODO: Seperate the bits that are responsible for "building" the navigation structure into its
  * own class.
  */
  var Navigation = Class.create({

      /** The  structure of Navigation menus - see navigationconfig.js */
      config: null,

      /** the array of card names - see navigationconfig.js */
      cardNames: null,
      
      /** The element that holds the dhtml/visual representation of the navigation menus. An instance of PrimaryNav*/
      navStructure: null,

      /** the parent HTML element that holds the navigation structure*/
      __parent: null,

      /** the current index into __cardNames */
      __currentCardIndex: 0,
      
      /** the current index into __cardNames of the previous card */
      __previousCardIndex: 0,
     
      
      /** The ID of the DIV that holds the content*/
      contentHolder: 'mainContent',
      
      /** The ID of target browser groups ( primary, secondary, unsupported )*/
      __browserGroup: 'primary',
      
      /**
       * The initializer takes a configuration dictionary.
       * 
       * Sets up a listener for navigation changes. 
       * In subclasses, this must be overriden to do nothing !
       */
	   initialize: function(parentElement, browserGroup){
	       
	       
	      this.__parent = parentElement;
	      this.__browserGroup = browserGroup;
	      
	       
	      this.config = NavigationConfig;
	      this.cardNames = NavigationConfigNames;
	
      },
       

      /**
       * Builds the navigational structure from the config file
       */
      build: function(){
          this.navStructure = new PrimaryNav(this.__parent, this.config);
          this.navStructure.build();
          
          // After building the navstructure, it will have an array property called cards. 
          // Those are basically empty DIVs that will hold the content that appears in the main
          // display.
          //
          // We are just creating and inserting them. Note that the won't have any content in them yet.
          // The content will be loaded ajaxly by this.contentLoader.
          var holder = $(this.contentHolder);

          for (var i=0; i<this.navStructure.cards.length; i++){
             holder.insert(this.navStructure.cards[i]);
          }
      }      
  });

  Navigation.findCard = function( parent, cardName ) {
      var parts = cardName.split('/');
      var target = $(parent).down('.'+ parts[0]);
      if (target && parts.length > 1){
          target = target.down('.'+parts[1]);
      }
      return target;
  }

  
  /**
  * Renders the primary navigation links.
  */
  var PrimaryNav = Class.create({
  	
      config: null,
      /** The element that holds the dhtml/visual representation of this navigation structure*/
      element: null,
      /** This is where we put the subnavigation links*/
      subNavElement: null,
      /** An array of elements. This is what goes inside the navigation strip.*/
      cards: [],
      
      /** the parent HTML element that holds the navigation structure*/
      __parent: null,
      /** Where this element falls in the nav hierarchy*/
      // __order: {},
      
      
      /**
       * The initializer takes a configuration dictionary.
       */
      initialize: function(parentElement, config){
          if (config){
              this.config = config;   
          } else { 
              // If no config was supplied, use the default.
              this.config = NavigationConfig;
          }
          this.__parent = parentElement;
      },
      
      /**
       * Builds the navigational structure from the config file
       */
      build: function(){
          this._buildElement();

          for (var i=0; i<this.config.order.length; i++){
              key = this.config.order[i];
              this.element.insert(this._makeRenderer(key));

              // this.__order[key] = i;

              if (this.config[key].sub){
                  var className = key;
                  var subNav = new SubNav(this.subNavElement, this.config[key].sub);
                  subNav.prefix = className;
                  subNav.build();
                  // Give the subnav a piculiar class name, so we can find it
                  // and select it later.
                  subNav.element.addClassName(className);
                  // hide all subnavs initially
                  //subNav.element.hide();
                  //this.cards.push(subNav.makeCards());
              }
          }
          if (this.subNavElement){
        	  // Insert the subnav
        	  this.element.insert(this.subNavElement);
          
          	// Mark the last element
          	this.subNavElement.select('.subNavElement').pop().addClassName('last-child');
          }
          //insert into parent
          this.__parent.insert(this.element);
      },
      
      /**
     * @protected
     * 
     * Makes a renderer for the top level navigation items.
     */
      _makeRenderer: function(configKey){
      	var firstSubKey = this.config[key].sub.order[0];
      	return new Element('a', {href: '/'+configKey+'/'+firstSubKey, 'class': configKey+" primary"});
      },
      
      /**
     * @protected
     * Encapsulates the building of the dhtml element that holds this thing.
     */
      _buildElement: function(){
          this.element = new Element('div', {'class': 'navElement'});
          this.subNavElement = new Element('div', {'class': 'subNavHolder'});
      }    
  });
  
  /**
  * @private
  * 
  * A subclass of PrimaryNav that renders links differently
  */
  var SubNav = Class.create(PrimaryNav, {
      /** We use this prefix to figure out the hash links of these navigation buttons*/
      prefix: '',
      
      /**
      * @override
      */
      listenForNavChanges: function(){
       // do nothing. Only the main display should listen for nav changes.     
      },
      
      /**
      * @override
      */
      _buildElement: function(){
          this.element = new Element('div', {'class': 'subNavElement'})
      },
      
      /**
     * @override
     */
      _makeRenderer: function(configKey){
          var link = '/'+this.prefix+'/'+configKey;
          // Does this entry have a URL property?
          if (typeof(this.config[configKey]["url"]) != "undefined"){
              link = this.config[configKey]["url"];
              return new Element('a', {href: link, 'class': configKey, 'target': '_blank'});
          }
          return new Element('a', {href: link, 'class': configKey});//.update(this.config[configKey].label);
      },
      
      /**
     * Produces the actual cards
     * The cards will be siblings in a div that has a classname equivalent to the main nav key.
     */
      makeCards: function(){
          var cardCategory = new Element('div', {'class': 'cardCategory ' + this.prefix});
          var background = new Element('div', {'class': 'categoryBackground ' + this.prefix, 
             'id': 'card_' + this.prefix});
          cardCategory.insert(background);
		  for (var i=0; i<this.config.order.length; i++){
		      var key = this.config.order[i];
		      var card = new Element('div', {'class': 'card ' + key, 'id': 'card_' + this.prefix + '/' + key});
		      cardCategory.insert(card);
		  }
		  return cardCategory;
      }
  });
  
/**
 * Support code for the show/hide navigation
 *
 */
var options = {enterDelay: 1, leaveDelay: 1};
var showNav = function(){$('topNav').down('.subNavHolder').show();};
var hideNav = function(){$('topNav').down('.subNavHolder').hide();};
function initNavigation(){
    $('topNav').down('.subNavHolder').hide();      
    $('topNav').down('.navElement').hover(showNav, hideNav, options);
    // Hook up the hover effect to the allurenthome overlay as well. Note that we're supressing the mouse_out handler
    // because it creates a race condition with the hover effect on the topNav.
    $('allurenthome').hover(showNav, null, options);
}
