/**
 * SP Menu 2.0
 * jQuery Plugin
 * 
 * This plugin allows you (the developer) to easily implement a dropdown menu.  It does
 * nothing more than handle the showing and hiding of the various drop-down menus - the
 * styling of said menus is left completely up to you.
 * 
 * The HTML should resemble something like:
 * <ul id="menuList">
 *    <li>
 *       <a href="">Menu A</a>
 *       <ul class="submenu level1">
 *       	<li>A.1</li>
 *       	<li>A.2</li>
 *       	<li>A.3</li>
 *       </ul>
 *    <li>
 *       <a href="">Menu B</a>
 *       <ul class="submenu level1">
 *       	<li>B.1</li>
 *       	<li>B.2</li>
 *       </ul>
 *    </li>
 * </ul>
 * 
 * At the very least, the CSS should resemble:
 * #menuList { list-style:none; }
 *    #menuList li { float:left; }
 *    #menuList li.hover { background:orange; }
 *    
 *    .submenu { position:absolute; list-style:none; }
 *    
 *    .submenu.level1 { left:100px; top:10px; }
 *       .submenu.level1 li.hover { background:blue; }
 * 
 * The above CSS assumes the main menu is horizontal, and will position each submenu
 * 100px from the left and 10px from the top of its parent <li>
 * 
 * Note: When submenus are displayed, they are taken out of the normal flow of the document
 * and positioned within a helper <div> at the root level that is the same size and position
 * of the <li> that the submenu is coming from.  Because of this, you cannot style menus in
 * the CSS with "#menuList .submenu.level1"
 * 
 * -----
 * Usage
 * -----
 * $('menuList').synergymenu(settings);
 * 
 * --------
 * Settings
 * --------
 * dropDownMenuTimeout		Milliseconds to wait when the mouse moves off the menu
 * 							before closing the menu
 * 							Default 300
 */
jQuery.fn.synergymenu = function(settings) {
	// Define default settings
	settings = jQuery.extend({dropDownMenuTimeout: 300}, settings);
	
	return this.each(function() {
		var el = jQuery(this);
		synergymenu_internal.setup(el, settings, el);
	});
};

var synergymenu_internal = {
	setup:function(el, settings, root) {
		el.data('synergymenu_openmenu', null);
		el.data('synergymenu_root', root);
		
		root.data('synergymenu_timeout', settings.dropDownMenuTimeout);
		root.data('synergymenu_timerid', 0);
		
		// Find all list items with submenus
		el.find('> li').each(function() {
			// Assign pointers
			var li = jQuery(this);
			var ul = li.find('ul:first');
			
			li.data('synergymenu_parent', el);
			// Listen for hover
			li.hover(
				function(ev) { synergymenu_internal.show(li); }
				,
				(el==root ? function(ev) { synergymenu_internal.hide(li); } : function(){})
				);
			
			// Search the <ul> for further submenus
			if (ul.length  &&  !ul.hasClass('nodropdown')) {
				li.data('synergymenu_submenu', ul);
				synergymenu_internal.setup(ul, settings, root);
			}
		});
	},
	
	show:function(li) {
		var el = li.data('synergymenu_parent');
		var root = el.data('synergymenu_root');
		var ul = li.find('> ul');
		
		// If parent has timer running, clear it
		clearTimeout(root.data('synergymenu_timerid'));
		
		// If this is the open menu, don't do anything
		if (el.data('synergymenu_openmenu') == li) return;
		
		// If another menu is open, close it
		if (el.data('synergymenu_openmenu')) synergymenu_internal.hideFinal(el);
		
		// Set this menu as the active menu for this level
		el.data('synergymenu_openmenu', li);
		
		// Show the submenu
		ul.css('visibility', 'visible');
		
		// Set <li> as hover
		var czindex = parseInt(el.css('z-index')) || 0;
		if (ul.length) li.addClass('sticky').css('z-index', (czindex + 1000));
		li.addClass('hover');
		
	},
	
	hide:function(li) {
		var el = li.data('synergymenu_parent');
		var root = el.data('synergymenu_root');
		
		root.data('synergymenu_timerid', setTimeout(function() {
			synergymenu_internal.hideFinal(el);
		}, root.data('synergymenu_timeout')));
	},
	
	hideFinal:function(el) {
		var li = el.data('synergymenu_openmenu');
		var ul = li.find('> ul');
		
		el.data('synergymenu_openmenu', null);
		
		// Hide all submenu items within this li's submenu
		if (ul.data('synergymenu_openmenu')) synergymenu_internal.hideFinal(ul);
		
		// Hide the submenu
		ul.css('visibility','hidden');
		
		// Remove the "hover" class
		li.removeClass('sticky').removeClass('hover').css('z-index', '');
	}
};
