var HMenu = {
    branch: null,
    isOpera: (typeof window.opera != 'undefined'),
    isIE: (typeof document.all != 'undefined' &&
           typeof window.opera == 'undefined' &&
           navigator.vendor != 'KDE'),
    isIElt7: (typeof document.all != 'undefined' &&
              typeof window.opera == 'undefined' &&
              navigator.vendor != 'KDE' &&
              typeof XMLHttpRequest != 'object'),
    isSafari: (navigator.vendor == 'Apple Computer, Inc.'),
    
    hasClass: function(elem, cls) {
        return new RegExp("(^|\\s)" + cls + "(\\s|$)").test(elem.className);
    },
    
    addClass: function(elem, cls) {
        if(HMenu.hasClass(elem, cls)) { return; }
        elem.className += (elem.className ? ' ' : '') + cls;
    },
    
    removeClass: function(elem, cls) {
        elem.className = elem.className.replace(new RegExp("(^|\\s*\\b[^-])" + cls + "($|\\b(?=[^-]))", "g"), "");
    },
    
    dropdownMenu: function(navId) {   
      var tree = document.getElementById(navId);
      if (tree) {
        var isHoriz = HMenu.hasClass(tree, 'hm-horiz');
        HMenu.branch = tree;
        var items = tree.getElementsByTagName('li');
        for (var i = 0; i < items.length; i++) {
          HMenu.dropdownTrigger(tree, items[i], navId, isHoriz);
        }
    
        if (!HMenu.isOpera) {
          HMenu.cleanUselessWhitespace(tree);
    
          var keyevent = HMenu.isSafari || HMenu.isIE ? 'keydown' : 'keypress';
          addEvent(document, keyevent, function(e) {
            var target = typeof e.target != 'undefined' ? e.target : e.srcElement;
            if (tree.contains(target) && target.getAttribute('href')) {
              if (/^(37|38|39|40)$/.test(e.keyCode.toString())) {
                HMenu.arrowKeyNavigation(tree, target, e.keyCode, isHoriz);
    
                cancelEvent(e);
                return false;
              }
            }
            return true;
    
          }, false);
        }
    
        var eles = typeof document.all != 'undefined' ? document.all : document.getElementsByTagName('*');
        for (i = 0; i < eles.length; i++) {
          addEvent(eles[i], 'focus', function(e) {
            var target = typeof e.target != 'undefined' ? e.target : e.srcElement;
            
            if (!tree.contains(target)){
              HMenu.resetSiblingBranches(items[0]);
            }
          }, false);
        }
    
        if (!HMenu.isIE) {
          tree.contains = function(node) {
            if (node === null) { return false; }
            if (node == this) { return true; }
            else { return this.contains(node.parentNode); }
          };
        }
      }
    },
    
    dropdownTrigger: function(tree, li, navId, isHoriz) {
      var opentime, closetime;
      var a = li.getElementsByTagName('a')[0];
      var submenus = li.getElementsByTagName('ul');
      var menu = submenus.length > 0 ? submenus[0] : null;
      var isSub = li.parentNode.id == navId;
      
	  if(isSub) li.style.color = "red";
	  
      if(HMenu.isOpera) {
        // For whatever reason, Opera needs "display: table"
        // on all of the <li>'s otherwise keyboard navigation
        // won't work reliably
        li.style.display = "table";
      }
      
      if (menu) {
        HMenu.addClass(li, 'hm-hasMenu');
        
        if(HMenu.isIE && !HMenu.isIElt7) {
          // Really strange IE7 issue where
          // where <li>'s with <ul>'s under
          // them get some extra margin space
          li.style.marginBottom = "-3px";
        }
        
        HMenu.addClass(a, 'hm-menuLink');
      }
    
      addEvent(a, 'focus', function(e) {
        clearTimeout(closetime);
    
        HMenu.addClass(a, 'hm-rollover');
    
        HMenu.resetSiblingBranches(li);
        if (menu) {
          HMenu.showMenu(menu, isHoriz, isSub, li, a);
        }
    
        var parent = li.parentNode;
        if (parent != tree) {
          if (parent.style.left === '' || parent.style.left == '-999em') {
            HMenu.showAncestors(tree, parent, isHoriz, isSub);
          }
        }
      }, false);
    
      addEvent(li, 'mouseover', function(e) {
        if (HMenu.unwantedTextEvent()) { return; }
        clearTimeout(closetime);
        if (HMenu.branch == li) { HMenu.branch = null; }
    
        HMenu.addClass(a, 'hm-rollover');
    
        var target = typeof e.target != 'undefined' ? e.target : window.event.srcElement;
        while (target.nodeName.toUpperCase() != 'LI') {
          target = target.parentNode;
        }
        if (target != li) { return; }
    
        if (menu) {
          opentime = window.setTimeout(function() {
            if (HMenu.branch) {
              HMenu.clearMenus(HMenu.branch);
              HMenu.branch = null;
            }
    
            HMenu.resetSiblingBranches(li);
            HMenu.showMenu(menu, isHoriz, isSub, li, a);
          }, 250);
        }
      }, false);
    
      addEvent(li, 'mouseout', function(e) {
        if (HMenu.unwantedTextEvent()) { return; }
        
        var related = typeof e.relatedTarget != 'undefined' ? e.relatedTarget : window.event.toElement;
        if (!li.contains(related)) {
          clearTimeout(opentime);
          HMenu.branch = li;
    
          HMenu.removeClass(a, 'hm-rollover');
          if (menu) {
            closetime = window.setTimeout(function() {
              menu.style.left = '-999em';
    
              HMenu.removeIframeLayer(menu);
            }, 600);
          }
        }
      }, false);
    
      if (!HMenu.isIE) {
        li.contains = function(node) {
          if (node === null) { return false; }
          if (node == this) { return true; }
          else { return this.contains(node.parentNode); }
        };
      }
    },
    
    showMenu: function(menu, isHoriz, isSub, li, a) {
      HMenu.addClass(a, 'hm-rollover');
      
      menu.style.left = isHoriz ? (HMenu.isIE ? (/*HMenu.isIElt7 ? li.offsetLeft + 'px' : */0) : 'auto') : '0';
      //menu.style.top = isHoriz && isSub ? (HMenu.isIE ? a.offsetHeight + 'px' : 'auto') : (HMenu.isIE ? li.offsetTop + 'px' : '0');
      //var testit = li.offsetTop != '-1' ? li.offsetTop: getRoughPosition(li);
      menu.style.top = isHoriz && isSub ? (HMenu.isIE ? li.offsetHeight + 'px' : 'auto') : (/*HMenu.isIElt7 ? testit + 'px' : */'0');
      
      HMenu.repositionMenu(menu);
    
      if (HMenu.isIElt7) {
        HMenu.createIframeLayer(menu);
      }
    },
    
    showAncestors: function(tree, menu, isHoriz, isSub) {
      HMenu.clearMenus(tree);
    
      while (menu.id != tree.id) {
        var li = menu.parentNode;
        var a = li.getElementsByTagName('a')[0];
    
        HMenu.showMenu(menu, isHoriz, isSub, li, a);
    
        menu = li.parentNode;
      }
    },
    
    resetSiblingBranches: function(trigger) {
      HMenu.clearMenus(trigger.parentNode);
    
      var links = trigger.parentNode.getElementsByTagName('a');
      for (var i = 0; i < links.length; i++) {
        HMenu.removeClass(links[i], 'hm-rollover');
      }
    },
    
    cleanUselessWhitespace: function(node) {
      for (var x = 0; x < node.childNodes.length; x++) {
        var child = node.childNodes[x];
        if (child.nodeType == 3 && !(/\S/.test(child.nodeValue))) {
          node.removeChild(node.childNodes[x]);
          x--;
        }
        if (child.nodeType == 1) {
          HMenu.cleanUselessWhitespace(child);
        }
      }
    },
    
    mapKeyCode: function(keycode, type) {
      switch (type) {
        case 0:
          if (keycode == 37) { keycode = 39; }
          else if (keycode == 39) { keycode = 37; }
          break;
    
        case 1:
          if (keycode % 2) { keycode++; }
          else { keycode--; }
          break;
    
        case 2:
          if (keycode == 38) { keycode = 37; }
          break;
      }
    
      return keycode;
    },
    
    arrowKeyNavigation: function(tree, link, keycode, isHoriz) {
      var li = link.parentNode;
      var submenus = li.getElementsByTagName('ul');
      var menu = submenus.length > 0 ? submenus[0] : null;
      var parent = li.parentNode;
      
      if (menu) {
        if (HMenu.getRoughPosition(menu, 'x') < HMenu.getRoughPosition(li.parentNode, 'x')) {
          keycode = HMenu.mapKeyCode(keycode, 0);
        }
      }
      else if (parent != tree) {
        if (HMenu.getRoughPosition(parent.parentNode.parentNode, 'x') > HMenu.getRoughPosition(parent, 'x')) {
          keycode = HMenu.mapKeyCode(keycode, 0);
        }
      }
    
      if (isHoriz) {
        if (parent == tree) {
          keycode = HMenu.mapKeyCode(keycode, 1);
        } else if (parent.parentNode.parentNode == tree && li == li.parentNode.firstChild) {
          keycode = HMenu.mapKeyCode(keycode, 2);
        }
      }
    
      switch (keycode) {
        case 37:
          parent = parent.parentNode;
          if (tree.parentNode == parent) { parent = null; }
          if (parent) {
            parent.firstChild.focus();
          }
          break;
    
        case 38:
          var previous = li.previousSibling;
          if (!previous) {
            previous = li.parentNode.childNodes[li.parentNode.childNodes.length - 1];
          }
          previous.firstChild.focus();
          break;
    
        case 39:
          if (menu) {
            menu.firstChild.firstChild.focus();
          }
          break;
    
        case 40:
          var next = li.nextSibling;
          if (!next) {
            next = li.parentNode.childNodes[0];
          }
          next.firstChild.focus();
          break;
      }
    },
    
    clearMenus: function(root) {
      var menus = root.getElementsByTagName('ul');
      for (var i = 0; i < menus.length; i++) {
        menus[i].style.left = '-999em';
        HMenu.removeIframeLayer(menus[i]);
      }
    },
    
    unwantedTextEvent: function() {
      return (navigator.vendor == 'Apple Computer, Inc.' &&
              (event.target == event.relatedTarget.parentNode ||
               (event.eventPhase == 3 &&
                event.target.parentNode == event.relatedTarget)));
    },
    
    getRoughPosition: function(ele, dir) {
      var pos = dir == 'x' ? ele.offsetLeft : ele.offsetTop;
      var tmp = ele.offsetParent;
      while (tmp !== null) {
        pos += dir == 'x' ? tmp.offsetLeft : tmp.offsetTop;
        tmp = tmp.offsetParent;
      }
      return pos;
    },
    
    getViewportSize: function() {
      var size = [0,0];
    
      if (typeof window.innerWidth != 'undefined') {
        size = [
            window.innerWidth,
            window.innerHeight
        ];
      } else if (typeof document.documentElement != 'undefined' &&
                 typeof document.documentElement.clientWidth != 'undefined' &&
                 document.documentElement.clientWidth !== 0) {
        size = [
            document.documentElement.clientWidth,
            document.documentElement.clientHeight
        ];
      } else {
        size = [
            document.getElementsByTagName('body')[0].clientWidth,
            document.getElementsByTagName('body')[0].clientHeight
        ];
      }
    
      return size;
    },
    
    repositionMenu: function(menu) {
      var extent = [
          HMenu.getRoughPosition(menu, 'x') + menu.offsetWidth + 25,
          HMenu.getRoughPosition(menu, 'y') + menu.offsetHeight + 25
      ];
      var viewsize = HMenu.getViewportSize();
    
      if (extent[0] > viewsize[0]) {
        var offset = menu.offsetWidth + menu.parentNode.parentNode.offsetWidth;
        var inset = menu.parentNode.offsetWidth - menu.offsetLeft;
    
        menu.style.left = (0 - offset + (inset * 2)) + 'px';
      }
    
      if (extent[1] > viewsize[1]) {
        var current = parseInt(menu.style.top, 10);
        var difference = extent[1] - viewsize[1];
    
        menu.style.top = (current - difference) + 'px';
      }
    },
    
    createIframeLayer: function(menu) {
      var layer = document.createElement('iframe');
      layer.tabIndex = '-1';
      layer.src = 'javascript:false;';
      menu.parentNode.appendChild(layer);
    
      layer.style.left = menu.offsetLeft + 'px';
      layer.style.top = menu.offsetTop + 'px';
      layer.style.width = menu.offsetWidth + 'px';
      layer.style.height = menu.offsetHeight + 'px';
    },
    
    removeIframeLayer: function(menu) {
      var layers = menu.parentNode.getElementsByTagName('iframe');
      while (layers.length > 0) {
        layers[0].parentNode.removeChild(layers[0]);
      }
    }
};

addEvent(window, 'load', function() {
    if(typeof document.getElementById == 'undefined' ||
       typeof document.getElementsByTagName == 'undefined' ||
       (HMenu.isSafari && typeof window.XMLHttpRequest == 'undefined') ||
       (HMenu.isIE && typeof document.uniqueID == 'undefined')) {
        return;
    }
    
    HMenu.dropdownMenu('cstNav');
});
