/*
Determine whether the browser is IE5.0.
*/
function isIE50() { // Private method
  return isIE5() && !isIE55();
}

/*
Determine whether the browser is IE5.5.
*/
function isIE55() { // Private method
  return navigator.userAgent.indexOf("MSIE 5.5") > -1;
}

function isIE7() {
	return navigator.userAgent.indexOf("MSIE 7") > -1;
}
/*
Determine whether the browser is IE5.0 or IE5.5.
*/
function isIE5() { // Private method
  return navigator.userAgent.indexOf("MSIE 5") > -1;
}

/*
Determine whether the browser is IE6.
*/
function isIE6() { // Private method
  return navigator.userAgent.indexOf("MSIE 6") > -1 && navigator.userAgent.indexOf("Opera") == -1;
}

/*
Determine whether the browser is IE.
*/
function isIE() { // Private method
  return isIE5() || isIE6() || isIE7();
}

/*
Determine whether the browser is Opera.
*/
function isOpera() { // Private method
  return navigator.userAgent.indexOf("Opera") > -1;
}

/*
Determine whether the browser is Safari.
*/
function isSafari() { // Private method
  return navigator.userAgent.indexOf("Safari") > -1;
}

/*
Determine the page render mode.

0: Quirks mode.
1: Strict mode.
*/
function getPageMode() { // Private method
  if (document.compatMode) {
    switch (document.compatMode) {
      case "BackCompat":
        return 0;
      case "CSS1Compat":
        return 1;
      case "QuirksMode":
        return 0;
    }
  }
  else {
    if (ie5) {
      return 0;
    }
    if (safari) {
      return 1;
    }
  }
  return 0;
}

/*
Alias for document.getElementById().
*/
function getElmId(id) { // Private method
  return document.getElementById(id);
}

/*
Alias for document.createElement().
*/
function createElm(tagName) { // Private method
  return document.createElement(tagName);
}

/*
Get the x-coordinate of the cursor position relative to the window.
*/
function getX(e) { // Private method
  if (!e) {
    var e = window.event;
  }
  if (safari) {
    return e.clientX - getScrollLeft();
  }
  else {
    return e.clientX;
  }
}

/*
Get the y-coordinate of the cursor position relative to the window.
*/
function getY(e) { // Private method
  if (!e) {
    var e = window.event;
  }
  if (safari) {
    return e.clientY - getScrollTop();
  }
  else {
    return e.clientY;
  }
}

/*
Get the scrollLeft property.
*/
function getScrollLeft() { // Private method
  switch (pageMode) {
    case 0:
      return document.body.scrollLeft;
    case 1:
      if (document.documentElement && document.documentElement.scrollLeft > 0) {
        return document.documentElement.scrollLeft;
      }
      else {
        return document.body.scrollLeft;
      }
  }
}

/*
Get the scrollTop property.
*/
function getScrollTop() { // Private method
  switch (pageMode) {
    case 0:
      return document.body.scrollTop;
    case 1:
      if (document.documentElement && document.documentElement.scrollTop > 0) {
        return document.documentElement.scrollTop;
      }
      else {
        return document.body.scrollTop;
      }
  }
}

/*
Get the clientHeight property.
*/
function getClientHeight() { // Private method
  switch (pageMode) {
    case 0:
      return document.body.clientHeight;
    case 1:
      if (safari) {
        return self.innerHeight;
      }
      else {
        if (!opera && document.documentElement && document.documentElement.clientHeight > 0) {
          return document.documentElement.clientHeight;
        }
        else {
          return document.body.clientHeight;
        }
      }
  }
}

/*
Get the clientWidth property.
*/
function getClientWidth() { // Private method
  switch (pageMode) {
    case 0:
      return document.body.clientWidth;
    case 1:
      if (safari) {
        return self.innerWidth;
      }
      else {
        if (!opera && document.documentElement && document.documentElement.clientWidth > 0) {
          return document.documentElement.clientWidth;
        }
        else {
          return document.body.clientWidth;
        }
      }
  }
}

/*
Convert the string into lower camel case.
*/
function toCamelCase(input) { // Private method
  var inputArray = input.split("-");
  if (inputArray.length == 1) {
    return inputArray[0];
  }
  else {
    var camelCase = inputArray[0];
    for (var i = 1, len = inputArray.length; i < len; i++) {
      camelCase += inputArray[i].charAt(0).toUpperCase() + inputArray[i].substring(1);
    }
    return camelCase;
  }
}

/*
Get the value of the property of the object.
*/
function getPropVal(obj, propertyName) { // Private method
  var propertyValue = obj.style[toCamelCase(propertyName)];
  if (propertyValue) {
    return propertyValue;
  }
  else {
    if (document.defaultView && document.defaultView.getComputedStyle) {
      return document.defaultView.getComputedStyle(obj, null).getPropertyValue(propertyName);
    }
    else {
      if (obj.currentStyle) {
        return obj.currentStyle[toCamelCase(propertyName)];
      }
      else {
        return null;
      }
    }
  }
}

/*
Get the integer value of the property of the object.
*/
function getPropIntVal(obj, propertyName) { // Private method
  return parseInt(getPropVal(obj, propertyName));
}

/*
Get the left position of the pop-up menu.
*/
function getMainMenuLeftPos(menuObj, x) { // Private method
  if (x + menuObj.offsetWidth <= getClientWidth()) {
    return x;
  }
  else {
    return x - menuObj.offsetWidth;
  }
}

/*
Get the top position of the pop-up menu.
*/
function getMainMenuTopPos(menuObj, y) { // Private method
//  alert("y=" + y + " menuObj.offsetHeight=" + menuObj.offsetHeight);
  if (y + menuObj.offsetHeight <= getClientHeight()) {
    return y;
  }
  else {
    return y - menuObj.offsetHeight;
  }
}

/*
Get the left position of the submenu.
*/
function getSubMenuLeftPos(menuObj, x, offset) { // Private method
  if (x + menuObj.offsetWidth - 2 <= getClientWidth()) {
    return x - 2;
  }
  else {
    return x - menuObj.offsetWidth - offset;
  }
}

/*
Get the top position of the submenu.
*/
function getSubMenuTopPos(menuObj, y, offset) { // Private method
  var top = getPropIntVal(menuObj, btw);
  var bottom = getPropIntVal(menuObj, bbw);
//  	alert("y=" + y + " top=" + top);
    if (safari) {
      return y - top;
    }
    else {
      return y;
    }
}

/*
Pop up the submenu.
*/
function popUpSubMenu(menuItemObj) { // Private method
  var parentMenuObj = menuItemObj.parent.menuObj;
  var menuObj = menuItemObj.subMenu.menuObj;
  var x;
  var y;
  if (parentMenuObj.style.position == "fixed") {
    x = parentMenuObj.offsetLeft + parentMenuObj.offsetWidth - getPropIntVal(parentMenuObj, brw);
    y = parentMenuObj.offsetTop + menuItemObj.offsetTop + getPropIntVal(parentMenuObj, btw) - getPropIntVal(menuObj, btw);
    menuObj.style.position = "absolute";
    menuObj.style.left = getSubMenuLeftPos(menuObj, x, menuItemObj.offsetWidth) + px;
    menuObj.style.top = getSubMenuTopPos(menuObj, y, menuItemObj.offsetHeight) + px;
    menuObj.style.position = "fixed";

    //MOD//
    //Display the <iframe> shim if we need to (IE6-)
    if (menuObj.shim) {
        var shim = menuObj.shim;
        shim.style.position = menuObj.style.position;
        shim.style.left = menuObj.style.left;
        shim.style.top = menuObj.style.top;
        shim.style.zIndex = menuObj.style.zIndex - 1;

        //Find the submenu width and height
        shim.style.width = menuObj.offsetWidth + "px";
        shim.style.height = menuObj.offsetHeight + "px";
    }
    //END MOD
  }
  else {
    if (parentMenuObj.mode == "static" && !ie50) {
      x = menuItemObj.offsetLeft + parentMenuObj.offsetWidth - getPropIntVal(parentMenuObj, blw) - getPropIntVal(parentMenuObj, brw) - getScrollLeft();
      y = menuItemObj.offsetTop - getPropIntVal(menuObj, btw) - getScrollTop();
      
      if (safari) {
        x += 8;
        y += getPropIntVal(menuObj, btw) + 13;
      } else {	
          x += getPropIntVal(parentMenuObj, blw);
          y += getPropIntVal(parentMenuObj, btw);
      }
      menuObj.style.left = (getSubMenuLeftPos(menuObj, x, menuItemObj.offsetWidth) + getScrollLeft()) + px;
      menuObj.style.top = (getSubMenuTopPos(menuObj, y, menuItemObj.offsetHeight) + getScrollTop()) + px;
      //MOD//
      //Display the <iframe> shim if we need to (IE6-)
      if (menuObj.shim) {
          var shim = menuObj.shim;
          shim.style.position = menuObj.style.position;
          shim.style.left = menuObj.style.left;
          shim.style.top = menuObj.style.top;
          shim.style.zIndex = menuObj.style.zIndex - 1;

          //Find the submenu width and height
          shim.style.width = menuObj.offsetWidth + "px";
          shim.style.height = menuObj.offsetHeight + "px";
      }
      //END MOD
    }
    else {
      x = parentMenuObj.offsetLeft + parentMenuObj.offsetWidth - getPropIntVal(parentMenuObj, brw) - getScrollLeft();
      y = parentMenuObj.offsetTop + menuItemObj.offsetTop + getPropIntVal(parentMenuObj, btw) - getPropIntVal(menuObj, btw) - getScrollTop();
      menuObj.style.left = (getSubMenuLeftPos(menuObj, x, menuItemObj.offsetWidth) + getScrollLeft()) + px;
      menuObj.style.top = (getSubMenuTopPos(menuObj, y, menuItemObj.offsetHeight) + getScrollTop()) + px;
	  menuObj.style.width = "183px";
      //MOD//
      //Display the <iframe> shim if we need to (IE6-)
      if (menuObj.shim) {
          var shim = menuObj.shim;
          shim.style.position = menuObj.style.position;
          shim.style.left = menuObj.style.left;
          shim.style.top = menuObj.style.top;
          shim.style.zIndex = menuObj.style.zIndex - 1;

          //Find the submenu width and height
          shim.style.width = menuObj.offsetWidth + "px";
          shim.style.height = menuObj.offsetHeight + "px";
      }
      //END MOD
    }
  }
  if (ie && menuObj.mode == "fixed") {
    menuObj.initialLeft = parseInt(menuObj.style.left) - getScrollLeft();
    menuObj.initialTop = parseInt(menuObj.style.top) - getScrollTop();
  }
  menuObj.style.visibility = "visible";

  //MOD//
  if (menuObj.shim) {
      menuObj.shim.style.display = "block";
  }
  //END MOD//
}

/*
Pop up the main menu.
*/
function popUpMainMenu(menu, e) { // Private method
  //MOD//
  //Changed the first parameter to the menu instead of the menu object to accommodate for
  //specific context menus
  menu.menuObj.style.left = (getMainMenuLeftPos(menu.menuObj, getX(e)) + getScrollLeft()) + px;
  menu.menuObj.style.top = (getMainMenuTopPos(menu.menuObj, getY(e)) + getScrollTop()) + px;
  menu.menuObj.style.zIndex = 90000;
  //END MOD//

  //MOD//
  //Show the menu's shim if there is one
  if (menu.menuObj.shim) {
      var shim = menu.menuObj.shim;
      shim.style.position = menu.menuObj.currentStyle.position;
      shim.style.left = menu.menuObj.style.left;
      shim.style.top = menu.menuObj.style.top;
      shim.style.zIndex = menu.menuObj.style.zIndex - 1;

      shim.style.height = menu.menuObj.offsetHeight + "px";
      shim.style.width = menu.menuObj.offsetWidth + "px";

      shim.style.display = "block";
  }
  //END MOD//

  var display = menu.menuObj.style.display;
  menu.menuObj.style.display = "none";
  menu.menuObj.style.visibility = "visible";
  menu.menuObj.style.display = display;
}

/*
Refresh the menu items.
*/
function refreshMenuItems(menuObj) { // Private method
  for (var i = 0, len = menuObj.childNodes.length; i < len; i++) {
    if (menuObj.childNodes[i].enabled) {
      menuObj.childNodes[i].className = menuObj.childNodes[i].itemClassName;
      if (menuObj.childNodes[i].subMenu) {
        menuObj.childNodes[i].arrowObj.className = menuObj.childNodes[i].arrowClassName;
      }
      if (menuObj.childNodes[i].iconObj) {
        menuObj.childNodes[i].iconObj.className = menuObj.childNodes[i].iconClassName;
      }
    }
  }
}

/*
Event handler that handles onmouseover event of the menu item.
*/
function menuItemOver(e) { // Private method
  //MOD//
  //all references to 'this' have been replaced with 'obj' to
  //make the function more flexible. An optional second parameter
  //contains the object to be referenced. If it does not exist,
  //'this' is assumed.
  if (arguments.length > 1) {
      obj = arguments[1];
//      alert(arguments.length);
  } else {
	  obj = this;
  }
  

  var previousItem = obj.parent.previousItem;
  if (previousItem) {
    if (previousItem.className == previousItem.itemClassNameOver) {
      previousItem.className = previousItem.itemClassName;
    }
    if (previousItem.subMenu) {
      previousItem.className = previousItem.itemClassName;
      previousItem.arrowObj.className = previousItem.arrowClassName;
      if (previousItem.iconObj) {
        previousItem.iconObj.className = previousItem.iconClassName;
      }
    }
    var menuObj = getElmId(obj.parent.menuObj.id);
    for (var i = 0, len = menuObj.childNodes.length; i < len; i++) {
      if (menuObj.childNodes[i].enabled && menuObj.childNodes[i].subMenu) {
          hideMenus(menuObj.childNodes[i].subMenu.menuObj);
      }
    }
  }
  if (obj.enabled) {
    obj.className = obj.itemClassNameOver;
    if (obj.subMenu) {
      obj.arrowObj.className = obj.arrowClassNameOver;
      popUpSubMenu(obj);
    }
    if (obj.iconObj && obj.iconClassNameOver) {
      obj.iconObj.className = obj.iconClassNameOver;
    }
  }
  obj.parent.previousItem = obj;
}

/*
Event handler that handles onclick event of the menu item.
*/
function menuItemClick(e, item) { // Private method
  //MOD//
  //allow a second parameter for more complicated
  //expressions
  var obj;
  if (arguments.length > 1) {
      obj = item;
  } else {
      obj = this;
  }

  if (obj.enabled && obj.actionOnClick) {
    var action = obj.actionOnClick;
    if (action.indexOf("link:") == 0) {
      location.href = action.substr(5);
    }
    else {
      if (action.indexOf("code:") == 0) {
        eval(action.substr(5));
      }
      else {
        location.href = action;
      }
    }
  }
  if (!e) {
    var e = window.event;
    e.cancelBubble = true;
  }
  if (e.stopPropagation) {
    e.stopPropagation();
  }
  if (obj.parent.menuObj.mode == "cursor") {
    hideCursorMenus();
  }
  if (obj.parent.menuObj.mode == "absolute" || obj.parent.menuObj.mode == "fixed") {
    hideVisibleMenus();
    if (typeof(hideMenuBarMenus) == "function") {
      hideMenuBarMenus();
    }
  }
}

/*
Event handler that handles onmouseout event of the menu item.
*/
function menuItemOut() { // Private method
  //MOD//
  //Made the function more flexible with an optional parameter
  //specifying the object to be referenced. If missing, 'this'
  //is assumed
  if (arguments.length > 0) {
      obj = arguments[0];
  } else {
      obj = this;
  }

  if (obj.enabled) {
//	  obj.enabled = false;  
    if (!(obj.subMenu && obj.subMenu.menuObj.style.visibility == "visible")) {
      obj.className = obj.itemClassName;
    }
    if (obj.subMenu) {
      if (obj.subMenu.menuObj.style.visibility == "visible") {
        obj.arrowObj.className = obj.arrowClassNameOver;
        if (obj.iconObj) {
          obj.iconObj.className = obj.iconClassNameOver;
        }
      }
    }
    else {
      if (obj.iconObj) {
        obj.iconObj.className = obj.iconClassName;
      }
    }
  }
  var e = arguments[1];
  var x = getX(e);
  var y = getY(e);
  y = y + getScrollTop(e);
  x = x + getScrollLeft(e);
  
  var visibleMenus = new Array();
  var count = 0;
  for (var i = 1; i <= menuCount; i++) {
	  var menuObj = getElmId("DOMenu" + i);
	  if(menuObj.style.visibility == "visible"){
		  visibleMenus[count] =  menuObj;
		  count ++;
	  }
  }
  count = 0; //
  for (var i = 0; i < visibleMenus.length; i++) {
	  menuObj = visibleMenus[i];
	  var len = menuObj.childNodes.length;
	  if( x >= (parseInt(menuObj.style.left) + parseInt(menuObj.style.width)) || x < parseInt(menuObj.style.left) 
			  || y < (parseInt(menuObj.style.top) ) || y > (parseInt(menuObj.style.top) + len * (13 + 2*5) )){
		  count ++;
	  }
  }
  if(count == visibleMenus.length){
//	  if(ie){
//		  window.setTimeout( 'hideVisibleMenus()', menu_delay);
//	  }else{
		  //window.setTimeout( hideVisibleMenus, menu_delay);
		  hideVisibleMenus();
//	  }
  }
}

/*
Determine whether any of the tag name/tag id pair in the filter matches the tagName/tagId pair.
*/
function findMatch(tagName, tagId, filter) { // Private method
  for (var i = 0, len = filter.length; i < len; i++) {
    var filterArray = filter[i].toLowerCase().split(".");
    if ((filterArray[0] == "*" && filterArray[1] == "*") ||
        (filterArray[0] == "*" && filterArray[1] == tagId) ||
        (filterArray[0] == tagName && filterArray[1] == "*") ||
        (filterArray[0] == tagName && filterArray[1] == tagId)) {
      return true;
    }
  }
  return false;
}

/*
Determine whether to show or hide the menu.
*/
function canShowMenu(tagName, tagId, allExcept, noneExcept) { // Private method
  if (allExcept.length > 0) {
    return (!findMatch(tagName.toLowerCase(), tagId.toLowerCase(), allExcept));
  }
  else {
    if (noneExcept.length > 0) {
      return findMatch(tagName.toLowerCase(), tagId.toLowerCase(), noneExcept);
    }
    else {
      return true;
    }
  }
}

/*
Shows/Hides the pop-up menu.
*/
function activatePopUpMenu(e) { // Private method
  //MOD//
  //Extend the function to accept an optional second parameter
  //which would contain a specific context menu to show. Of
  //course, 'e' may not be set, but we will always set it if
  //we need a specific menu
  var tempMenu;
  if (arguments.length > 1) {
      tempMenu = arguments[1];
  } else if (popUpMenuObj) {
      tempMenu = popUpMenuObj;
  } else {
      return;
  }

  var state = tempMenu.menuObj.style.visibility;
  if (state == "visible") {
    for (var i = 1; i <= menuCount; i++) {
      var menuObj = getElmId("DOMenu" + i);
      //MOD//
      //close shim if it exists
      var menuObjShim = getElmId("Shim" + menuObj.id);
      //END MOD//
      if (menuObj.mode == "cursor") {
        menuObj.style.visibility = "hidden";
        menuObj.style.left = "0px";
        menuObj.style.top = "0px";
        menuObj.initialLeft = 0;
        menuObj.initialTop = 0;

        //MOD//
        //close shim if it exists
        if (menuObjShim) {
            menuObjShim.style.display = "none";
        }
        //END MOD//

        refreshMenuItems(menuObj);
      }
    }
  }
  else {
    if (!e) {
      var e = window.event;
    }
    var targetElm = (e.target) ? e.target : e.srcElement;
    if (targetElm.nodeType == 3) {
      targetElm = targetElm.parentNode;
    }
    if (canShowMenu(targetElm.tagName, targetElm.id, tempMenu.menuObj.allExceptFilter, tempMenu.menuObj.noneExceptFilter)) {
      popUpMainMenu(tempMenu, e);
    }
  }
}

/*
Event handler that handles left click event.
*/
function leftClickHandler(e) { // Private method
  if (getX(e) > getClientWidth() || getY(e) > getClientHeight()) {
    return;
  }
  if (!e) {
    var e = window.event;
  }
  if (e.button && e.button == 2) {
    return;
  }
  hideVisibleMenus();//
  if (typeof(hideMenuBarMenus) == "function") {
    hideMenuBarMenus();
  }
  if (popUpMenuObj) {
    var state = popUpMenuObj.menuObj.style.visibility;
    if (state == "visible" && (hideValue == 0 || hideValue == 2)) {
      activatePopUpMenu(e);
    }
    if ((state == "hidden" || state == "") && (showValue == 0 || showValue == 2)) {
      activatePopUpMenu(e);
    }
  }

  //MOD//
  //let's close all the other cursor menus
  for (var i = 1; i <= menuCount; i++) {
    var menuObj = getElmId("DOMenu" + i);
    //MOD//
    //close shims if they exist
    var menuObjShim = getElmId("Shim" + menuObj.id);
    //END MOD//
    if (menuObj.mode == "cursor" && !menuObj.alwaysVisible) {
      if (popUpMenuObj && menuObj == popUpMenuObj.menuObj) {
          continue;
      }
      menuObj.style.visibility = "hidden";
      menuObj.style.left = "0px";
      menuObj.style.top = "0px";
      menuObj.initialLeft = 0;
      menuObj.initialTop = 0;

      if (menuObjShim) {
          menuObjShim.style.display = "none";
      }
    }
    if (menuObj.mode == "cursor") {
      refreshMenuItems(menuObj);
    }
  }
}

/*
Event handler that handles right click event.
*/
function rightClickHandler(e) { // Private method
  if (!e) { e = window.event; }

  if (getX(e) > getClientWidth() || getY(e) > getClientHeight()) {
    return;
  }

  //MOD//
  //An optional second parameter should specify whether we want 'this' or not
  if (arguments.length > 1) {
      obj = arguments[1];
  } else {
      obj = this;
  }

  //MOD//
  //if there is a custom menu, use it. otherwise, use the document one
  var tempMenu; var tempShowValue; var tempHideValue;
  hideCursorMenus();
  if (obj && obj.length > 1) {
      tempMenu = obj[0];
      tempShowValue = obj[1];
      if (obj.length > 2) {
          tempHideValue = obj[2];
      } else {
          tempHideValue = tempShowValue;
      }

      //let's end this chain
      if (e.stopPropagation) {
          e.stopPropagation();
          e.preventDefault();
      } else {
          e.cancelBubble = true;
          e.returnValue = false;
      }
  } else {
      if (popUpMenuObj) {
          tempMenu = popUpMenuObj;
          tempShowValue = showValue;
          tempHideValue = hideValue;
      }
      //hide all current menus
      hideVisibleMenus();
      if (typeof(hideMenuBarMenus) == "function") {
          hideMenuBarMenus();
      }
  }
  //END MOD//

  //MOD//
  //necessary to force the first 'e' parameter in activatePopUpMenu() function
  if (!e) { e = window.event; }

  if (tempMenu) {
    var state = tempMenu.menuObj.style.visibility;
    if (state == "visible" && (tempHideValue == 1 || tempHideValue == 2)) {
      activatePopUpMenu(e, tempMenu);
      return false;
    }
    if ((state == "hidden" || state == "") && (tempShowValue == 1 || tempShowValue == 2)) {
      activatePopUpMenu(e, tempMenu);
      return false;
    }
  }
}

/*
Event handler that handles scroll event.
*/
function scrollHandler() { // Private method
  for (var i = 1; i <= menuCount; i++) {
      var menuObj = getElmId("DOMenu" + i);
      if (ie && menuObj.mode == "fixed") {
        menuObj.style.left = (menuObj.initialLeft + getScrollLeft()) + px;
        menuObj.style.top = (menuObj.initialTop + getScrollTop()) + px;
      }
  }
  if (typeof(menuBarScrollHandler) == "function") {
    menuBarScrollHandler();
  }
}

/*
Show the icon before the display text.
Arguments:
className          : Required. String that specifies the CSS class selector for the icon.
classNameOver      : Optional. String that specifies the CSS class selector for the icon when
                     the cursor is over the menu item.
*/
function showMenuItemIcon() { // Public method
  var iconElm = createElm("span");
  iconElm.id = this.id + "Icon";
  iconElm.className = arguments[0];
  this.insertBefore(iconElm, this.firstChild);
  var height;
  if (ie) {
    height = getPropIntVal(iconElm, "height");
  }
  else {
    height = iconElm.offsetHeight;
  }
  iconElm.style.top = Math.floor((this.offsetHeight - height) / 2) + px;
  if (ie) {
    var left = getPropIntVal(iconElm, "left");
    if (ie55 || ie6) {
      iconElm.style.left = (left - getPropIntVal(this, "padding-left")) + px;
    }
    else {
      iconElm.style.left = left + px;
    }
  }
  this.iconClassName = iconElm.className;
  if (arguments.length > 1 && arguments[1].length > 0) {
    this.iconClassNameOver = arguments[1];
  }
  this.iconObj = iconElm;
  this.setIconClassName = function(className) { // Public method
    this.iconClassName = className;
    this.iconObj.className = this.iconClassName;
  };
  this.setIconClassNameOver = function(classNameOver) { // Public method
    this.iconClassNameOver = classNameOver;
  };
}

/*
Set the menu object that will show up when the cursor is over the menu item object.
Argument:
menuObj            : Required. Menu object that will show up when the cursor is over the
                     menu item object.
*/
function setSubMenu(menuObj) { // Public method
  var arrowElm = createElm("div");
  arrowElm.id = this.id + "Arrow";
  arrowElm.className = this.arrowClassName;
  this.appendChild(arrowElm);
  var height;
  if (ie) {
    height = getPropIntVal(arrowElm, "height");
  }
  else {
    height = arrowElm.offsetHeight;
  }
  arrowElm.style.top = Math.floor((this.offsetHeight - height) / 2) + px;
  this.subMenu = menuObj;
  this.arrowObj = arrowElm;
  this.setArrowClassName = function(className) { // Public method
    this.arrowClassName = className;
    this.arrowObj.className = this.arrowClassName;
  };
  this.setArrowClassNameOver = function(classNameOver) { // Public method
    this.arrowClassNameOver = classNameOver;
  };
  menuObj.menuObj.style.zIndex = this.parent.menuObj.level + 1;
  menuObj.menuObj.level = this.parent.menuObj.level + 1;
}

//MOD//
/*
Create a new shim
Argument:
menuObj            : Required. Menu object that is going to have a shim
*/
function createShim(menuObj) {
    var shim = createElm("iframe");
    shim.id = "Shim" + menuObj.id;
    shim.frameborder = "0";
    shim.scrolling = "no";
    shim.style.zIndex = menuObj.style.zIndex - 1;
    shim.style.display = "none";
    document.body.appendChild(shim);

    //assign the iframe to the menu
    menuObj.shim = shim;
}


/*
Add a new menu item to the menu.
Argument:
menuItemObj        : Required. Menu item object that is going to be added to the menu object.
*/
function addMenuItem(menuItemObj) { // Public method
  if (menuItemObj.displayText == "-") {
    var hrElm = createElm("hr");
    var itemElm = createElm("div");
    itemElm.appendChild(hrElm);
    itemElm.id = menuItemObj.id;
    if (menuItemObj.className.length > 0) {
      itemElm.sepClassName = menuItemObj.className;
    }
    else {
      itemElm.sepClassName = menuItemObj.sepClassName;
    }
    itemElm.className = itemElm.sepClassName;
    this.menuObj.appendChild(itemElm);
    itemElm.parent = this;
    itemElm.setClassName = function(className) { // Public method
      this.sepClassName = className;
      this.className = this.sepClassName;
    };
    itemElm.onclick = function(e) { // Private method
      if (!e) {
        var e = window.event;
        e.cancelBubble = true;
      }
      if (e.stopPropagation) {
        e.stopPropagation();
      }
    };
    itemElm.onmouseover = menuItemOver;
    if (menuItemObj.itemName.length > 0) {
      this.items[menuItemObj.itemName] = itemElm;
    }
    else {
      this.items[this.items.length] = itemElm;
    }
  }
  else {
    var itemElm = createElm("div");
    itemElm.id = menuItemObj.id;
    itemElm.actionOnClick = menuItemObj.actionOnClick;
    itemElm.enabled = menuItemObj.enabled;
    itemElm.itemClassName = menuItemObj.className;
    itemElm.itemClassNameOver = menuItemObj.classNameOver;
    itemElm.className = itemElm.itemClassName;
    itemElm.subMenu = null;
    itemElm.arrowClassName = arrowClassName;
    itemElm.arrowClassNameOver = arrowClassNameOver;
    var textNode = document.createTextNode(menuItemObj.displayText);
    itemElm.appendChild(textNode);
    this.menuObj.appendChild(itemElm);
    itemElm.parent = this;
    itemElm.setClassName = function(className) { // Public method
      this.itemClassName = className;
      this.className = this.itemClassName;
    };
    itemElm.setClassNameOver = function(classNameOver) { // Public method
      this.itemClassNameOver = classNameOver;
    };
    itemElm.setDisplayText = function(text) { // Public method
      if (this.childNodes[0].nodeType == 3) {
        this.childNodes[0].nodeValue = text;
      }
      else {
        this.childNodes[1].nodeValue = text;
      }
    };
    itemElm.setSubMenu = setSubMenu;
    itemElm.showIcon = showMenuItemIcon;

    //MOD//
    //do not assign events in the traditional way. We make it more
    //flexible by assigning an anonymous function. The functions
    //for the original menu item status (ie. hover, out, etc.) need
    //to be changed to have a reference to 'this'
    itemElm.onmouseover = function(e) {
        if (!e) { e = window.event; }

        //original function with added 'this' parameter
        menuItemOver(e, this);

        //show the tooltip if there is one
        if (menuItemObj.tooltip.length > 0 && window.showTooltip) {
            showTooltip(e, menuItemObj.tooltip);
        }

        //show a status bar message if there is one
        if (menuItemObj.statusMessage.length > 0) {
            window.status = menuItemObj.statusMessage;
        }
    };
    itemElm.onmouseout = function(e) {
        //hide the tooltip if it exists
        if (menuItemObj.tooltip.length > 0 && window.hideTooltip) {
            hideTooltip();
        }

        //erase status bar message if one exists
        if (menuItemObj.statusMessage.length > 0) {
            if (window.defaultStatus && window.defaultStatus.length > 0) {
                window.status = window.defaultStatus;
            } else {
                window.status = '';
            }
        }

        //original function with added 'this' parameter
        menuItemOut(this,e);
    };

    //MOD//
    //set the specific context menu if there is one
    if (typeof(menuItemObj.contextMenu) != "boolean" && menuItemObj.contextMenu.length > 1) {
        itemElm.oncontextmenu = function(e) {
            if (!e) { e = window.event; }

            for (var i = 0; i < menuItemObj.contextMenu[0].items.length; i++) {
                menuItemObj.contextMenu[0].items[i].par = menuItemObj;
            }

            rightClickHandler(e, menuItemObj.contextMenu);
        };
    }

    //MOD//
    //give the menu extra click functions if we need them (for JS effects)
    if (menuItemObj.click) {
        itemElm.onclick = function(e) {
            if (!e) { e = window.event; }

            //return false
            if (e.returnValue) { e.returnValue = false; }
            else if (e.preventDefault) { e.preventDefault(); e.stopPropagation(); }

            if (this.enabled) {
                //let's currently disable the action!
                this.enabled = false;
                menuItemClick(e, this);
                this.enabled = true;

                menuItemObj.click(this, e);
            }
        }
    } else {
        itemElm.onclick = menuItemClick;
    }
    if (menuItemObj.itemName.length > 0) {
      this.items[menuItemObj.itemName] = itemElm;
    }
    else {
      this.items[this.items.length] = itemElm;
    }
  }
}

/*
Create a new menu item object.
Arguments:
displayText        : Required. String that specifies the text to be displayed on the menu item. If
                     displayText = "-", a menu separator will be created instead.
itemName           : Optional. String that specifies the name of the menu item. Defaults to "" (no
                     name).
actionOnClick      : Optional. String that specifies the action to be done when the menu item is
                     being clicked. Defaults to "" (no action).
enabled            : Optional. Boolean that specifies whether the menu item is enabled/disabled.
                     Defaults to true.
className          : Optional. String that specifies the CSS class selector for the menu item.
                     Defaults to "jsdomenuitem".
classNameOver      : Optional. String that specifies the CSS class selector for the menu item when
                     the cursor is over it. Defaults to "jsdomenuitemover".
*/
function menuItem() { // Public method
  //MOD//
  //set some new defaults
  this.par = false; //parent
  this.tooltip = '';
  this.statusMessage = '';
  this.contextMenu = false;
  this.click = false;

  this.displayText = arguments[0];
  if (this.displayText == "-") {
    this.id = "menuSep" + (++sepCount);
    this.className = sepClassName;
  }
  else {
    this.id = "menuItem" + (++menuItemCount);
    this.className = menuItemClassName;
  }
  this.itemName = "";
  this.actionOnClick = "";
  this.enabled = true;
  this.classNameOver = menuItemClassNameOver;
  this.sepClassName = sepClassName;
  var len = arguments.length;
  if (len > 1 && arguments[1].length > 0) {
    this.itemName = arguments[1];
  }
  if (len > 2 && arguments[2].length > 0) {
    this.actionOnClick = arguments[2];
  }
  if (len > 3 && typeof(arguments[3]) == "boolean") {
    this.enabled = arguments[3];
  }
  if (len > 4 && arguments[4].length > 0) {
    if (arguments[4] == "-") {
      this.className = arguments[4];
      this.sepClassName = arguments[4];
    }
    else {
      this.className = arguments[4];
    }
  }
  if (len > 5 && arguments[5].length > 0) {
    this.classNameOver = arguments[5];
  }
}

/*
Create a new menu object.
Arguments:
width              : Required. Integer that specifies the width of the menu.
mode               : Optional. String that specifies the mode of the menu. Defaults to "cursor".
id                 : Optional, except when mode = "static". String that specifies the id of
                     the element that will contain the menu. This argument is required when
                     mode = "static".
alwaysVisible      : Optional. Boolean that specifies whether the menu is always visible. Defaults
                     to false.
className          : Optional. String that specifies the CSS class selector for the menu. Defaults
                     to "jsdomenudiv".
*/
function jsDOMenu() { // Public method
  this.items = new Array();
  var menuElm;
  var len = arguments.length;
  if (len > 2 && arguments[2].length > 0 && arguments[1] == "static") {
    menuElm = getElmId(arguments[2]);
    if (!menuElm) {
      return;
    }
    staticMenuId[staticMenuId.length] = arguments[2];
  }
  else {
    menuElm = createElm("div");
    menuElm.id = "DOMenu" + (++menuCount);
  }
  menuElm.level = 10;
  menuElm.previousItem = null;
  menuElm.allExceptFilter = allExceptFilter;
  menuElm.noneExceptFilter = noneExceptFilter;
  menuElm.className = menuClassName;
  menuElm.mode = menuMode;
  menuElm.alwaysVisible = false;
  menuElm.initialLeft = 0;
  menuElm.initialTop = 0;
  if (len > 1 && arguments[1].length > 0) {
    switch (arguments[1]) {
      case "cursor":
        menuElm.style.position = "absolute";
        menuMode.mode = "cursor";
        break;
      case "absolute":
        menuElm.style.position = "absolute";
        menuElm.mode = "absolute";
        break;
      case "fixed":
        if (ie) {
          menuElm.style.position = "absolute";
        }
        else {
          menuElm.style.position = "fixed";
        }
        menuElm.mode = "fixed";
        break;
      case "static":
        menuElm.style.position = "static";
        menuElm.mode = "static";
        break;
    }
  }
  if (len > 3 && typeof(arguments[3]) == "boolean") {
    menuElm.alwaysVisible = arguments[3];
  }
  if (len > 4 && arguments[4].length > 0) {
    menuElm.className = arguments[4];
  }
  
  menuElm.style.width = arguments[0] + px;
  menuElm.style.width = '183' + px;
  menuElm.style.left = "0px";
  menuElm.style.top = "0px";
  if (menuElm.mode != "static") {
    document.body.appendChild(menuElm);
  }
  if (!getPropVal(menuElm, blw)) {
    menuElm.style.borderWidth = menuBorderWidth + px;
  }
  this.menuObj = menuElm;
  this.addMenuItem = addMenuItem;
  this.setClassName = function(className) { // Public method
    this.menuObj.className = className;
  };
  this.setMode = function(mode) { // Public method
    switch (mode) {
      case "cursor":
        this.menuObj.style.position = "absolute";
        this.menuObj.mode = "cursor";
        break;
      case "absolute":
        this.menuObj.style.position = "absolute";
        this.menuObj.mode = "absolute";
        this.menuObj.initialLeft = parseInt(this.menuObj.style.left);
        this.menuObj.initialTop = parseInt(this.menuObj.style.top);
        break;
      case "fixed":
        if (ie) {
          this.menuObj.style.position = "absolute";
          this.menuObj.initialLeft = parseInt(this.menuObj.style.left);
          this.menuObj.initialTop = parseInt(this.menuObj.style.top);
        }
        else {
          this.menuObj.style.position = "fixed";
        }
        this.menuObj.mode = "fixed";
        break;
    }
  };
  this.setAlwaysVisible = function(alwaysVisible) { // Public method
    if (typeof(alwaysVisible) == "boolean") {
      this.menuObj.alwaysVisible = alwaysVisible;
    }
  };
  this.show = function() { // Public method
    this.menuObj.style.visibility = "visible";
  };
  this.hide = function() { // Public method
    this.menuObj.style.visibility = "hidden";
    if (this.menuObj.mode == "cursor") {
      this.menuObj.style.left = "0px";
      this.menuObj.style.top = "0px";
      this.menuObj.initialLeft = 0;
      this.menuObj.initialTop = 0;
    }
  };
  this.setX = function(x) { // Public method
    this.menuObj.initialLeft = x;
    this.menuObj.style.left = x + px;
  };
  this.setY = function(y) { // Public method
    this.menuObj.initialTop = y;
    this.menuObj.style.top = y + px;
  };
  this.moveTo = function(x, y) { // Public method
    this.menuObj.initialLeft = x;
    this.menuObj.initialTop = y;
    this.menuObj.style.left = x + px;
    this.menuObj.style.top = y + px;
  };
  this.moveBy = function(x, y) { // Public method
    var left = parseInt(this.menuObj.style.left);
    var top = parseInt(this.menuObj.style.top);
    this.menuObj.initialLeft = left + x;
    this.menuObj.initialTop = top + y;
    this.menuObj.style.left = (left + x) + px;
    this.menuObj.style.top = (top + y) + px;
  };
  this.setAllExceptFilter = function(filter) { // Public method
    this.menuObj.allExceptFilter = filter;
    this.menuObj.noneExceptFilter = new Array();
  };
  this.setNoneExceptFilter = function(filter) { // Public method
    this.menuObj.noneExceptFilter = filter;
    this.menuObj.allExceptFilter = new Array();
  };
  this.setBorderWidth = function(width) { // Public method
    this.menuObj.style.borderWidth = width + px;
  };

  //MOD//
  //set shims if needed
  if (ie) {
      createShim(this.menuObj);
  }
  //END MOD//
}

/*
Specifies how the pop-up menu shows/hide.
Arguments:
showValue          : Required. Integer that specifies how the menu shows.
hideValue          : Optional. Integer that specifies how the menu hides. If not specified, the
                     menu shows/hides in the same manner.

0: Shows/Hides the menu by left click only.
1: Shows/Hides the menu by right click only.
2: Shows/Hides the menu by left or right click.
*/
function activatePopUpMenuBy() { // Public method
  showValue = typeof(arguments[0]) == "number" && arguments[0] > -1 ? arguments[0] : 0;
  if (arguments.length > 1) {
    hideValue = typeof(arguments[1]) == "number" && arguments[1] > -1 ? arguments[1] : 0;
  }
  else {
    hideValue = showValue;
  }
  if (showValue == 1 || showValue == 2 || hideValue == 1 || hideValue == 2) {
    document.oncontextmenu = rightClickHandler;
  }
}

/*
Hide all menus, except those with alwaysVisible = true.
*/
function hideAllMenus() { // Public method
  for (var i = 1; i <= menuCount; i++) {
    var menuObj = getElmId("DOMenu" + i);
    //MOD//
    //get shim menu if it exists
    var menuObjShim = getElmId("Shim" + menuObj.id);
    //END MOD//
    if (!menuObj.alwaysVisible) {
      if (menuObj.style.position == "fixed") {
        menuObj.style.position == "absolute";
        menuObj.style.visibility = "hidden";
        menuObj.style.position == "fixed";
      }
      else {
        menuObj.style.visibility = "hidden";
        if (menuObj.mode == "cursor") {
          menuObj.style.left = "0px";
          menuObj.style.top = "0px";
          menuObj.initialLeft = 0;
          menuObj.initialTop = 0;
        }
      }

      //MOD//
      //close shims if they exist
      if (menuObjShim) {
          menuObjShim.style.display = "none";
      }
      //END MOD//
    }
    refreshMenuItems(menuObj);
  }
  for (var i = 0, len = staticMenuId.length; i < len; i++) {
    refreshMenuItems(getElmId(staticMenuId[i]));
  }
}

/*
Hide all menus with mode = "cursor", except those with alwaysVisible = true.
*/
function hideCursorMenus() { // Public method
  for (var i = 1; i <= menuCount; i++) {
    var menuObj = getElmId("DOMenu" + i);
    //MOD//
    //get shim if it exists
    var menuObjShim = getElmId("Shim" + menuObj.id);
    //END MOD//
    if (menuObj.mode == "cursor" && !menuObj.alwaysVisible) {
      menuObj.par = false;
      menuObj.style.visibility = "hidden";
      menuObj.style.left = "0px";
      menuObj.style.top = "0px";
      menuObj.initialLeft = 0;
      menuObj.initialTop = 0;

      //MOD//
      //close shims
      if (menuObjShim) {
          menuObjShim.style.display = "none";
      }
    }
    if (menuObj.mode == "cursor") {
      refreshMenuItems(menuObj);
    }
  }
}

/*
Hide all menus with mode = "absolute" or mode = "fixed" or mode = "static", except those with
alwaysVisible = true.
*/
function hideVisibleMenus() { // Public method
  for (var i = 1; i <= menuCount; i++) {
    var menuObj = getElmId("DOMenu" + i);
    //MOD//
    //close shims if they exist
    var menuObjShim = getElmId("Shim" + menuObj.id);
    //END MOD//
    if ((menuObj.mode == "absolute" || menuObj.mode == "fixed") && !menuObj.alwaysVisible) {
      if (menuObj.style.position == "fixed") {
        menuObj.style.position = "absolute";
        menuObj.style.visibility = "hidden";
        menuObj.style.position = "fixed";
      }
      else {
        menuObj.style.visibility = "hidden";
        menuObj.style.left = "0px";
        menuObj.style.top = "0px";
        menuObj.initialLeft = 0;
        menuObj.initialTop = 0;
      }

      //MOD//
      //close shims if they exist
      if (menuObjShim) {
          menuObjShim.style.display = "none";
      }
      //END MOD//
    }
    if (menuObj.mode == "absolute" || menuObj.mode == "fixed") {
      refreshMenuItems(menuObj);
    }
  }
  for (var i = 0, len = staticMenuId.length; i < len; i++) {
	  refreshMenuItems(getElmId(staticMenuId[i]));
  }
  if (typeof(staticMenuBarId) == "object") {
    for (var i = 0, len = staticMenuBarId.length; i < len; i++) {
      refreshMenuBarItems(getElmId(staticMenuBarId[i]));
    }
  }
}

/*
Hide the menu and all its submenus.
Argument:
menuObj            : Required. Menu object that specifies the menu and all its submenus to
                     be hidden.
*/
function hideMenus(menuObj) { // Public method
  refreshMenuItems(menuObj);
  for (var i = 0, len = menuObj.childNodes.length; i < len; i++) {
    if (menuObj.childNodes[i].enabled && menuObj.childNodes[i].subMenu) {
      hideMenus(menuObj.childNodes[i].subMenu.menuObj);
    }
  }
  if (menuObj.style.position == "fixed") {
    menuObj.style.position = "absolute";
    menuObj.style.visibility = "hidden";
    menuObj.style.position = "fixed";
  }
  else {
    menuObj.style.visibility = "hidden";
    menuObj.style.left = "0px";
    menuObj.style.top = "0px";
    menuObj.initialLeft = 0;
    menuObj.initialTop = 0;
  }

  //MOD//
  //If there is a shim for the menu, close it
  if (menuObj.shim) {
      menuObj.shim.style.display = "none";
  }
  //END MOD//
}

/*
Set the menu object to be the pop-up menu.
Argument:
menuObj            : Required. Menu object that specifies the pop-up menu.
*/
function setPopUpMenu(menuObj) { // Public method
  popUpMenuObj = menuObj;
}
/*
Check browser compatibility and create the menus.
*/
function initjsDOMenu() { // Public method
  if (document.createElement && document.getElementById) {
    createjsDOMenu();
  }
}

if (typeof(allExceptFilter) == "undefined") {
  var allExceptFilter = new Array("A.*",
                                  "BUTTON.*",
                                  "IMG.*",
                                  "INPUT.*",
                                  "OBJECT.*",
                                  "OPTION.*",
                                  "SELECT.*",
                                  "TEXTAREA.*"); // Public field
}

if (typeof(noneExceptFilter) == "undefined") {
  var noneExceptFilter = new Array(); // Public field
}

if (typeof(menuClassName) == "undefined") {
  var menuClassName = "jsdomenudiv"; // Public field
}

if (typeof(menuItemClassName) == "undefined") {
  var menuItemClassName = "jsdomenuitem"; // Public field
}

if (typeof(menuItemClassNameOver) == "undefined") {
  var menuItemClassNameOver = "jsdomenuitemover"; // Public field
}

if (typeof(sepClassName) == "undefined") {
  var sepClassName = "jsdomenusep"; // Public field
}

if (typeof(arrowClassName) == "undefined") {
  var arrowClassName = "jsdomenuarrow"; // Public field
}

if (typeof(arrowClassNameOver) == "undefined") {
  var arrowClassNameOver = "jsdomenuarrowover"; // Public field
}

if (typeof(menuMode == "undefined")) {
  var menuMode = "cursor"; // Public field
}

if (typeof(menuBorderWidth) == "undefined") {
  var menuBorderWidth = 2; // Public field
}

var ie50 = isIE50(); // Private field
var ie55 = isIE55(); // Private field
var ie5 = isIE5(); // Private field
var ie6 = isIE6(); // Private field
var ie7 = isIE7();
var ie = isIE(); // Private field
var opera = isOpera(); // Private field
var safari = isSafari(); // Private field
var pageMode = getPageMode(); // Private field
var px = "px"; // Private field
var btw = "border-top-width"; // Private field
var bbw = "border-bottom-width"; // Private field
var blw = "border-left-width"; // Private field
var brw = "border-right-width"; // Private field
var menuCount = 0; // Private field
var menuItemCount = 0; // Private field
var sepCount = 0; // Private field
var popUpMenuObj = null; // Private field
var showValue = 0; // Private field
var hideValue = 0; // Private field
var staticMenuId = new Array(); // Private field

document.onclick = leftClickHandler;
window.onscroll = scrollHandler;
//MOD//
document.oncontextmenu = rightClickHandler;
