//
//// Javscript code for PanPage websites
//   v2.00, (C) Abbeydale.Net 2009-2011
//   this file loads in the head section
//
//// nav menu code... ////
//
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 = 0;
var menuOffsetX1 = 0;     // offsets for first level drop downs
var menuOffsetY1 = 0;
//
//// 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 6/6/2011, MT: stops at first relative positioned parent
// and gets over IE problems if that is the gallery container!
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 navigation stuff ////
//
//// communication functions ////
//
// nsmhere() - No Spam Mail function - provides email
//            link without exposure to harvesters.
//
function nsmhere(sUsername, sSubject, sHide, sImage)
  {
  // get domain
  var sDomain = window.location.hostname;
  if (sDomain.substring(0, 4) == "www.")
    sDomain = sDomain.substring(4);  
  document.write('<a');
  if (typeof(cls) != "undefined" && cls != "")
    document.write(' class="' + cls + '"');
  document.write(' href="' + 'mailto:' + sUsername + '@' + sDomain);
  if (typeof(sSubject) != "undefined" && sSubject != "")
    document.write('?subject=' + sSubject);
  if (typeof(sHide) != "undefined" && sHide != "")
    {
    if (sHide == "image" && typeof(sImage) != "undefined" && sImage != "")
      document.write('"><img alt="' + sUsername + '" src="' + sImage + '" /></a>');
    else  
      document.write('">' + sHide + '</a>');
    }
  else
    document.write('">' + sUsername + '@' + sDomain + '</a>');
  }
//
/////////////////////////////////////////////////////
//
// nsm() - No Spam Mail function - provides email
//            link without exposure to harvesters.
//
// deprecated - use nsmhere where possible
//
function nsm(user, domain, suffixCode, subject, hide, img)
  {
  var suffix = "co.uk";
  switch (suffixCode)
    {
    case "b":
      suffix = "biz";
      break;
    case "c":
      suffix = "com";
      break;
    case "n":
      suffix = "net";
      break;
    case "o":
      suffix = "org";
      break;
    case "cu":
      suffix = "co.uk";
      break;
    case "gu":
      suffix = "gov.uk";
      break;
    case "mu":
      suffix = "me.uk";
      break;
    case "pu":
      suffix = "police.uk";
      break;
    case "ou":
      suffix = "org.uk";
      break;
    }
  document.write('<a');
  if (typeof(cls) != "undefined" && cls != "")
    document.write(' class="' + cls + '"');
  document.write(' href="' + 'mailto:' + user + '@' + domain + '.' + suffix);
  if (typeof(subject) != "undefined" && subject != "")
    document.write('?subject=' + subject);
  if (typeof(hide) != "undefined" && hide != "")
    {
    if (hide == "image" && typeof(img) != "undefined" && img != "")
      document.write('"><img alt="' + user + '" src="' + img + '" /></a>');
    else  
      document.write('">' + hide + '</a>');
    }
  else
    document.write('">' + user + '@' + domain + '.' + suffix + '</a>');
  }
//
//
/////////////////////////////////////////////////////
//
// bValidateForm() - validate fields in enquiry form
//                   highlight elCaptions for invalid/missing
//                   fields, and move focus to first one.
//
// NB. Moving the focus to the first invalid field BEFORE
//     displaying the alert gets round the IE timing bug!
//
function bValidateForm(form)
  {
  // alert("Validating form...");
  var sMsg = "Please fill in at least the boxes shown coloured.";
  var bValid = true;
  var elCaption;

  // Message text...
  elCaption = document.getElementById("lblMessage");
  if (bIsEmpty(form.sMessage))
    {
    elCaption.className = "lblErr";
    form.sMessage.focus();
    sMsg = "Please fill in the message box.";
    bValid = false;
    }
  else
    elCaption.className = "lblReq";

  // Email address & phone no...
  elCaption = document.getElementById("lblEmail");
  var elCapPhone = document.getElementById("lblPhone");
  if (bIsEmpty(form.sEmail) && bIsEmpty(form.sPhone))
    {
    elCaption.className = "lblErr";
    elCapPhone.className = "lblErr";
    form.sEmail.focus();
    sMsg = "Please give an email address or a phone number, or both.";
    bValid = false;
    }
  else
    {
    elCaption.className = "lblReq";
    elCapPhone.className = "lblReq";
    }
  
  // Name...
  var elCaption = document.getElementById("lblName");
  if (bIsEmpty(form.sName))
    {
    elCaption.className = "lblErr";
    form.sName.focus();
    sMsg = "Please tell us your name.";
    bValid = false;
    }
  else
    elCaption.className = "lblReq";

  // tell Sir if he goofed...
  if (!bValid)
    alert(sMsg);
  return bValid;
  }

function bIsEmpty(elem)
  {
  var str = elem.value;
  if (str == null || str.length == 0)
    return true;
  else
    return false;
  }

function bIsValidRadio(elem)
  {
  for (var i = 0; i < elem.length; i++)
    {
    if (elem[i].checked)
      return true;
    }
  return false;
  }
//
// End of File //////////////////////////////////////


