/*
 * jQuery ddMenu plugin v1.4
 * File Date: 10/28/2008
 *
 * Copyright (c) 2008 Jim Salyer
 * Licensed under the MIT License:
 *   http://www.opensource.org/licenses/mit-license.php
 */
 
$.extend({
  ddMenu: {
    active: []
  }
});

$.fn.extend({
  ddMenu: function(locals)
  {
    // initialize the global properties and merge them with the provided properties
    var globals = {
      menuClass: "ddMenu",
      submenuClass: "ddMenuSub",
      activeClass: "ddMenuActive",
      activeLinks: true,
      showDelay: 0,
      hideDelay: 0,
      offsetHX: 0,
      offsetHY: 0,
      offsetVX: 0,
      offsetVY: 0,
      zIndex: 1000,
      init: function(){$(this).dequeue();},
      show: function(){$(this).show().dequeue();},
      hide: function(){$(this).hide().dequeue();},
      blankPage: "about:blank"
    };
    $.extend(globals, locals);
    
    // initialize the Internet Explorer 6 detector and the global root menu object
    var ie6 = ($.browser.msie && parseInt($.browser.version) <= 6 && !this.XMLHttpRequest);
    var menus = $(this);
    if (menus.length <= 0) return;
    
    // start the root menu's "chain" by adding the appropriate class to it and queueing up the initialization handler
    menus.addClass(globals.menuClass).css("z-index", globals.zIndex).queue($.isFunction(globals.init) ? globals.init : function(){$(this).dequeue();}).find("ul").wrap('<div class="' + globals.submenuClass + '"></div>').parent().each(function()
    {
      var menu = $(this);
      menu.css("z-index", parseInt(menu.parent().css("z-index")) + 1);
    });
    
    // loop through the items in the menus
    menus.find("li").each(function()
    {
      var li = $(this);
      if (li.find("ul").length > 0)
      {
        // get each item that has a submenu and set its initial properties
        li.data("ddMenu_showFunction", function()
        {
          if ($.inArray(li.parents("li:eq(0)").get(0), $.map($.ddMenu.active, function(n, i)
          {
            return n.get(0);
          })) < 0)
          {
            $.each($.ddMenu.active, function(i, n)
            {
              window.clearTimeout(n.data("ddMenu_showDelay"));
              window.clearTimeout(n.data("ddMenu_hideDelay"));
              n.data("ddMenu_hideFunction")();
            });
            $.ddMenu.active = [];
          }
          $.ddMenu.active.push(li);
          
          // 1. apply the active item class
          // 2. set up the item's submenu position
          // 3. queue up the show handler
          // 4. show an IFrame behind the menu if the browser is Internet Explorer 6
          li.addClass(globals.activeClass).children("a").addClass(globals.activeLinks ? globals.activeClass : "").parent().children("div." + globals.submenuClass).css({
            left: li.css("float") == "none" ? li.outerWidth() + globals.offsetVX : globals.offsetHX,
            top: li.css("float") == "none" ? globals.offsetVY : li.outerHeight() + globals.offsetHY
          }).queue($.isFunction(globals.show) ? globals.show : function(){$(this).show().dequeue();}).queue(function()
          {
            var menu = $(this);
            var mo = menu.position();
            
            if (ie6)
            {
              li.data("ddMenu_iframe").css({
                left: mo.left,
                top: mo.top,
                height: menu.outerHeight(),
                width: menu.outerWidth()
              }).show();
            }
            menu.dequeue();
          });
        });
        
        li.data("ddMenu_hideFunction", function()
        {
          // 1. remove the active item class
          // 2. hide the IFrame behind the menu if the browser is Internet Explorer 6
          // 3. queue up the hide handler
          li.removeClass(globals.activeClass).children("a").removeClass(globals.activeLinks ? globals.activeClass : "").parent().children("div." + globals.submenuClass).queue(function()
          {
            if (ie6) li.data("ddMenu_iframe").hide();
            $(this).dequeue();
          }).queue($.isFunction(globals.hide) ? globals.hide : function(){$(this).hide().dequeue();});
        });
        
        li.data("ddMenu_showTimer", null);
        li.data("ddMenu_hideTimer", null);
        if (ie6) li.data("ddMenu_iframe", $('<iframe src="' + globals.blankPage + '" border="0" frameborder="0" style="position:absolute; left:0; top:0; z-index:' + li.css("z-index") + ';"></iframe>').appendTo(li).hide());
        
        // set up the hover events for the item
        li.hover(function()
        {
          // clear the item's hide timer (if one is running) and start a new show timer
          window.clearTimeout(li.data("ddMenu_hideTimer"));
          li.data("ddMenu_showTimer", window.setTimeout(li.data("ddMenu_showFunction"), globals.showDelay));
        }, function()
        {
          // clear the item's show timer (if one is running) and start a new hide timer
          window.clearTimeout(li.data("ddMenu_showTimer"));
          li.data("ddMenu_hideTimer", window.setTimeout(li.data("ddMenu_hideFunction"), globals.hideDelay));
        });
      }
      else
      {
        // appropriately handle each item that doesn't have a submenu
        li.mouseover(function()
        {
          if ($.inArray(li.parents("li").get(0), $.map($.ddMenu.active, function(n, i)
          {
            return n.get(0);
          })) < 0)
          {
            $.each($.ddMenu.active, function(i, n)
            {
              window.clearTimeout(n.data("ddMenu_showDelay"));
              window.clearTimeout(n.data("ddMenu_hideDelay"));
              n.data("ddMenu_hideFunction")();
            });
            $.ddMenu.active = [];
          }
          /*$.each($.ddMenu.active, function(i, n)
          {
            if (n.parents("li").length > 0)
            {
              n.parents("li").each(function()
              {
                if ($(this).get(0) == li.parents("li").get(0))
                {
                  window.clearTimeout(n.data("ddMenu_showDelay"));
                  window.clearTimeout(n.data("ddMenu_hideDelay"));
                  n.data("ddMenu_hideFunction")();
                }
              });
            }
          });*/
        });
      }
    });
    return menus;
  }
});