/*
 * 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
 */

(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) { 
                try {
                    $(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 );
                    }
                } catch (err) {alert('mouseenter.jdmenu/mouseleave.jdmenu handling error: ' + err.toString());}
            })
            .bind('click.jdmenu', function(evt) {
                try {
                    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();
                    }
                } catch (err) {alert('click.jdmenu handling error: ' + err.toString());}
            })
            .find('> a')
                .bind('focus.jdmenu blur.jdmenu', function(evt) {
                    try {

                        var p = $(this).parents('li:eq(0)');
                        if ( evt.type == 'focus' ) {
                            p.addClass('jdm_hover');
                        } else {
                            p.removeClass('jdm_hover');
                        }
                    } catch (err) {alert('focus.jdmenu/blur.jdmenu handling error: ' + err.toString());}
                })
                .filter('.accessible')
                    .bind('click.jdmenu', function(evt) {
                        try {
                            evt.preventDefault();
                        } catch (err) {alert('click.jdmenu handling error: ' + err.toString());}

                    });
    }

    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:    false
                                    // 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);

var initJdMenu = function() {
    try {
        $('ul.jd_menu').jdMenu();
    } catch (err) {
        alert('initJdMenu error: ' + err.toString());
    }

}
// This initializes the menu
$(initJdMenu);

