/*

 * 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.jd_menu').jdMenu();

	$('li.menu-sub').eq(0).removeClass().addClass("menu-left");

	$('li.menu-sub:last').removeClass().css("float","right").addClass("menu-right");

});



(function($){

	function addEvents(ul) {

		var settings = $.data( $(ul).parents().andSelf().filter('ul.jd_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 );

					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('jd_menu') ) ) {

					$(this).parent().jdMenuHide();

					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('jd_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(.jd_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.jd_menu').each(function() {

			$.data(	this,

					'jdMenuSettings',

					$.extend({ isVertical: $(this).hasClass('jd_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.jd_menu ul:visible').jdMenuHide();

		});



})(jQuery);


