/*
 * All Javascript logic for the flyout menus.
 *
 * The code relies on the JQuery library to be also loaded.
 * 
 * Menus should have the following structure:
 * 
 * <div id="menuId">
 *      <ul>
 *           <li rel="childMenuId1">Menu 1</li>
 *           <li rel="childMenuId2">Menu 2</li>
 *           ...
 *           <li rel="childMenuIdm">Menu m</li>
 *      </ul> 
 * </div>
 * 
 * <div id="childMenuId1">
 *      ...child menu 1 items
 * </div>
 * <div id="childMenuId2">
 *      ...child menu 2 items
 * </div>
 * ...
 * <div id="childMenuIdm">
 *      ...child menu m items
 * </div>
 * 
 * 
 * When the user hovers over any menu item, its corresponding child menu will be display.  Moving the cursor out of 
 * the menu or child menu, a timer is set.  Once the timer expires, if the cursor is outside any menu or child menu, 
 * all the child menus will be hidden.
 */


/*
 * menuTimer - map containing the timers for the different menus.  When a timer event fires,
 *             the cursor position is checked.  If the cursor is outside any menu or child menu,
 *             all visible menus are hidden.
 * isInMenu - map containing the cursor trackers for the different menus.  When the cursor moves
 *            in a menu, the corresponding tracker is set to "true" for that menu.  When the cursor
 *            leaves the menu, the tracker is set to "false". 
 * menuMouseLeaveTimeout - number of milliseconds before closing all menus when the user moves the
 *                         cursor out of a menu or child menu.
 */
var menuTimer = new Object;
var isInMenu = new Object;
var menuMouseLeaveTimeout = 300;	// in milliseconds

/*
 * Sets all the events needed for a fully-functional menu.  See needed HTML structure above for more details.
 * 
 * menuId - the ID of the main <div> containing all the menu items.
 */
function initializeMenu(menuId) {
	// Initialize menu cursor tracker
	isInMenu[menuId] = false;
	
	hideAllMenus(menuId);
	
	// For each child menu item of the given menu...
	jQuery("#" + menuId + " li").each(function() {
		var menuItem = jQuery(this);
		// Set reference container ID of the current menu item
		menuItem.data("menuId", menuId);

		// Get the ID of the corresponding child menu of the current menu item
		var childMenuId = menuItem.attr("rel");
		if (childMenuId != "") {
			var childMenu = jQuery("#" + childMenuId);
			
			// Set the reference info of the child menu
			childMenu.data("parentMenuId", menuId);
			childMenu.data("parentMenu", menuItem);
			
			// Set the mouse events of the child menu
			childMenu.hover(
				function() {
					// Mouse enter handler for the child menu
					var menuId = jQuery(this).data("parentMenuId");
	
					resetMenuTimer(menuId);									// Turn off the timer for the menu container
					isInMenu[menuId] = true;								// Set the cursor tracker for the child menu's container
					jQuery(this).data("parentMenu").addClass("current");	// Set the class flag for the currently active menu  
				},			
				function() {
					// Mouse leave handler for the child menu
					var menuId = jQuery(this).data("parentMenuId");
	
					isInMenu[menuId] = false;								// Reset the cursor tracker for the child menu's container
					setMenuTimer(menuId);									// Turn on the timer for the menu container
				}
			);
			// end of childMenu.hover
		}
		// end of if (childMenuId != "")
		
		// Set the mouse events of the menu item
		menuItem.hover(
			function() {
				// Mouse enter handler for the menu item
				var menuItem = jQuery(this);
				var menuId = menuItem.data("menuId");

				resetMenuTimer(menuId);						// Turn off the timer for the menu container
				isInMenu[menuId] = true;					// Set the cursor tracker for the menu's container
				hideAllMenus(menuId);						// Hide all the visible child menus
				menuItem.addClass("current");				// Set the class flag for the currently active menu
				showMenu(jQuery(this).attr("rel"));			// Just display the currently active child menu
			},	
			function() {
				// Mouse leave handler for the menu item
				var menuId = jQuery(this).data("menuId");
	
				isInMenu[menuId] = false;					// Reset the cursor tracker for the menu's container
				setMenuTimer(menuId);						// Turn on the timer for the menu container
			}
		);
		// end of menuItem.hover
	});	
}
// end of function initializeMenu(menuId)


/*
 * Displays the child menu with the given ID.
 * 
 * childMenuId - the ID of the child menu that will be displayed.
 */
function showMenu(childMenuId) {
	if (childMenuId != "") {
		jQuery("#" + childMenuId).show();
	}
}
// end of function showMenu(childMenuId)


/*
 * Hides the child menu with the given ID.
 * 
 * childMenuId - the ID of the child menu that will be hidden.
 */
function hideMenu(childMenuId) {
	if (childMenuId != "") {
		jQuery("#" + childMenuId).hide();
	}
}
// end of function hideMenu(childMenuId)


/*
 * Hides all child menus of the given menu container.
 * 
 * menuId - the ID of the menu container of the child menus that will be hidden.
 */
function hideAllMenus(menuId) {
	jQuery("#" + menuId + " li").each(function() {
		var menuItem = jQuery(this);
		menuItem.removeClass("current");			// Clear the class flag for the current menu item
		hideMenu(menuItem.attr("rel"));				// Hide the current menu item's corresponding child menu
	});
}
// end of function hideAllMenus(menuId)


/*
 * Checks whether the mouse cursor is outside any menu or child menu.  If it is, all child menus of the given
 * menu container ID will be hidden.  The menu timer is also turned off.
 * 
 * menuId - the ID of the menu container of the child menus that will be hidden.
 */
function checkMenuHover(menuId) {
	resetMenuTimer(menuId);
	if (!isInMenu[menuId]) {
		isInMenu[menuId] = false;					// Reset the cursor tracker for the menu's container
		hideAllMenus(menuId);
	}
}
// end of function checkMenuHover(menuId)


/*
 * Turns on the timer of the given menu container.  When the timer expires, the mouse cursor position is
 * checked if it is over any menu or child menu item.
 * 
 * menuId - the ID of the menu container whose timer will be turned on.
 */
function setMenuTimer(menuId) {
	menuTimer[menuId] = setTimeout(function() {
		checkMenuHover(menuId);						// When the timer expires, check the cursor position
	}, menuMouseLeaveTimeout);
}
// end of function setMenuTimer(menuId)


/*
 * Turns off the timer of the given menu container.
 * 
 * menuId - the ID of the menu container whose timer will be turned off.
 */
function resetMenuTimer(menuId) {
	if (menuTimer[menuId]) {
		clearTimeout(menuTimer[menuId]);			// Turn off the menu timer
		menuTimer[menuId] = null;
	}
}
// end of function resetMenuTimer(menuId)

