/*
 * jQuery UI Menu 1.0.1
 *
 * Created by Negru Nicolae Marian (marian.negru@gmail.com)
 * Modified by Edward Leigh (edward@visualconnections.com)
 *
 * Depends:
 *   ui.core.js
 */
$.fn.reverse = Array.prototype.reverse;
(function($) {
$.widget("ui.menu", {

  version: "1.0.0",
  options: {
    scope : '',
    shadow : true,
    menuOutDelay : 150
  },
  
  _create: function() {
    var self = this;
    
    // set the scope
    if(this.options.scope)
      this.element.addClass(this.options.scope);
      
    // insert left end cap
    this.element.wrapInner('<div class="ui-menu-left">');

    // prepare menu. Set classes
    var mainMenus = this.element.find('ul:first').addClass('ui-menu').children();
    mainMenus.addClass('ui-menu-item-box');
    
    // set menu items
    mainMenus.find('a:first').addClass('ui-menu-item');

    this.element.show();
    
    // find elements with child menus
    $('li > ul', this.element).each(function() {
      var list = $(this);
      // set classes on submenus
      list.addClass('ui-submenu').children().addClass('ui-submenu-item-box')
        .find('a:first').addClass('ui-submenu-item');
    });

    var dropDowns = $('li > ul', this.element).reverse().each(function() {
        var list = $(this).css({position:'absolute', top:'0px', left:'0px'});
        //list.width(list.width()).height(list.height())
        list.parent().data('hasMenu', true);
    });

    // add the hover on submenu element
    dropDowns.each(function(i){
      var list = $(this);
      var w = list.width();
      list.children().each(function() {
        var link = $(this).find('a:first');

        if(link.length > 0) {
          // set li width heigth
          var h = link.outerHeight();
          $(this).width(w).height(h);

          $('<div class="ui-submenu-item-box-hover"></div>').prependTo(this).css({position:'absolute', top:'0px', left:'0px'}).width(w).height(h).hide();
          // set link width and height
          //var wi = link.width();
          // here add more for width on IE and mac xxxx
          var wi = w - (parseInt(link.css('padding-left'), 10) || 0) - (parseInt(link.css('padding-right'), 10) || 0);
          link.css({position:'absolute', top:'0px', left:'0px'}).width(wi).height(h); 
        }
      });
      var baseIndex = $(this).css('zIndex');
      $(this).hide().parent().css({position:'relative', zIndex : baseIndex - i}); // z-index is a fix for IE
    });
    // add the hover on menu element
    mainMenus.each(function(){
        var link = $(this).find('a:first');

        if(link.length > 0) {
          // set li width heigth
          var w = link.outerWidth(true);
          var h = link.outerHeight(true);
          $(this).width(w).height(h);
          $('<div class="ui-menu-item-box-hover"></div>').prependTo(this).css({position:'absolute', top:'0px', left:'0px'}).width(w).height(h).hide();
          // set link width and height
          w = link.width();
          h = link.height();
          link.css({position:'absolute', top:'0px', left:'0px'}).width(w).height(h);
        }
    });

    // bind events
    $('li', this.element).each(function(i){
      var baseIndex = $(this).css('zIndex');
      var menu = $(this).css({position:'relative', zIndex : baseIndex - i});// z-index is a fix for IE
      menu.hover(
        $.context(self).callback(self._onMenuOver, menu),
        $.context(self).callback(self._onMenuOut, menu));
    });

    // add dropdown shadow
    if(this.options.shadow) {
      dropDowns.each(function(){
        var ul = $(this);
        $('<div></div>').appendTo(ul.parent()).addClass('ui-submenu-shadow').css({position:'absolute', display:'none'}).width(ul.outerWidth()).height(ul.outerHeight() - 3);
      });
    }
  },
  
  _onMenuOver : function(menu) {
    // stop the hide thread first
    this._stopHideThread(menu);
    
    if(this.over != null) {
      this.over.call(menu.find('div:first'));
    }
    
    if(menu.data('hasMenu')) {
      
      menu.find('a:first').addClass('ui-menu-open');
      var el = menu.find('ul:first');
      
      if(this.hiding) {
        this._onMenuOverCallback(el,menu);
      }
      if(el.data('menu-over-timer') == null)
        el.data('menu-over-timer', 
            setTimeout($.context(this).callback(this._onMenuOverCallback, el,menu), this.options.menuOutDelay));
    }
  },
  
  _onMenuOverCallback : function(el,menu) {
    this.showSubMenu.apply(el);
      
    var t = parseInt(el.css('top'));
    var l = parseInt(el.css('left'));
    $('.ui-submenu-shadow', menu).show().css({top:(t + 5) + 'px', left:(l + 2) + 'px'});
    var timer = el.data('menu-over-timer');
    if(timer) {
      el.removeData('menu-over-timer');
      clearTimeout(timer);
    }
  },
  _stopHideThread : function(menu) {
    var hideThread = menu.data('menu-timer');
    if(hideThread != null)
    {
      clearTimeout(hideThread);
      hideThread = null;
    }
    this.hiding = false;
  },
  _onMenuOut : function(menu) {
    if(menu.data('hasMenu')) {
      this._stopHideThread(menu);
      this.hiding = true;
      menu.data('menu-timer', 
            setTimeout($.context(this).callback(this._onMenuOutCallback, menu), this.options.menuOutDelay));
    }
    else if(this.out != null) {
      this.out.call(menu.find('div:first'));
    }
  },
  _onMenuOutCallback : function(menu) {
    var el = menu.find('ul:first');
    
    this.hideSubMenu.apply(el);
    $('.ui-submenu-shadow', menu).hide();
    
    // remove the hover effect
    var menuLink = menu.find('a:first').removeClass('ui-menu-open');
    var data = menuLink.data('menu-data');
    if(data)
      data.out.call(menuLink);
      
    // hover menu
    if(this.out != null) {
      this.out.call(menu.find('div:first'));
    }
    this.hiding = false;
  },
  
  destroy: function() {
    $.Widget.prototype.destroy.apply(this, arguments);
  },
  
  showSubMenu: function() {
    var menu = this.parent();
    
    if(!menu.hasClass('ui-menu-item-box'))
      this.css({top:'0px', left:(menu.outerWidth() + 1) + 'px'});
    else
      this.css({top:(menu.outerHeight() - 1) + 'px', left:'-1px'});

    this.fadeIn(150, function() {
      if (jQuery.browser.msie)
        this.style.removeAttribute('filter');
    });
  },
  
  hideSubMenu: function() {
    this.fadeOut(150);
  },
  
  over: function() {
    // on hover
    this.fadeIn(150, function() {
      if (jQuery.browser.msie)
        this.style.removeAttribute('filter');
    });
  },
  
  out: function() {
    // off hover
    this.fadeOut(150);
  }
  
});

// $.context
$.extend(
{
  context: function (context)
  {
    var co = 
    {
      callback: function ()
      {
        /*var args = null;
        if(typeof arguments == 'Array')
          args = arguments.slice(1, arguments.length);*/
        var method = arguments[0];
        var args = [];
        for(var i = 1; i < arguments.length; i++) {
          args.push(arguments[i]);
        }
        if (typeof method == 'string') method = context[method];
          var cb = function () { method.apply(context, args ? args.concat(arguments) : arguments); }
          return cb;
        }
      };
      return co;
    }
  });
})(jQuery);

