/* Filename:    MenuLib.js  */

var PPDIMAGEDIR  = "/images/"
var debugFlag    = false;
var oBrowser     = null;

var aTopImages   = new Array;
var aTopPreload  = new Array("tb2", "tn2", "tn3", "tn4", "tn5", "tn6",
			     "tn7", "tn8", "tn9", "tn10");

var iPASSWD_MIN  = 6;

/* Function:    BrowserType()
   Description: Determines if the browser is CSS- and W3C-compatible, setting
                the global object "oBrowser" when a function needs it.  This
		should only be called after the body has been loaded.
*/
function BrowserType () {
  if (document.images) {
    this.bCSS = (document.body && document.body.style) ? true : false;
    this.bW3C = (this.bCSS && document.getElementById) ? true : false;
    this.bIE4 = (this.bCSS && document.all)            ? true : false;
    this.bNN4 = (document.layers)                      ? true : false;
  }
}

function nullFcn() { }

/* Functions: 	findObj(), restoreImages(), swapImages(), swapImagesArray()
   Description: Low-level object functions, used to find and replace images.
*/
function findObj (obj) {
  if (oBrowser == null) { oBrowser = new BrowserType(); }
  var oFound = null;

  // Searching by name - search according to browser type
  if (typeof obj == "string") {
    if      (oBrowser.bW3C) {
      oFound = document.getElementById(obj);
      if (oFound == null) {
	var aAllNames = document.getElementsByName(obj);
	if (aAllNames != null) { oFound = aAllNames[0]; }
      }
    }
    else if (oBrowser.bIE4) { oFound = document.all(obj);            }
    else if (oBrowser.bNN4) { 
      for (var i = 0, oFound = eval("document." + obj);
	   oFound == null && document.layers && i < document.layers.length; i++){
        oFound = eval("document.layers[" + i + "].document." + obj);
      }
    }
    if (!oFound && debugFlag) { alert("Unable to find '" + obj + "'"); }
  }

  // Object already defined
  else { oFound = obj; }
  return oFound;
}

function buttonImage (replaceName, imgSrc, x, y) {
  this.image = new Image(x, y);
  this.image.src = imgSrc;
  this.replaceName = replaceName;
}

function clearMenu () {
  restoreImages();
  window.status = "";
  return true;
}

function restoreImages () {
  var i, x, a = document.imagesToRestore;
  for (i = 0; a != null && i < a.length && (x = a[i]) && x.oSrc; i++)
    x.src = x.oSrc;
  document.imagesToRestore = null;
}

function swapImages () { 
  var i, j, x, a = swapImages.arguments;
  document.imagesToRestore = new Array;

  for (i = 0, j = 0; i < (a.length - 1); i += 2)
    if ((x = findObj(a[i])) != null) {
      document.imagesToRestore[j++] = x;
      if (x.oSrc == null) x.oSrc = x.src;
      x.src = a[i+1];
    }
}

function sleep (n) {
  while (n > 0) { --n; }
}

function preLoadImages () {
  if (aTopImages.length > 0) { return; }

  var i;
  for (i = 0; i < aTopPreload.length; i++) {
    aTopImages[i]  = new Image;
    aTopImages[i].src = PPDIMAGEDIR + "top/" + aTopPreload[i] + "o.gif";
  }
}

function LeftNavEvent (oAnchor) {
  oTableCell = oAnchor.parentNode ? oAnchor.parentNode : oAnchor.parentElement;
  if (!oTableCell) { return false; }
  switch(oTableCell.className) {
  case "LeftNav":            sClass = "LeftNavMouseOver";   break;
  case "LeftNavMouseOver":   sClass = "LeftNav";            break;
  default: return false;
  }
  if (oTableCell.getElementsByTagName) {
    aDivs = oTableCell.getElementsByTagName("div");
    if (aDivs.length) { aDivs[0].className = sClass; }
  }
  oTableCell.className = sClass;
  return true;
}

function GetCssAttribute (sStyleName, sProperty) {

  // Lower case search
  sStyleName = sStyleName.toLowerCase();

  // Search through all possible sheets for this style name
  var oStyle = null;
  for (n = 0; n < document.styleSheets.length; n++) {

    var oSheet = document.styleSheets[n];
    var aRules = oSheet.rules ? oSheet.rules : oSheet.cssRules;
    for (i = 0; i < aRules.length && oStyle == null; i++) {
      if (aRules[i].selectorText.toLowerCase() == sStyleName) {
	oStyle = aRules[i].style;
      }
    }
  }
  if (oStyle) { return eval("oStyle." + sProperty); }
  return null;
}

function Menu (label, menuWidth, menuItemHeight, menuItemPadding,
	       menuItemSpacing, menuBorder, hideTimeout,
	       submenuXOffset, submenuYOffset, submenuRelativeToItem,
	       menuBgOpaque, vertical, menuItemIndent) {

  this.menuWidth             = menuWidth;
  this.menuItemHeight        = menuItemHeight;

  this.menuItemBorder        = 1;
  this.menuItemIndent        = menuItemIndent;

  this.menuBorder            = menuBorder;
  this.menuBgOpaque          = menuBgOpaque;

  sPixels                    = GetCssAttribute("div.menuItemText", "fontSize");
  if (sPixels && sPixels.search("px")) {
    this.fontSize = parseInt(sPixels.replace("px", ""));
  } else {
    this.fontSize = 10;
  }
    
  this.bgColor               = GetCssAttribute("div.menuLayer", 
					       "backgroundColor");
  this.menuLiteBgColor       = GetCssAttribute("div.menuItemHilite",
					       "backgroundColor");
  this.menuItemVAlign        = GetCssAttribute("div.menuItemText", 
					       "verticalAlign");
  this.menuItemHAlign        = GetCssAttribute("div.menuItemText", 
					       "textAlign");
  this.menuBorderBgColor     = GetCssAttribute("div.menuLayer", 
					       "color");

  // Things that should be in the stylesheet
  this.menuHiliteBgColor     = this.menuLiteBgColor;
  this.menuContainerBgColor  = "#cccccc";
  this.menuItemPadding       = menuItemPadding;
  this.menuItemSpacing       = menuItemSpacing;

  this.childMenuIcon         = "arrows.gif";
  this.submenuXOffset        = submenuXOffset;
  this.submenuYOffset        = submenuYOffset;
  this.submenuRelativeToItem = submenuRelativeToItem;
  this.vertical              = vertical;
  this.items                 = new Array();
  this.actions               = new Array();
  this.targets               = new Array();
  this.columns               = new Array();
  this.childMenus            = new Array();
  this.hideOnMouseOut        = true;
  this.hideTimeout           = hideTimeout;
  this.addMenuItem           = addMenuItem;
  this.writeMenus            = writeMenus;
  this.MM_showMenu           = MM_showMenu;
  this.onMenuItemOver        = onMenuItemOver;
  this.onMenuItemAction      = onMenuItemAction;
  this.hideMenu              = hideMenu;
  this.hideChildMenu         = hideChildMenu;
  this.label                 = " " + label;

  // Add two menu arrays to the window object (if not already added)
  if (!window.menus)       { window.menus = new Array();       }
  if (!window.activeMenus) { window.activeMenus = new Array(); }

  // Add this object to menu array, both by name and simple index
  window.menus[this.label]          = this;
  window.menus[window.menus.length] = this;
}

function addMenuItem (label, action, target, column) {
  this.items[this.items.length]     = label;
  this.actions[this.actions.length] = action;
  this.targets[this.targets.length] = target;
  this.columns[this.columns.length] = (column > 1) ? column : 1;
}

function writeMenus(container) {

  // Get the complete user agent string and browser type
  var sAgent = navigator.userAgent.toLowerCase();
  if (oBrowser == null) { oBrowser = new BrowserType(); }

  // Stop if attempted already, in layers or unsupported browser 
  if (window.triedToWriteMenus || document.layers ||
      !oBrowser.bW3C || sAgent.indexOf("opera") != -1) { return false; }

  // Start the container - stop if not found
  document.writeln('<span id="menuContainer"></span>');
  if (!(oContainer = findObj("menuContainer"))) { return false; }
    
  // Clear the timer, set attempt flag, and fill container, clearing window
  window.mmHideMenuTimer   = null;
  window.triedToWriteMenus = true; 
  oContainer.menus = new Array();
  for (var i = 0; i < window.menus.length; i++) {
    oContainer.menus[i] = window.menus[i];
  }
  window.menus.length = 0;

  // Initialize item count and the new content
  var iItemCount = 0;
  var sContent   = "";

  // Loop through each of the menus
  for (var iMenu = 0; iMenu < oContainer.menus.length; iMenu++) {

    // Get the current menu object
    var oMenu = oContainer.menus[iMenu];

    // Image or opaque - eliminate the border
    if (oMenu.bgImageUp || !oMenu.menuBgOpaque) {
      oMenu.menuBorder     = 0;
      oMenu.menuItemBorder = 0;
    }

    // Add the top-level divisions
    sContent += '<div id="menuLayer'+ iMenu +
      '" style="position:absolute;z-index:1;left:10px;top:' + (iMenu * 100) +
      'px;visibility:hidden;">\n'+
      '  <div id="menuLite' + iMenu +
      '" style="position:absolute;z-index:1;left:' + oMenu.menuBorder +
      'px;top:'+ oMenu.menuBorder +
      'px;visibility:hide;" onmouseout="mouseoutMenu();">\n'+
      '	 <div id="menuFg'+ iMenu +
      '" style="position:absolute;left:' + oMenu.menuBorder +
      'px;top:'+ oMenu.menuBorder +'px;visibility:hide;">\n';

    // Add each of the menu items
    for (var iItem = 0, iVerticalPos = 0; iItem < oMenu.items.length; iItem++) {

      var sItem = oMenu.items[iItem];
      var bChildMenu = false;
      var iDefaultHeight = oMenu.fontSize+2*oMenu.menuItemPadding;
      if (sItem.label) {
	sItem = sItem.label;
	bChildMenu = true;
      }
      oMenu.menuItemHeight = oMenu.menuItemHeight || iDefaultHeight;

      // IE7 requires white-space attribute to avoid cutoff of words
      var sItemProps = 'white-space:nowrap;';

      // Initialize item property and position
      var sMouseOver = 'onmouseover="onMenuItemOver(null,this)"';
      var iItemLeft, iItemTop;

      // Vertical menus - adjust for column position
      if (oMenu.vertical) {
	var iColumn = oMenu.columns[iItem];
	iItemTop = iVerticalPos * oMenu.menuItemHeight;
	if (iColumn == 1) { iItemLeft = 0;  ++iVerticalPos;              }
	else              { iItemLeft = (iColumn - 1) * oMenu.menuWidth; }
      }
      
      // Horizontal menus
      else {
	iItemLeft = iItem * oMenu.menuWidth;
	iItemTop = 0;
      }

      // Get the current action and target
      var sAction = oMenu.actions[iItem];
      var sTarget = oMenu.targets[iItem];

      // Start the anchor division with current action
      var sAnchorDiv      = '<a class="menuItem" href="' + sAction + '"';
      var sAnchorDivClose = '</a>';

      // Target needed - add target and close anchor, otherwise close anchor
      if (sTarget) { sAnchorDiv += (' sTarget="' + sTarget + '">' ); }
      else         { sAnchorDiv += '>';                              }
 
      // Create the top-level division that positions the item 
      var sPosDiv, sPosDivClose = '</div>';
      if (oMenu.bgImageUp) {
	sPosDiv = '<div class="menuItem" id="menuItem'+ iItemCount +
	  '" style="background:url(' + oMenu.bgImageUp +
	  ');position:absolute;left:' + iItemLeft + 'px;top:' + iItemTop +
	  'px;' + sItemProps + '" ' + sMouseOver + '>';
      } else {
	sPosDiv = '<div class="menuItem" id="menuItem' + iItemCount +
	  '" style="position:absolute;left:' + iItemLeft + 'px;top:' +
	  iItemTop + 'px;' + sItemProps + '" ' + sMouseOver + '>';
      }

      // Determine position of the text
      var iLeftPos = 0, iTopPos = 0;
      iLeftPos = 1 + oMenu.menuItemPadding + oMenu.menuItemIndent;
      switch (oMenu.menuItemVAlign) {
      case "top":    iTopPos = oMenu.menuItemPadding; break;
      case "bottom": iTopPos = oMenu.menuItemHeight - oMenu.fontSize - 1 -
		       oMenu.menuItemPadding; break;
      case "middle": iTopPos = (oMenu.menuItemHeight / 2) -
		       (oMenu.fontSize / 2) - 1; break;
      }
      var sTextPosition = 'position:absolute;left:' + iLeftPos + 'px;top:' +
	iTopPos + 'px;';

      // Create the two internal divisions
      var sSubDivision = '<div id="menuItemShim' + iItemCount +
	'" style="position:absolute;left:0px;top:0px;">' +
	'<div align="' + oMenu.menuItemHAlign + '">' + sItem + '</div></div>';

      // Create the main division
      var sDivision = '<div class="menuItemText" id="menuItemText' + iItemCount+
	'" style="' + sTextPosition +';">' + sSubDivision + '&nbsp</div>' +
	'<div class="menuItemHilite" id="menuItemHilite' + iItemCount +
	'" style="' + sTextPosition + 'visibility:hidden;">' + sSubDivision +
	'&nbsp</div>';


      // Create the final division and add to content
      var sFinalDiv;
      if (bChildMenu) {
	sFinalDiv = sAnchorDiv + sPosDiv + sDivision + '<div id="childMenu' +
	  iItemCount + '" style="position:absolute;left:0px;top:3px;">' +
	  '<img src="../old/' + oMenu.childMenuIcon + '"></div>\n' + sPosDivClose +
	  sAnchorDivClose;
      } else {
	sFinalDiv = sAnchorDiv + sPosDiv + sDivision + sPosDivClose +
	  sAnchorDivClose;
      }
      sContent += sFinalDiv;

      // Increment the complete item count
      iItemCount++;  
    }

    // Add the focus division and closing tags
    sContent += '	  <div id="focusItem' + iMenu +
      '" style="position:absolute;left:0px;top:0px;visibility:hide;" ' +
      'onclick="onMenuItemAction(null,this);"> </div>\n ' +
      '   </div>\n  </div>\n</div>\n';
  }

  // Write out the HTML
  document.open("text/html");
  document.writeln(sContent);
  document.close(); 

  /* View the code
    var debug_win = window.open("", "Example1");
    debug_win.document.open("text/html");
    debug_win.document.writeln(sContent);
    debug_win.document.close();
    */

  // Unable to find the base layer - HTML write failed - stop now
  if (!findObj("menuLayer0")) return false;

  // Initialize item count and the new content
  var iItemCount = 0;

  // Loop through each of the menus
  for (var iMenu = 0; iMenu < oContainer.menus.length; iMenu++) {

    // Get the current menu layer and menu object
    var sMenuLayer = "menuLayer" + iMenu;
    var oMenuLayer = findObj(sMenuLayer);
    var oMenu      = oContainer.menus[iMenu];

    // Set layer and item layers in menu object, and menu object in main layer
    oMenu.menuLayer           = sMenuLayer;
    oMenuLayer.Menu           = oMenu;
    oMenu.menuItemLayers      = new Array();
    oMenuLayer.Menu.container = "menuLayer" + iMenu;

    // Set the z-index and starting positions (will be reset below)
    oMenuLayer.style.zindex    = 1;
    if (oBrowser.bIE4) {
      oMenuLayer.style.pixeltop  = -300;
      oMenuLayer.style.pixelleft = -300;
    } else {
      oMenuLayer.style.top       = "-300px";
      oMenuLayer.style.left      = "-300px";
    }

    // Set the item width, initialize the top and left positions
    var iItemWidth = oMenu.menuWidth;
    var iLeftPos = 0, iTopPos = 0, iNumColumns = 1;

    // Opaque background for menu - use same bg color as border 
    if (oMenu.menuBgOpaque) {
      oMenuLayer.style.backgroundColor = oMenu.menuBorderBgColor;
    }

    // Position each of the items
    for (var iItem = 0, iVerticalPos = 0; iItem < oMenu.items.length; iItem++) {

      // Find the main division and text division using the overall count
      var oItem     = findObj("menuItem" + iItemCount);
      var oItemText = findObj("menuItemText" + iItemCount);

      // Set the menu in the item, and item in the menu list of layers
      oItem.Menu = oMenu;
      oMenu.menuItemLayers[oMenu.menuItemLayers.length] = oItem;

      // Set the pixel width and height, and cursor type
      oItem.style.pixelWidth  = iItemWidth;
      oItem.style.pixelHeight = oMenu.menuItemHeight;
      oItem.style.cursor      = "hand";

      // W3C event listener is available - add event listeners
      if (oItem.addEventListener) {
	oItem.addEventListener("mouseover", onMenuItemOver,   false);
	oItem.addEventListener("click",     onMenuItemAction, false);
	oItem.addEventListener("mouseout",  mouseoutMenu,     false);
      }

      // Internet Explorer - position item
      if (oBrowser.bIE4) {
	oItem.style.pixelTop  = iTopPos;
	oItem.style.pixelLeft = iLeftPos;

	// No left horizontal alignment - adjust the shim
	if (oMenu.menuItemHAlign != 'left') {
	  var shim = findObj("menuItemShim" + iItemCount);
	  var iPixWidth = iItemWidth - (2 * oMenu.menuItemPadding) -
	    oMenu.menuItemIndent;
	  shim[0].style.pixelWidth = iPixWidth;
	  shim[1].style.pixelWidth = iPixWidth;
	}
      }

      // Not IE - position item
      else {

	// Modify the item size and position
	oItem.style.width  = iItemWidth + 'px';
	oItem.style.height = oMenu.menuItemHeight + 'px';
	oItem.style.top    = iTopPos + 'px';
	oItem.style.left   = iLeftPos + 'px';

	// Modify the text height and width to avoid any unwanted wrapping
	oItemText.style.width  = iItemWidth + 'px';
	oItemText.style.height = oMenu.menuItemHeight + 'px';

	// No left horizontal alignment - adjust the shim
	if (oMenu.menuItemHAlign != 'left') {
	  oItem.hiliteShim = findObj("menuItemHilite" + iItemCount + "Shim");
	  oItem.hiliteShim.style.visibility = "inherit";
	  oItem.textShim = findObj("menuItemText" + iItemCount + "Shim");
	  var iPixWidth = iItemWidth - (2 * oMenu.menuItemPadding) -
	    oMenu.menuItemIndent;
	  oItem.hiliteShim.style.width = iPixWidth;
	  oItem.textShim.style.width   = iPixWidth;
	}
      }

      // Vertical alignment - adjust for multiple columns
      if (oMenu.vertical) {

	// Evaluating last item or next item is in first column - adjust top
	if (oMenu.columns.length == (iItem+1) || oMenu.columns[iItem+1] == 1) {
	  iTopPos += oMenu.menuItemHeight + oMenu.menuItemBorder +
	    oMenu.menuItemSpacing;
	  iLeftPos = 0;
	}

	// Multiple columns - next item not in first column - set left position
	else {
	  var iColumn = oMenu.columns[iItem + 1];
	  iLeftPos = (iItemWidth + oMenu.menuItemBorder +
		      oMenu.menuItemSpacing) * (iColumn - 1);
	  if (iColumn > iNumColumns) { iNumColumns = iColumn; }
	}
      }

      // Horizontal alignment 
      else {
	iLeftPos = iLeftPos + iItemWidth + oMenu.menuItemBorder +
	  oMenu.menuItemSpacing;
      }

      // Set the item visibility, save color and action 
      oItem.style.visibility  = "inherit";
      oItem.saveColor         = oItem.style.backgroundColor;
      oItem.menuHiliteBgColor = oMenu.menuHiliteBgColor;
      oItem.mmaction          = oMenu.actions[iItem];

      // Set highlight and focus objects into the item 
      oItem.hilite    = findObj("menuItemHilite" + iItemCount);
      oItem.focusItem = findObj("focusItem" + iMenu);

      // Set the focus item position
      if (oBrowser.bIE4) { oItem.focusItem.style.pixelTop = -30; }
      else               { oItem.focusItem.style.top = '-30px';  }

      // Child menu exists 
      var oChild = findObj("childMenu" + iItemCount);
      if (oChild) {

	// Add the child menu to the item and menu
	oItem.childMenu = oMenu.items[iItem].menuLayer;
	oMenu.childMenus[oMenu.childMenus.length] = oItem.childMenu;

	// Adjust the position
	var iLeftChild = iItemWidth - 11;
	var iTopChild  = (oMenu.menuItemHeight / 2) - 4;
	if (oBrowser.bIE4) { 
	  oChild.style.pixelLeft = iLeftChild;
	  oChild.style.pixelTop  = iTopChild;
	} else {
	  oChild.style.left      = iLeftChild + 'px';
	  oChild.style.top       = iTopChild  + 'px';
	}
      }

      // Increment the complete item count
      iItemCount++;  
    }

    // Last item not in the last column - adjust for unenven columns by bringing
    // up the top position by one item, shrinking the underlying areas
    if (oMenu.columns[oMenu.columns.length - 1] < iNumColumns) {
      iTopPos -= oMenu.menuItemHeight + oMenu.menuItemSpacing;
    }

    // Set the height and width
    if (oMenu.vertical) {
      oMenu.menuHeight = iTopPos - 1 - oMenu.menuItemSpacing;
      oMenu.menuWidth  = iItemWidth;
    } else {
      oMenu.menuHeight = oMenu.menuItemHeight;
      oMenu.menuWidth  = iLeftPos - 1 - oMenu.menuItemSpacing;
    }

    // Get the foreground and lite objects
    var oBody = findObj("menuFg" + iMenu);
    var oLite = findObj("menuLite" + iMenu);

    // Determine the height and width, with extra margin for multi columns
    var iHeight1 = oMenu.menuHeight +  oMenu.menuBorder;
    var iHeight2 = oMenu.menuHeight + (oMenu.menuBorder * 2);
    var iHeight3 = oMenu.menuHeight + (oMenu.menuBorder * 4);
    var iWidth1  = (oMenu.menuWidth * iNumColumns)  +  oMenu.menuBorder +
      (iNumColumns - 1);
    var iWidth2  = (oMenu.menuWidth * iNumColumns)  + (oMenu.menuBorder * 2) +
      (iNumColumns - 1);
    var iWidth3  = (oMenu.menuWidth * iNumColumns)  + (oMenu.menuBorder * 4) +
      (iNumColumns - 1);

    // Set the height and width
    if (oBrowser.bIE4) {
      oBody.style.pixelHeight      = iHeight1;
      oBody.style.pixelWidth       = iWidth1;
      oLite.style.pixelHeight      = iHeight2;
      oLite.style.pixelWidth       = iWidth2;
      oMenuLayer.style.pixelHeight = iHeight3;
      oMenuLayer.style.pixelWidth  = iWidth3;
    } else {
      oBody.style.height      = iHeight1 + 'px';
      oBody.style.width       = iWidth1  + 'px';
      oLite.style.height      = iHeight2 + 'px';
      oLite.style.width       = iWidth2  + 'px';
      oMenuLayer.style.height = iHeight3 + 'px';
      oMenuLayer.style.width  = iWidth3  + 'px';
    }

    // Opaque background for menu - use same bg color as border 
    if (oMenu.menuBgOpaque) {
      oLite.style.backgroundColor = oMenu.menuLiteBgColor;
      oBody.style.backgroundColor = oMenu.bgColor;
    }
  }

  if (document.captureEvents) {
    document.captureEvents(Event.MOUSEUP);
  }
  if (document.addEventListener) {
    document.addEventListener("mouseup", onMenuItemOver, false);
  }
  document.onmouseup = mouseupMenu;
  window.mmWroteMenu = true;
  window.status = "";
  return true;
}

function onMenuItemOver(e, l) {
  if (document.layers) { return; }
  MM_clearTimeout();
  l = l || this;
  a = window.ActiveMenuItem;
  if (l.style && l.Menu) {
    if (a) {
      a.style.backgroundColor = a.saveColor;
      if (a.hilite) a.hilite.style.visibility = "hidden";
      if (a.hiliteShim) a.hiliteShim.style.visibility = "inherit";
      if (a.Menu.bgImageUp) a.style.background = "url(" + a.Menu.bgImageUp +")";;
    }
    l.style.backgroundColor = l.menuHiliteBgColor;
    l.zIndex = 1;
    if (l.Menu.bgImageOver) l.style.background = "url(" + l.Menu.bgImageOver +")";
    if (l.hilite) {
      l.hilite.style.visibility = "inherit";
      if( l.hiliteShim ) l.hiliteShim.style.visibility = "visible";
    }
    if (oBrowser.bIE4) {
      l.focusItem.style.pixelTop  = l.style.pixelTop;
      l.focusItem.style.pixelLeft = l.style.pixelLeft;
    } else {
      l.focusItem.style.top  = l.style.top;
      l.focusItem.style.left = l.style.left;
    }
    l.focusItem.style.zIndex = l.zIndex +1;
    l.Menu.hideChildMenu(l);
  } else return;
  window.ActiveMenuItem = l;
}

function onMenuItemAction(e, l) {
  l = window.ActiveMenuItem;
  if (!l) return;
  hideActiveMenus();
  // if (l.mmaction) eval("" + l.mmaction);
  window.ActiveMenuItem = 0;
}

function MM_clearTimeout() {
  if (mmHideMenuTimer) clearTimeout(mmHideMenuTimer);
  mmHideMenuTimer = null;
  mmDHFlag = false;
}

function MM_startTimeout() {
  if( window.ActiveMenu ) {
    mmStart = new Date();
    mmDHFlag = true;
    mmHideMenuTimer = setTimeout("mmDoHide()", window.ActiveMenu.Menu.hideTimeout);
  }
}

function MM_findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

function MM_swapImage() { //v3.0
  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
}

function MM_swapImgRestore() { //v3.0
  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}
function mmDoHide() {
  if (!mmDHFlag || !window.ActiveMenu) return;
  var elapsed = new Date() - mmStart;
  var timeout = window.ActiveMenu.Menu.hideTimeout;
  if (elapsed < timeout) {
    mmHideMenuTimer = setTimeout("mmDoHide()", timeout+100-elapsed);
    return;
  }
  mmDHFlag = false;
  hideActiveMenus();
  window.ActiveMenuItem = 0;
}

function MM_showMenu(menu, x, y, child, imgname) {
  if (!window.mmWroteMenu || document.layers) return;
  MM_clearTimeout();
  if (menu) {
    var obj = findObj(imgname) || document.images[imgname] || document.links[imgname] || document.anchors[imgname];
    x = moveXbySlicePos (x, obj);
    y = moveYbySlicePos (y, obj);
  }
  if (findObj("menuItem0")) {
    var l = menu.menuLayer || menu;	
    hideActiveMenus();
    if (typeof(l) == "string") l = findObj(l);
    window.ActiveMenu = l;
    var s = l.style;
    s.visibility = "inherit";
    if (x != "relative") {
      s.pixelLeft = x || (window.pageX + document.body.scrollLeft) || 0;
      s.left = s.pixelLeft + 'px';
    }
    if (y != "relative") {
      s.pixelTop = y || (window.pageY + document.body.scrollTop) || 0;
      s.top = s.pixelTop + 'px';
    }
    l.Menu.xOffset = document.body.scrollLeft;
    l.Menu.yOffset = document.body.scrollTop;
  }
  if (menu) window.activeMenus[window.activeMenus.length] = l;
  MM_clearTimeout();
}

function onMenuItemDown(e, l) {
}

function mouseupMenu(e) {
  hideMenu(true, e);
  hideActiveMenus();
  return true;
}

function getExplorerVersion() {
  var ieVers = parseFloat(navigator.appVersion);
  if( navigator.appName != 'Microsoft Internet Explorer' ) return ieVers;
  var tempVers = navigator.appVersion;
  var i = tempVers.indexOf( 'MSIE ' );
  if( i >= 0 ) {
    tempVers = tempVers.substring( i+5 );
    ieVers = parseFloat( tempVers ); 
  }
  return ieVers;
}

function mouseoutMenu() {
  if ((navigator.appName == "Microsoft Internet Explorer") && (getExplorerVersion() < 4.5))
    return true;
  hideMenu(false, false);
  return true;
}

function hideMenu(mouseup, e) {
  if (document.layers) { return; }
  var a = window.ActiveMenuItem;
  if (window.ActiveMenu && findObj("menuItem0")) {
    if (a) {
      a.style.backgroundColor = a.saveColor;
      if (a.hilite) a.hilite.style.visibility = "hidden";
      if (a.hiliteShim) a.hiliteShim.style.visibility = "inherit";
      if (a.Menu.bgImageUp) a.style.background = "url(" + a.Menu.bgImageUp +")";
    }
  }
  if (!mouseup && window.ActiveMenu) {
    if (window.ActiveMenu.Menu) {
      if (window.ActiveMenu.Menu.hideOnMouseOut) MM_startTimeout();
      return(true);
    }
  }
  return(true);
}

function hideChildMenu(hcmLayer) {
  if (document.layers) { return; }
  MM_clearTimeout();
  var l = hcmLayer;
  for (var i=0; i < l.Menu.childMenus.length; i++) {
    var theLayer = l.Menu.childMenus[i];
    theLayer = findObj(theLayer);
    theLayer.style.visibility = "hidden";
    if( theLayer.Menu.menuItemHAlign != 'left' ) {
      for(var j = 0; j < theLayer.Menu.menuItemLayers.length; j++) {
	var itemLayer = theLayer.Menu.menuItemLayers[j];
	if(itemLayer.textShim) itemLayer.textShim.style.visibility = "inherit";
      }
    }
    theLayer.Menu.hideChildMenu(theLayer);
  }
  if (l.childMenu) {
    var childMenu = l.childMenu;
    if (findObj("menuItem0")) {
      childMenu = findObj(l.childMenu);
      var menuLayer = findObj(l.Menu.menuLayer);
      var s = childMenu.style;
      s.zIndex = menuLayer.style.zIndex+1;
      if (document.all) {
	s.pixelTop = menuLayer.style.pixelTop + l.Menu.submenuYOffset;
	if( l.Menu.vertical ) {
	  if( l.Menu.submenuRelativeToItem ) s.pixelTop += l.style.pixelTop;
	  s.pixelLeft = l.style.pixelWidth + menuLayer.style.pixelLeft + l.Menu.submenuXOffset;
	  s.left = s.pixelLeft + 'px';
	} else {
	  s.pixelTop += l.style.pixelTop;
	  if( l.Menu.submenuRelativeToItem ) s.pixelLeft = menuLayer.style.pixelLeft + l.style.pixelLeft + l.style.pixelWidth + (2*l.Menu.menuBorder) + l.Menu.submenuXOffset;
	  else s.pixelLeft = (menuLayer.style.pixelWidth-4*l.Menu.menuBorder) + menuLayer.style.pixelLeft + l.Menu.submenuXOffset;
	  s.left = s.pixelLeft + 'px';
	}
      } else {
	var top = parseInt(menuLayer.style.top) + l.Menu.submenuYOffset;
	var left = 0;
	if( l.Menu.vertical ) {
	  if( l.Menu.submenuRelativeToItem ) top += parseInt(l.style.top);
	  left = (parseInt(menuLayer.style.width)-4*l.Menu.menuBorder) + parseInt(menuLayer.style.left) + l.Menu.submenuXOffset;
	} else {
	  top += parseInt(l.style.top);
	  if( l.Menu.submenuRelativeToItem ) left = parseInt(menuLayer.style.left) + parseInt(l.style.left) + parseInt(l.style.width) + (2*l.Menu.menuBorder) + l.Menu.submenuXOffset;
	  else left = (parseInt(menuLayer.style.width)-4*l.Menu.menuBorder) + parseInt(menuLayer.style.left) + l.Menu.submenuXOffset;
	}
	s.top = top + 'px';
	s.left = left + 'px';
      }
      childMenu.style.visibility = "inherit";
    } else return;
    window.activeMenus[window.activeMenus.length] = childMenu;
  }
}

function hideActiveMenus() {
  if (!window.activeMenus) return;
  for (var i=0; i < window.activeMenus.length; i++) {
    if (!activeMenus[i]) continue;
    if (activeMenus[i].visibility && activeMenus[i].Menu) {
      activeMenus[i].visibility = "hidden";
      activeMenus[i].Menu.container.visibility = "hidden";
      activeMenus[i].Menu.container.clip.left = 0;
    } else if (activeMenus[i].style) {
      var s = activeMenus[i].style;
      s.visibility = "hidden";
      s.left = '-200px';
      s.top = '-200px';
    }
  }
  if (window.ActiveMenuItem) hideMenu(false, false);
  window.activeMenus.length = 0;
}

function moveXbySlicePos (x, img) { 
  if (document.layers) { return; }
  var onWindows = navigator.platform ? navigator.platform == "Win32" : false;
  var macIE45 = document.all && !onWindows && getExplorerVersion() == 4.5;
  var par = img;
  var lastOffset = 0;
  while(par){
    if( par.leftMargin && ! onWindows ) x += parseInt(par.leftMargin);
    if( (par.offsetLeft != lastOffset) && par.offsetLeft ) x += parseInt(par.offsetLeft);
    if( par.offsetLeft != 0 ) lastOffset = par.offsetLeft;
    par = macIE45 ? par.parentElement : par.offsetParent;
  }
  return x;
}

function moveYbySlicePos (y, img) {
  if(document.layers) { return; }
  var onWindows = navigator.platform ? navigator.platform == "Win32" : false;
  var macIE45 = document.all && !onWindows && getExplorerVersion() == 4.5;
  var par = img;
  var lastOffset = 0;
  while(par){
    if( par.topMargin && !onWindows ) y += parseInt(par.topMargin);
    if( (par.offsetTop != lastOffset) && par.offsetTop ) y += parseInt(par.offsetTop);
    if( par.offsetTop != 0 ) lastOffset = par.offsetTop;
    par = macIE45 ? par.parentElement : par.offsetParent;
  }		
  return y;
}

function StdInputValue (oInput) {
  var sValue = null;
  if (typeof(oInput) == "object") {
    switch(oInput.type) {
    case "select-multiple": case "select-one":
      sValue = oInput.options[oInput.selectedIndex].value; break;
    case "hidden": case "text": case "textarea": case "password":
    case "checkbox": 
      sValue = oInput.value; break;
    default:
      for (var i = 0; i < oInput.length && sValue == null; i++) {
        if (oInput[i].checked) { sValue = oInput[i].value; }
      }
      break;
    }
  }
  return sValue;
}

function FormValidate (oForm, sRequired) {
  if (!oForm || !ValidStr(sRequired)) { return false; }

  // Array of variables: variable name, description
  var aArgs = sRequired.split(",");

  // Loop through variable/test set, stopping if an error occurs
  for (var n = 0; n < aArgs.length; n += 2) {

    // Set variable name, test type and get the input object from the form
    sVarName = aArgs[n].replace(/^ */, "");
    sDesc    = aArgs[n+1].replace(/^ */, "");
    oInput   = eval("oForm." + sVarName);

    // Input object is defined - continue
    if (oInput) {
      var sValue = StdInputValue(oInput);

      // No state but there is a country input
      if (sVarName == "state" && oForm.country && !ValidStr(sValue)) {

	// No state defined
	if (StdInputValue(oForm.country) == "United States") {
	  alert("Please select a US state");
	  oInput.focus(); return false;
	}

	// No province defined
	else if (StdInputValue(oForm.country) == "Canada") {
	  alert("Please select a Canadian province");
	  oInput.focus(); return false;
	}
      }
      

      // Phone or fax check
      else if (sVarName == "phone" || sVarName == "fax") {
	if (!ValidStr(sValue) || sValue.search(/[^0-9\(\)\+\. -]/) >= 0 ||
	    sValue.length < 7) {
	  alert("Invalid number for " + sDesc);
	  oInput.value = ""; oInput.focus(); return false;
	}
      }

      // Zip code check - only verifying US codes for now
      else if (sVarName == "zip") {
	if (StdInputValue(oForm.country) == "United States" &&
	    (sValue.length < 5 || sValue.search(/[^0-9\-]/) >= 0)) {
	  alert("Please enter a valid US zip code");
	  oInput.focus(); return false;
	}
      }

      // Email check
      else if (sVarName == "email") {
	var reFilter = /^([a-z0-9_]|\-|\.)+@(([a-z0-9_]|\-)+\.)+[a-z]+$/i;
	//	var filter=/^.+@.+\..{2,3}$/;
	if (!reFilter.test(sValue)) {
	  alert("Please input a valid email address");
	  oInput.focus(); return false;
	}
      }

      // Checkbox value - assume description is complete
      else if (oInput.type == "checkbox" && !oInput.checked) {
	alert(sDesc);
	if (oInput.focus) { oInput.focus(); }
	return false;
      }

      // Standard value check - may be a radio button, so check for focus()
      else if (!ValidStr(sValue)) {
	alert("Please fill in " + sDesc);
	if (oInput.focus) { oInput.focus(); }
        else if (oInput.length > 0 && oInput[0].focus) { oInput[0].focus(); }
	return false;
      }

      // Password check
      if (sDesc.toLowerCase() == "password") {
	var sMsg = "";

	if (sValue.length < iPASSWD_MIN) {
	  sMsg = "Please use at least " + iPASSWD_MIN +
	    " characters or numbers in the password.";
	} else if (sValue.search(/[^A-Za-z0-9]/) >= 0) {
	  sMsg = "Your password should contain only characters or numbers.";
	  alert(sValue);
	} else if (oForm.sPasswordCheck &&
		   oForm.sPasswordCheck.value != sValue) {
	  sMsg = "Your passwords do not match.";
	  oForm.sPasswordCheck.value = "";
	}

	if (sMsg != "") {
	  alert(sMsg + " Please enter the password again.");
	  oInput.value = ""; oInput.focus(); return false;
	}
      }
    }
  }
  return true;
}

function ValidStr (sStr) {
  return (sStr != null && sStr.search(/[a-z0-9]/i) != -1);
}

function clearMenu () {
  restoreImages();
  window.status = "";
  return true;
}

function restoreImages () {
  var i, x, a = document.imagesToRestore;
  for (i = 0; a != null && i < a.length && (x = a[i]) && x.oSrc; i++)
    x.src = x.oSrc;
  document.imagesToRestore = null;
  document.subMenuRestore  = null;
}

function getUniqueName () {
  var oDate = new Date(); return("" + oDate.getTime());
}

function popUpWindow (url, width, height, scrollbar, verify) {

  if (verify && !ppdOutsideConfirm()) { return; }

  var str = "toolbar=0,directories=0,status=0,menubar=0,resizable=1";
  var x = Math.round((screen.width - width) / 2);
  var y = Math.round((screen.height - height) / 2);

  str += ",left=" + x + ",width="  + width;
  str += ",top="  + y + ",height=" + height;

  if (scrollbar == true) { str += ",scrollbars=1"; }
  else                   { str += ",scrollbars=0"; }

  subwindow = window.open(url, getUniqueName(), str);
  subwindow.focus();
}

function ppdOutsideLink (url) {
  if (!ppdOutsideConfirm()) { return; }
  subwindow = window.open(url, getUniqueName());
  subwindow.focus();
}

function ppdOutsideConfirm () {
  return confirm("You are leaving the PPD Web site. Linked Web sites\n" +
		 "are not under the control of PPD.  PPD does not\n" +
		 "endorse any Web site to which the PPD Web site is\n" +
		 "linked and PPD is not responsible for the content\n" +
		 "of any Web site linked to the PPD Web site.")
}

function BlankWindow (url) {
  var subwindow = window.open(url, getUniqueName());
  subwindow.focus();
}

function topNavAdvSearch (oForm) {
  oForm.action = "/advanced_search.htm";
  oForm.submit();
}

function topNavAdvSearch2 (oForm) {
  oForm.action = "http://www.ppdi.com/advanced_search.htm";
  oForm.submit();
}

// Follow a link with optional variables
function FollowLink (sUrl, sUrlVariables) {
  if (sUrlVariables != null) {
    var sAddVar  = (sUrl.match(/\.html?\?/i) == null) ? "?" : "&";
    sUrl += sAddVar + sUrlVariables;
  }
  window.location = sUrl;
}

// Redirection for select objects
function SelectRedirect (oSelect) {
  var sValue = StdInputValue(oSelect);
  if (ValidStr(sValue)) { window.location = sValue; }
}

// END OF FILE
