/**
 * W|W JavaScript Dropdown Menus.
 * 
 * Version 1.0 (totally made that up)
 * 
 * Requires:
 *   jQuery 1.2.2+
 *   jQuery Dimensions Plugin 1.2+
 * 
 * @author Pat Collins <pat@walltowall.com>
 */

(function($){

var menus = [];
var subMenus = [];
var options = {
  mode: 'horizontal',
  submenus: {
    mode: 'separate' // could be "integrated"
  },
  offsets: {
    x: 0,
    y: 0
  },
  hidedelay: 200
};
var state = 'NO_MENUS_SHOWN';

$.fn.extend({
/**
 * Attaches the dropdown behavior to 
 * 
 * @param int numOfSubMenus The number of submenus, calculated in the main wwMenu() function above. Used to calculate if submenu is last submenu or not.
 * @param int index The index of the submenu being currently processed. Used to calculate if submenu is last submenu or not.
 * @param object offsets The offsets passed in through the wwMenu() constructor.
 * 
 * @return object The absolute top and left positions where the submenu should go, relative to the parent menu element. (The "this" in wwMenu above.)
 */
  wwMenu: function(passedOptions){
    this.each(function(){
      var id = this.id;
      var index = menus.length; // generate unique index based on how many menus have been generated with this script.
      
      // overwrite default options.
      options = $.extend(options, passedOptions || {});
      // console.log(options);
      
      switch(options.submenus.mode){
        case 'separate':
          // console.log($(".submenu", this).length);
          $(".submenu", this).clone(true).appendTo($('body')).end().remove();
          break;
      }
      
      menus[index] = $(this);
      subMenus[index] = $(".submenu");
      
      // attach menu behavior.
      $(this).children("ul.main").children("li").children("a").hover(function(){
        state = 'LINK_MOUSEOVER';
        // link mouseover
        var link = $(this);
        // openMenu(this.id);
        subMenus[index].hide();
        link.findAndSetPosition(subMenus[index].length, options.offsets);
        wwMenuTrigger('linkMouseOverBefore');
        var id = link.parent().get(0).id.split("_link")[0];
        link.addClass("hover");
        $('#'+id).show();
        wwMenuTrigger('linkMouseOverAfter');
      },function(){
        state = 'LINK_MOUSEOUT';
        // link mouseout
        var link = $(this);
        link.removeClass("hover");
        setTimeout(function(){
          if($.inArray(state, ['LINK_MOUSEOVER', 'SUB_MENU_MOUSEOVER']) == -1){
            wwMenuTrigger('linkMouseOutBefore');
            var id = link.parent().get(0).id.split("_link")[0];
            $('#'+id).hide();
            wwMenuTrigger('linkMouseOutAfter');
            state = 'NO_MENUS_SHOWN';
          }
        }, options.hidedelay);
      }).end().each(function(){
        var id = this.id.split("_link")[0];
        // taking the id of the links, finding the divs, and attaching behavior.
        $('#'+id+', #'+id+' a').hover(function(){
          state = 'SUB_MENU_MOUSEOVER';
          wwMenuTrigger('subMenuMouseOverBefore');
          $('#'+id).show();
          wwMenuTrigger('subMenuMouseOverAfter');
        },function(){
          state = 'SUB_MENU_MOUSEOUT';
          $('#'+id+'_link').children().removeClass("hover");
          setTimeout(function(){
            if($.inArray(state, ['LINK_MOUSEOVER', 'SUB_MENU_MOUSEOVER']) == -1){
              wwMenuTrigger('subMenuMouseOutBefore');
              $('#'+id).hide();
              wwMenuTrigger('subMenuMouseOutAfter');
              state = 'NO_MENUS_SHOWN';
            }
          }, options.hidedelay);
        }).mousemove(function(){
          wwMenuTrigger('subMenuMouseMoveBefore');
          $('#'+id+'_link').children().addClass("hover");
          $('#'+id).show();
          wwMenuTrigger('subMenuMouseMoveAfter');
        });
      });
      
      // Function to calculate absolute positions of the submenus in question.
      // Done on window.onload, thus wwAddLoadEvent() adds this event onto a window.load "queue" 
      wwAddLoadEvent(function(){
        // Position the top of each flyout element to the top of where its corresponding link in the main menu is.
        var numOfSubMenus = subMenus[index].length;
        subMenus[index].each(function(i){
          // set the node to be evaluated.
          // this may need to change depending on the menu's CSS.
          // generally, it should grab the position of the child link elements to base the submenu's position on. (helpful if links are set to display:block in CSS)
          // this generality was discovered b/c of browser incompatibilities with jQuery Dimensions plugin and Safari 2
          var node = $('#'+this.id+'_link').children("a");
          // get the submenu's position
          var pos = node.wwSubMenuPos(numOfSubMenus, i, options.offsets);
          // console.log(pos);
          $(this).css(pos);
        });
      });
    });
  },
  
  findAndSetPosition: function(numOfSubMenus, offsets){
    var id = $(this).parent().get(0).id.split("_link")[0];
    var index = $.inArray($("#"+id)[0], $.makeArray($(".submenu")));
    // console.log(index);
    if(index > -1){
      var pos = $(this).wwSubMenuPos(numOfSubMenus, index, offsets);
      $("#"+id).css(pos);
      // console.log(pos);
    }
  },
  
/**
 * Returns the top/left positions of where the submenu should be placed for the given top-level menu item (this)
 * 
 * @param int numOfSubMenus The number of submenus, calculated in the main wwMenu() function above. Used to calculate if submenu is last submenu or not.
 * @param int index The index of the submenu being currently processed. Used to calculate if submenu is last submenu or not.
 * @param object offsets The offsets passed in through the wwMenu() constructor.
 * 
 * @return object The absolute top and left positions where the submenu should go, relative to the parent menu element. (The "this" in wwMenu above.)
 */
  wwSubMenuPos: function(numOfSubMenus, index, offsets){
    var top;
    var left;
    
    offsets = $.extend({
      x: 0,
      y: 0
    }, offsets || {});
    
    var pos = this.offset();
    
    top = pos.top;
    left = pos.left;
    switch(options.mode){
      case 'horizontal':
        top = top + this.outerHeight();
        if(index == numOfSubMenus-1){
          var menu;
          $(this).parents("li").eq(0).each(function(){
            var menu_id = this.id.split('_link')[0];
            menu = $("#"+menu_id);
          });
          left = left - (menu.outerWidth() - this.outerWidth());
        }
        break;
      case 'vertical':
        var padTop = 0;
        // hacky, i know.
        // if($.browser.msie && parseFloat($.browser.version) <= 6){
        //  padTop -= this.parents("ul.main").position().top - 3;
        // }

        // var parents = this.parents();
        // parents = $.grep(parents, function(n, i){
        //  return i <= $.inArray($("#menu").get(0), $.makeArray(parents));
        // });
        // $.each(parents, function(i,parent){
        //  // padTop += parseInt($.curCSS($(parent).jquery ? $(parent)[0] : $(parent), 'paddingTop', true)) || 0;
        //  // var top = parseInt($.curCSS($(parent).jquery ? $(parent)[0] : $(parent), 'top', true)) || 0;
        //  // console.log(top);
        //  console.log($(parent));
        //  console.log($(parent).position());
        //  // padTop += parseInt($.curCSS($(parent).jquery ? $(parent)[0] : $(parent), 'top', true)) || 0;
        // });
        // alert(top);
        // console.log(this.offset());
        top = top + padTop;
        left = left + this.outerWidth();
        break;
    }

    return {
      'top': top + offsets.y + 'px',
      'left': left + offsets.x + 'px'
    };
  }
});

var openMenu = function(id){
  
};

var keepMenu = function(id){
  
};

var wwMenuTrigger = function(trigger){
  switch(trigger){
    case 'linkMouseOverBefore':
      defaultBeforeMenuDisplayActions();
      break;
    case 'linkMouseOverAfter':
      break;
    case 'linkMouseOutBefore':
      break;
    case 'linkMouseOutAfter':
      defaultAfterMenuDisplayActions();
      break;
    case 'subMenuMouseOverBefore':
      defaultBeforeMenuDisplayActions();
      break;
    case 'subMenuMouseOverAfter':
      break;
    case 'subMenuMouseOutBefore':
      break;
    case 'subMenuMouseOutAfter':
      defaultAfterMenuDisplayActions();
      break;
    case 'subMenuMouseMoveBefore':
      defaultBeforeMenuDisplayActions();
      break;
    case 'subMenuMouseMoveAfter':
      break;
  }
};

var defaultBeforeMenuDisplayActions = function(){
  if($.browser.msie) {
    $("select").css("visibility", "hidden");
  }
};

var defaultAfterMenuDisplayActions = function(){
  if($.browser.msie) {
    $("select").css("visibility", "visible");
  }
};

var wwAddLoadEvent = function(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
};

})(jQuery);


