/*
Sony Style Global Navigation
AUTHOR: Jonathan Cheung
===================================================================================================================================================================
// !  * Menu Class (Prototype) for the dropDownMenu

	Variables:
	type: String, type of the node
	closeDelayTimer: Number, referent to the timer
	quickCollapse: Boolean, skip close animation or not
	closeDelayTime: Number, in milliseconds

	Functions:
	initialize: constructor
	config: The function we modify to set the parameters
// ===================================================================================================================================================================
*/

var Menu = Class.create();
Menu.prototype = {

	/*
	Class Constructor
	idORelement: String|HTMLElement, root Node of the menu (ul)
	name: String, name of the variable that stores the whole Menu class
	*/
	initialize: function(idORelement, name, _activeClassName,_plusClassName, _highlightClassName) {

		this.name = name;
		//Set type for this node
		this.type = "menu";
		//Initialize the timer
		this.closeDelayTimer = null;

		this.closingMenuItem = null;
		//Sets up the menu with custom properties
		this.config();

		this.activeClassName = _activeClassName
		this.plusClassName = _plusClassName
		this.highlightClassName = _highlightClassName

		/* We initialize the Menu container class by the Div ID */
		this.rootContainer = new MenuContainer(idORelement, this);
	},

	config: function() {
	  this.closeDelayTime = 100;
	}

}

/* ===================================================================================================================================================================
// !  * MenuContainer Class (Prototype) for the dropDownMenu

	Variables:
	type: String, type of the node
	menuItems:Array, stores references to each child items
	element: Prototype Object, the object for prototype
	parent: HTMLElement, Reference to the parent element
	parentMenu: HTMLElement, Reference to parent element
	root: HTMLElement, Reference to root UL
	id: element id
	isOpen: stores the open status
	rollOverElement: Store the element for hover and roll off state

	Functions:
	initialize: constructor
	init: Initialize the current element
	open: open this tab
	close: close this tab
	closeAll: closes the subNav list
	setupRollOverElement: Function to determine the rollover element to add/remove active state.

// ===================================================================================================================================================================
*/
var MenuContainer = Class.create();
MenuContainer.prototype = {
	initialize: function(idORelement, parent) {
		this.type = "menuContainer";
  		this.menuItems = [];
  		/* Initializing the menu using the init() function */

		this.init(idORelement, parent);

	},

	init: function(idORelement, parent) {
		var menuContainer = this;
	  this.element = $(idORelement);
	  this.parent = parent;
	  // If this is a menuContainer (extended class) we set the parentMenu to parent.parent/null or or parent
	  this.parentMenu = (this.type == "menuContainer") ? ((parent) ? parent.parent : null) : parent;
	  // Set the root variable to the menu
	  this.root = parent instanceof Menu ? parent : parent.root;

	  this.id = this.element.id;

	  this.setupRollOverElement();

	  if (this.type == "menuContainer") {

	  	/* Setup the 3 types of menuTypes nodes hotizontal,dropdown or seconddropdown*/
		if (Element.select(this.element," span").length>0) {this.menuType = "horizontal";}
		else
		if (Element.select(this.element," ul").length>0) {this.menuType = "dropdown";}
		else this.menuType = "seconddropdown";

		//If this is a seconddropdown or dropdown
	    if (this.menuType == "seconddropdown" || this.menuType == "dropdown") {
	      this.isOpen = false;
	    } else {
	      this.isOpen = true;
	    }
	  } else {
	    this.isOpen = this.parentMenu.isOpen;
	  }

	  var childNodes = this.element.childNodes;
	  //If there isn't any childNodes we end here.
	  if (childNodes == null) return;

	  //Otherwise we go through the childnodes and set them up as menuItem or menuContainer

	  for (var i = 0; i < childNodes.length; i++) {
	    var node = childNodes[i];
	    if (node.nodeType == 1) {
	      if (this.type == "menuContainer") {
	        if (node.tagName.toLowerCase() == "li") {
	          this.menuItems.push(new MenuItem(node, this));
	        }
	      } else {
	        if (node.tagName.toLowerCase() == "ul") {
	          // "subMenu" will be used for storing references to sub menus so we can trigger the the functions open,close...etc.
	          this.subMenu = new MenuContainer(node, this);
	        }
	      }
	    }
	  }

	},

	setupRollOverElement: function(){
		// This checks to see if SPAN tag is in the LI, if so it is the top menu element then we attach the mouse event listeners to the appropriate tags
		/* First find the element we want to add the listner
		*/
		this.rollOverElement = (Element.select(this.element," span").length>0)?
							this.element.getElementsByTagName('span')[0]:
							this.element;
	},

	open: function() {
	  if (this.root.closeDelayTimer) window.clearTimeout(this.root.closeDelayTimer);
	  this.parentMenu.closeAll(this);
	  this.isOpen = true;
	  if(isIE6()) hideSelects();
	  Element.setStyle(this.element,{visibility: "visible"});
	},

	close: function() {
		Element.setStyle(this.element,{visibility: "hidden"});
		this.dehighlight()
		this.isOpen = false;
		this.closeAll();
		if(isIE6()) showSelects();
		//Get the parent of this open item and de-highlight
	},

	closeAll: function(trigger) {
		for (var i = 0; i < this.menuItems.length; ++i) {
			this.menuItems[i].closeItem(trigger);
		}
		
	},

	closeByTimer: function (){
		this.close();
		//this.parentMenu.closeAll();

		this.parent.rollOverElement.removeClassName(this.root.activeClassName);
	},


    highlight: function(){
        if(this.parent.rollOverElement)
        	this.parent.rollOverElement.addClassName(this.root.highlightClassName);

    },
    dehighlight: function(){
    	 if (this.parent.rollOverElement)
    	 	if (this.parent.rollOverElement.hasClassName(this.root.highlightClassName))
       			this.parent.rollOverElement.removeClassName(this.root.highlightClassName);
    }

}

/* ===================================================================================================================================================================
// !  * MenuItem Class (Prototype) for the dropDownMenu

	Variables:
	inherits from MenuContainer and Menu
	subMenu: Stores the reference to the sub menu.

	Functions:
	initialize: constructor and initializes the element.
	openItem: open this menuItem
	closeItem: close this menuItem

// ===================================================================================================================================================================
*/

var MenuItem = Class.create();

Object.extend(Object.extend(MenuItem.prototype, MenuContainer.prototype), {
	// Constructor
	initialize: function(idORelement, parent) {
		var menuItem = this;
		this.type = "menuItem";
	//	this.subMenu;
		this.init(idORelement, parent);
		
		Event.observe(this.element, "mouseover",this.openItem.bind(this))
		
		/* If this is a dropdown menu item */
			if (this.parent.menuType == "dropdown"){
			  Event.observe(this.rollOverElement.childElements()[0], "mouseover", function(e){
			  		menuItem.rollOverElement.removeClassName(menuItem.root.highlightClassName);
			  });
			}
			Event.observe(this.rollOverElement, "mouseover", function (e){
				this.addClassName(menuItem.root.activeClassName);
				menuItem.parentMenu.highlight();
			});
			if (this.subMenu == undefined){
				Event.observe(this.rollOverElement, "mouseout", function (e){
						this.removeClassName(menuItem.root.activeClassName);
				});
			}



		/*  If there's a submenu we will set a timer to close the submenu. */
		if (this.subMenu) {
			 Event.observe(this.element, "mouseout", function (){
			  if (menuItem.root.closeDelayTimer) window.clearTimeout(menuItem.root.closeDelayTimer);
			  //Stores this Menu item's parent to the root.
			  eval(menuItem.root.name + ".closingMenuItem = menuItem");
			  //Delay timer will be set to trigger the close () function for the submenu
			  menuItem.root.closeDelayTimer =
		  			window.setTimeout(menuItem.root.name + ".closingMenuItem.subMenu.closeByTimer()", menuItem.root.closeDelayTime);
			})
		}
	},
	openItem: function() {
		if (this.subMenu) {
				this.subMenu.open();
			//	This will turn on the parent horizontal menu hightlight
				this.rollOverElement.addClassName(this.root.activeClassName);
				this.rollOverElement.addClassName(this.root.plusClassName);
		}else{
			 	this.parentMenu.closeAll();
				this.rollOverElement.addClassName(this.root.activeClassName);
		}
	  
	},

	closeItem: function(trigger) {
	  this.isOpen = false;

	    if (this.subMenu && this.subMenu != trigger){
	     this.subMenu.close();
		}
		  if (this.rollOverElement.hasClassName(this.root.activeClassName))
		     this.rollOverElement.removeClassName(this.root.activeClassName);

	}
});

// Shows/unhides all of the SELECT boxes on a page
function showSelects() {
    $(document.body).select("select").each(function(select) {
        select.show();
    });
}

// Hides all of the SELECT boxes on a page
function hideSelects() {
    $(document.body).select("select").each(function(select) {
        select.hide();
    });
}

// Returns if the browser is IE 6
function isIE6() {
    return Prototype.Browser.IE && navigator.appVersion.indexOf("MSIE 6.0") != -1;
}