/*
 * jdMenu 1.4.1 (2008-03-31)
 *
 * Copyright (c) 2006,2007 Jonathan Sharp (http://jdsharp.us)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://jdsharp.us/
 *
 * Built upon jQuery 1.2.1 (http://jquery.com)
 * This also requires the jQuery dimensions >= 1.2 plugin
 */

// This initializes the menu
$(function() {
	$('ul.nav_menu').jdMenu();
});

(function($)
{
	function addEvents(ul)
	{
		var settings = $.data( $(ul).parents().andSelf().filter('ul.nav_menu')[0], 'jdMenuSettings' );
		$('> li', ul)
			.bind('mouseenter.jdmenu mouseleave.jdmenu', function(evt)
 	    {
		 	$(this).toggleClass('jdm_hover');
			var ul = $('> ul', this);
			if( ul.length == 1 )
			{
				clearTimeout( this.$jdTimer );
				
				var enter = ( evt.type == 'mouseenter' );
				var fn = ( enter ? showMenu : hideMenu );
				this.$jdTimer = setTimeout(function()
				{
	 			   fn( ul[0], settings.onAnimate, settings.isVertical );
				}, enter ? settings.showDelay : settings.hideDelay );
			}
		})
		
		.bind('click.jdmenu', function(evt)
	    {
		   var ul = $('> ul', this);
		   if( ul.length == 1                                                  && 
			  (settings.disableLinks == true || $(this).hasClass('accessible')) )
		   {
			   showMenu( ul, settings.onAnimate, settings.isVertical );
			   if( $(this).hasClass('run') )  //XXX
				   return true;
			   else
				   return false;
		   }
				
		   //The user clicked the li and we need to trigger a click for the a
	  	   if( evt.target == this )
		   {
			   var link = $('> a', evt.target).not('.accessible');
			   if( link.length > 0 )
			   {
				   var a = link[0];
				   if( !a.onclick )
				   {
						window.open( a.href, a.target || '_self' );
				   }
				   else
				   {
						$(a).trigger('click');
				   }
				}
			}
			
			if( settings.disableLinks                                             || 
				(!settings.disableLinks && !$(this).parent().hasClass('nav_menu')) )
			{
				//$(this).parent().jdMenuHide(); //XXX
				evt.stopPropagation();
			}
		})
		
		.find('> a')
		.bind('focus.jdmenu blur.jdmenu', function(evt)
	   {
			var p = $(this).parents('li:eq(0)');
			if( evt.type == 'focus' )
			{
			    p.addClass('jdm_hover');
			}
			else
			{ 
			    p.removeClass('jdm_hover');
			}
		})
		
		.filter('.accessible')
		.bind('click.jdmenu', function(evt)
  	    {
			evt.preventDefault();
		});
	}

	function showMenu(ul, animate, vertical)
	{
		var ul = $(ul);
		if( ul.is(':visible') )
		{
			return;
		}
		
		ul.bgiframe();
		var li = ul.parent();
		ul	.trigger('jdMenuShow')
			.positionBy({ target: li[0], 
						  targetPos: ( vertical === true || !li.parent().hasClass('nav_menu') ? 1 : 3 ), 
						  elementPos: 0,
						  hideAfterPosition: true });

        if( !ul.hasClass('jdm_events') )
		{
			ul.addClass('jdm_events');
			addEvents(ul);
		}
		
		li	.addClass('jdm_active')
			// Hide any adjacent menus
			.siblings('li').find('> ul:eq(0):visible')
				.each(function()
 	    {
		  	 hideMenu( this ); 
		});
	
	    if( animate === undefined )
		{
			ul.show();
		}
		else
		{
			animate.apply( ul[0], [true] );
		}
	}
	
	function hideMenu(ul, animate)
	{
		var ul = $(ul);
		$('.bgiframe', ul).remove();
		ul	.filter(':not(.nav_menu)')
			.find('> li > ul:eq(0):visible')
				.each(function()
	   {
			hideMenu( this );
  	   })
	   .end();
		
	   if( animate === undefined )
	   {
			ul.hide()
	   }
	   else
	   {
			animate.apply( ul[0], [false] );
	   }

	   ul	.trigger('jdMenuHide')
			.parents('li:eq(0)')
				.removeClass('jdm_active jdm_hover')
			.end()
				.find('> li')
				.removeClass('jdm_active jdm_hover');
	}
	
	// Public methods
	$.fn.jdMenu = function(settings)
	{
		//Future settings: activateDelay
		var settings = $.extend({	// Time in ms before menu shows
									showDelay: 		200,
									// Time in ms before menu hides
									hideDelay: 		500,
									// Should items that contain submenus not 
									// respond to clicks
									disableLinks:	true
									// This callback allows for you to animate menus
									//onAnimate:	null
									}, settings);
		if( !$.isFunction( settings.onAnimate ) )
		{
			settings.onAnimate = undefined;
		}
		
		return this.filter('ul.nav_menu').each(function()
		{
			$.data(	this, 
					'jdMenuSettings', 
					$.extend({ isVertical: $(this).hasClass('nav_menu_vertical') }, settings) 
					);
			addEvents(this);
		});
	};
	
	$.fn.jdMenuUnbind = function()
	{
		$('ul.jdm_events', this)
			.unbind('.jdmenu')
			.find('> a').unbind('.jdmenu');
	};
	
	$.fn.jdMenuHide = function()
	{
		return this.filter('ul').each(function(){ 
			hideMenu( this );
	});
	};

	// Private methods and logic
	$(window)
		// Bind a click event to hide all visible menus when the document is clicked
		.bind('click.jdmenu', function()
        {
			$('ul.nav_menu ul:visible').jdMenuHide();
		});
})(jQuery);

