( function($) {

    /**
     * 
     * Dropdown-type menu jQuery plugin.
     * 
     * @requires jQuery 1.2.6 or above
     * 
     * @param {Object} options
     *            
     */
    $.fn.dropDownMenu = function(options) {
        
        var defaults = {
            subXoffset : 3,
            subYoffset : 0,
            subMenuEffect : {
                type : 'expand',      // expand | fade
                openSpeed : 300,      // Milliseconds
                closeSpeed : 150,     // Milliseconds
                delay : 250           // Milliseconds
            }
        };

        var options     = $.extend(defaults, options);
        var menuWrapper = $(this).parent();
        var menuBlocks  = $('li', this);
        var properties  = {};



        /**
         * Calculate the closing speed based on speed ratio set in the options
         * and the height of the object to be displayed.
         * 
         */
        $.fn.setAnimProperties = function() {
            var menuBlock = $(this);
            var props = {};
            
            props.height = menuBlock.outerHeight();
            props.offset = menuBlock.offset();
            
            props.openSpeedMs = ((options.subMenuEffect.openSpeed / 2) * props.height);
            props.closeSpeedMs = props.openSpeedMs * (options.subMenuEffect.closeSpeed / options.subMenuEffect.openSpeed);
            
            return props;
        };



        /**
         * Submenu display effects
         * 
         */
        $.fn.setSubMenuAnim = function() {
            var menuBlock =  $(this);
            var func = {};

            var animProperties = menuBlock.setAnimProperties();
            var openHeight = animProperties.height - properties.subOffsetY;

            // Fade in/out
            if (options.subMenuEffect.type == 'fade') {

                func.open = function() {
                    menuBlock.fadeIn(300);
                 };

                 func.close = function() {
                     menuBlock.fadeOut(150);
                 };
            
            // Expand
            } else if (options.subMenuEffect.type == 'expand') {
                
                func.open = function() {
                    menuBlock.show(300);
                };
                
                func.close = function() {
                    menuBlock.hide(150);
                };
            }
            
            return func;
        };



        /**
         * Toggle submenu.
         * 
         */
        $.fn.toggleSubMenu = function() {
            var parentLi = $(this);
            var subMenu = $('> ul', parentLi);
            
            var runOpenAnim;

            var effectFunc = subMenu.setSubMenuAnim();

            parentLi.hover(
            function() {
                runOpenAnim = setTimeout(effectFunc.open, options.subMenuEffect.delay);
                parentLi.addClass('over');
            },
            function() {
                clearTimeout(runOpenAnim);
                setTimeout(effectFunc.close, options.subMenuEffect.delay);
                parentLi.removeClass('over');
            });
            
            return this;
        };



        /**
         * Calculate submenu offset.
         * 
         */
        $.fn.setSubOffset = function(isLast, isTop) {
            var thisBlock = $(this);

            var thisHeight = thisBlock.outerHeight();
            var thisWidth = thisBlock.outerWidth();
 
            // Top level : Sub level - Normal
            properties.subOffsetX = (isTop) ? 0 : (thisWidth + options.subXoffset);
            properties.subOffsetY = (isTop) ? thisHeight : options.subYoffset;

            return this;
        };



        /**
         * Initiate the menu.
         * 
         */
        menuBlocks.each( function() {
            var thisBlock = $(this);

            if ($(':has(ul)', thisBlock)) {

                thisBlock.find('ul').css('z-index', 3000);
                
                /* Apply bgiframe to dropdown in IE6 - bgiframe must be loaded. */
                if ($.browser.msie && $.browser.version < 7) {
                    thisBlock.find('ul').bgiframe();
                }

                thisBlock.toggleSubMenu();
            }
            
            return this;
        });
    }
    
    return this;    
        
})(jQuery);

