/*
 * 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();
});

(function($) {
    function addEvents(ul) {
        var settings = $.data($(ul).parents().andSelf().filter('ul.jd_menu')[0], 'jdMenuSettings');
        
        $('> li[class!=splitter]', 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')
//disable position adjust
//			.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);
