/*
	jQuery Pull-down Menu Plugin.
   
	A simple reusable pull-down (or flyout) for use in a menu structure.
   
	Usage:
		Call the pulldown function on the UL element that you want to use as
		the menu root.
	   
		$("#mySelect").pulldown();
	   
		The menu structure is assumed to be a nested set of elements with one
		"hider" as the descendent of each "handle". A simple nested list is the
		easiest example and will work with no further configuration.
	   
		<ul id="mySelect">
			<li>
				<a>Child 1</a>
			   
				<ul>
					<li><a>Sub Category</a></li>
				</ul>
			</li>
		</ul>
		
		In this example the ULs (except the outermost) would be the hiders and
		the LIs are the handles.
		
	Options:
		closeDelay
			Time taken for menu to close after the mouse leaves (ms).
			
		clickAway
			Enables the ability to click outside of the menu to close it
			instantly.
			
		handleSelector
			The handles which when hovered over will open up an "hider".
			
		hiderSelector
			The elements that get hidden and shown as the mouse moves over the
			"handles".
		
		activeClass
			CSS class to give to active elements. Normally just "active".
			
		siblingDist
			Similar to using z-index in CSS, in order to determine the depth
			of each handle there must be some point in the DOM where there are
			sibling elements with just one handle in each.
			
			Usually this is the handles themselves. If not, siblingDist is the
			height to assend the tree to find such elements.
*/

(function($) {
   
	$.fn.pulldown = function(options) {
		var opts = $.extend({}, $.fn.pulldown.defaults, options);
	   
		function closeTree(root) {
			$(opts.handleSelector, root).removeClass(opts.activeClass);
			$(root).removeClass(opts.activeClass);
			$(opts.hiderSelector, root).hide();
		}
	   
		function closeSiblings(self) {
			self.each(function() {
				closeTree(this);
			});
		}
	   
		this.each(function(el) {
			// Stores the delayed close event. Will be cancelled if mouse
			// re-enters the menu before it closes.
			var closeEvent;
			var menu = $(this);
			var handles = $(opts.handleSelector, menu);
		   
			handles.mouseenter(function(e) {
				var item = $(opts.hiderSelector + ":first", this);
				var handle = $(this);
				var commonSib = handle;
			   
				for ( var i = 0; i < opts.siblingDist; i++ ){
					closeSiblings(commonSib.siblings());
					commonSib = commonSib.parent();
				}
			   
				clearTimeout(closeEvent);
				   
				closeSiblings(commonSib.siblings());
				   
				// Show descendent item.
				handle.addClass(opts.activeClass);
				item.show();
			});
		   
			// Exiting the menu entirely it treated as a special case with
			// a delay.
			menu.mouseleave(function(e) {
				closeEvent = setTimeout(function() {
					closeTree(menu);
				}, opts.closeDelay);
			});
		   
			// Speed along close delay if user clicks outside of menu.
			if (opts.clickAway) {
				$(document).click(function(e) {
					if (!closeEvent || ($(e.target).parents().index(menu))) {
						return;
					}
					closeTree(menu);
				});
			}
		});
	   
		return this;
	};
   
	// Allow access to defaults.
	$.fn.pulldown.defaults = {
		closeDelay: 1000,
		clickAway: true,
		handleSelector: "li",
		hiderSelector: "ul",
		activeClass: "active",
		siblingDist: 0
	};
   
})(jQuery);


