//// Navigation menu code for Abbeydale sites ////
//
function sGetVersion() {return "2.00";}
// array of navigation item base names...
//var arrMenu = new Array("", "about", "", "", "", "");
// prefixes for navigation items and drop down menus...
var prefixMenu = "mnu";
var prefixNav = "nav";
var navDelay = 500;       // milliseconds before drop menu closes
var menuOffsetX = 0;      // offset for deep drop downs
var menuOffsetY = 10;
var menuOffsetX1 = 0;     // offsets for first level drop downs
var menuOffsetY1 = -1;
//
////////////////////////////////////////////
//// No config items beyond this point! ////
////////////////////////////////////////////
//
// index of currently open menu or -1 if none open...
var navTimer = 0;
var bGoRight = true;
//
///////////////////////////////////////////////
//
// define the CMenu class...
//
function CMenu(sName, nParent)
  {
  this.sName = sName;
  this.nParent = nParent;
  this.arrChildren = new Array();
  this.bOpen = false;
  }
//
///////////////////////////////////////////////
// menuOpen()
//
// Drops open a menu and marks it as open
// Also opens (re-opens?) parent menus
// sID: string: the base ID name of the menu item to open
//
function menuOpen(sID)
  {
  // check the menu exists...
  var sNavID = prefixNav + sID;
  var sMenuID = prefixMenu + sID;
  var ndx = menuGetIndex(sID);
  if (ndx < 1 || arrMenu[ndx].sName == "")
    return false;

  var elemNav = document.getElementById(sNavID);
  var elemMenu = document.getElementById(sMenuID);
  if (elemNav && elemMenu)
    {
    // cancel any pending menu closures...
    clearTimeout(navTimer);
    // hide other drop downs except ancestors...
    menuShutAll(sID);
    // drop open this menu...
    elemMenu.style.top = findPosY(elemNav) + (arrMenu[ndx].nParent ? menuOffsetY : elemNav.offsetHeight + menuOffsetY1) + "px";
    // move far to left to calc true width...
    elemMenu.style.left = "-1000px";
    elemMenu.style.display = "block";
    var menuWidth = elemMenu.offsetWidth;
    // calc horiz position...
    var left = findPosX(elemNav);
    if (bGoRight)
      left += (arrMenu[ndx].nParent ? menuOffsetX + elemNav.offsetWidth : menuOffsetX1);
    else
      left -= (arrMenu[ndx].nParent ? menuOffsetX + menuWidth : menuOffsetX1);
    elemMenu.style.left = left + "px"
    // and mark it as open...
    arrMenu[ndx].bOpen = true;
    // now check the menu is still on screen...
    var right = left + menuWidth;
    if (left < 0)
      {
      // menu is off left - never really happens does it?
      bGoRight = true;
      }
    else if (right > document.body.clientWidth)
      {
      // menu is off right, bring it back...
      bGoRight = false;
      left = findPosX(elemNav);
      if (arrMenu[ndx].nParent)
        {
        // deep menu - move to other side of parent...
        left -= menuOffsetX + menuWidth;
        }
      else
        {
        // first level - nudge left a bit...
        left -= right - document.body.clientWidth;
        }
      elemMenu.style.left = left + "px";
      }
    }
  return true;   // allows browser to display link target
  }

///////////////////////////////////////////////
// menuKeepOpen()
//
// Marks a previously closed (but still droppped down)
// menu as open and resets the menu display property
// to ensure it stays displayed.  Used when the mouse
// moves from a nav item down to its dropped menu.
// Keeps parent menu open too...
// sID: string: the base ID name of the menu item to open
//
function menuKeepOpen(sID)
  {
  var sMenuID = prefixMenu + sID;
  var ndx = menuGetIndex(sID);
  if (ndx > 0 && arrMenu[ndx].sName != "")
    {
    arrMenu[ndx].bOpen = true;
    var elem = document.getElementById(sMenuID);
    elem.style.display = "block";
    }
  // keep parent(s) open too
  var nParent = arrMenu[ndx].nParent;
  if (nParent)
    menuKeepOpen(arrMenu[nParent].sName);
  }

///////////////////////////////////////////////
// menuClose()
//
// Schedules the raising of a dropped menu.
// Actually schedules all menus to close since those
// needing to be kept open will be KeepOpen'd anyway!
// sID: string: the base ID name of the menu item to close
//
function menuClose(sID)
  {
  var sMenuID = prefixMenu + sID;
  var ndx = menuGetIndex(sID);
  if (ndx < 1 || arrMenu[ndx].sName == "")
    return;
  // mark all menus to be closed.  Some may
  // subsequently be KeepOpen'd
  var i = 0;
  for (i in arrMenu)
    if (i)
      arrMenu[i].bOpen = false;
  // schedule menu closure...
  navTimer = setTimeout("menuHideAllClosed()", navDelay);
  }

///////////////////////////////////////////////
// menuHide()
//
// Internal function to raise a dropped menu.
// Used via setTimeout() to delay the raising of a menu
// for a short while after a mouseout event closes it.
// ndx: int: the array index of the menu item to close
//
function menuHide(ndx)
  {
  arrMenu[ndx].bOpen == false;
  var elem = document.getElementById(prefixMenu + arrMenu[ndx].sName);
  if (elem)
    elem.style.display = "none";
  }
//
///////////////////////////////////////////////
// menuHideAllClosed()
//
// Internal func to raise all menus marked as closed
// Used via setTimeout()
//
function menuHideAllClosed()
  {
  var elem;
  var i = 0;
  for (i in arrMenu)
    if (i && !arrMenu[i].bOpen)
      menuHide(i);
  var bAllClosed = true;
  for (var i in arrMenu)
    if (arrMenu[i].bOpen)
      bAllClosed = false;
  if (bAllClosed)
    bGoRight = true;
  }

///////////////////////////////////////////////
// menuShutAll()
//
// Close immediately all open menus except current
// and ancestors. Used before opening another menu.
// If sID is blank ALL menus will be shut.
//
function menuShutAll(sID)
  {
  var sMenuID = prefixMenu + sID;
  var ndx = menuGetIndex(sID);
  var i = 0;
  for (i in arrMenu)
    if (ndx < 0 || (i && i != ndx && !bIsAncestor(i, ndx)))
      menuHide(i);
  }

///////////////////////////////////////////////
// menuGetIndex()
//
// Internal function to calc index of a specified
// base ID name.
// sID: string: base ID name of menu to find
//
function menuGetIndex(sID)
  {
  for (var i in arrMenu)
    {
    if (arrMenu[i].sName == sID)
      return i;
    }
  // if we're here we didn't find the menu...
  return -1;
  }

///////////////////////////////////////////////
// bIsAncestor()
//
// Returns true if nOld is an acestor of nYoung.
//
function bIsAncestor(nOld, nYoung)
  {
  var i = nYoung;
  while (i != 0)
    {
    if (arrMenu[i].nParent == nOld)
      return true;
    i = arrMenu[i].nParent;
    }
  return false;
  }

// functions to find the position of an element...
// updated 2/9/2007, MT: fixes IE offsetParent problem
// updated 6/6/2011, MT: stops at first relative positioned parent
function findPosX(obj)
  {
  var curleft = obj.offsetLeft;
  while (obj.offsetParent)
    {
    obj = obj.offsetParent;
    if (obj.currentStyle && obj.currentStyle["position"] == "relative")
      break;
    if (window.getComputedStyle && window.getComputedStyle(obj, null).position == "relative")
      break;
    curleft += obj.offsetLeft;
    }
  //dbg alert("curleft="+curleft);
  return curleft;
  }

function findPosY(obj)
  {
  var curtop = obj.offsetTop;
  while (obj.offsetParent)
    {
    obj = obj.offsetParent;
    if (obj.currentStyle && obj.currentStyle["position"] == "relative")
      break;
    if (window.getComputedStyle && window.getComputedStyle(obj, null).position == "relative")
      break;
    curtop += obj.offsetTop;
    }
  //dbg alert("curtop="+curtop);
  return curtop;
  }

//
//// image navigation...
//
function setImage(name, state)
  {
  if (state == 1)
    {
    document.images["navimg" + name].src = navimgsHi[name].src;
    return true;
    }
  else if (state == 0)
    {
    document.images["navimg" + name].src = navimgsLo[name].src;
    return true;
    }
  return false;
  }


//
///// End of File ///////////////////////////////////////

