/******************************************************/
/* Summary:                                           */
/* --------                                           */
/*                                                    */
/* Browser(): Detect browser                          */
/* positionFooter: put the footer navigation right at */
/* the bottom of the page, on loading and resizing.   */
/*                                                    */
/******************************************************/




/******************************
  Prototyping for legacy support 
 ******************************/
if (typeof Array.prototype.push == "undefined") {
  Array.prototype.push = function(str) {
    this[this.length] = str;
  }
}



var current_browser = new Browser();
var posX = 0;
var posY = 0;
var timerID = null;
var timerRunning = false;
var explanationElement = null;
document.onclick = getEventXandY;
if (document.captureEvents) document.captureEvents(Event.CLICK);



// FUNCTION: detects the browser for use in later functions.
//
function Browser() 
{
  var ua, s, i;

  this.isIE    = false;  // Internet Explorer
  this.isNS    = false;  // Netscape
  this.version = null;

  ua = navigator.userAgent;

  s = "MSIE";
  if ((i = ua.indexOf(s)) >= 0) 
  {
    this.isIE = true;
    this.version = parseFloat(ua.substr(i + s.length));
    return;
  }

  s = "Netscape6/";
  if ((i = ua.indexOf(s)) >= 0) 
  {
    this.isNS = true;
    this.version = parseFloat(ua.substr(i + s.length));
    return;
  }

  s = "Opera/";
  if ((i = ua.indexOf(s)) >= 0) 
  {
    this.isNS = true;
    this.version = parseFloat(ua.substr(i + s.length));
    return;
  }

  // Treat any other "Gecko" browser as NS 6.1.

  s = "Gecko";
  if ((i = ua.indexOf(s)) >= 0) 
  {
    this.isNS = true;
    this.version = 6.1;
    return;
  }
}



/***********************************/
/* FUNCTION DEFINITIIONS FOLLOW... */
/***********************************/

function standardInit() {
  // calls all the standard preparatory functions.

  setLayout();
  setLinkTargets();
  //the following hack makes sure that all the elements of page are repositioned by external scripts (like the hero banner on the frontpage) before measuring the heights. this is necessary to avoid the 'big gap' issue at the bottom of the HomePage
  if (current_browser.isIE){
  window.setTimeout('setLayout()', 1000)
  }
}


function getSections() {
  sections = new Array();

  sections[0] = document.getElementById('main-banner');
  sections[1] = document.getElementById('main-left');
  sections[2] = document.getElementById('main-right');
  sections[3] = document.getElementById('main-background');
  sections[4] = document.getElementById('main-content');
  sections[6] = document.getElementById('main-content-middle');
  sections[7] = document.getElementById('main-content-bottom-left');
  sections[8] = document.getElementById('main-content-bottom-right');
  sections[5] = document.getElementById('main-footer');
  return sections;
}
function resetSectionHeights(s) {
  for(var i in s) {
    if(typeof(s[i]) == "object" && s[i] != null) {
      s[i].style.height = "auto";
    }
  }
}

function redrawLayout() {
  //resetSectionHeights(getSections());
  setLayout();
}

function setLayout() {
  if (current_browser.version > 5)
  {
    sections = getSections();

    // get lowest content base to use for footer positioning.
    footerHeight = sections[5].offsetHeight;
    contentBase = getContentBasePosition(sections);
    pageBottom = getBottomOfPage() - footerHeight;
    //alert("footerHeight: " + footerHeight +'\n' + "contentBase: " + contentBase + '\n' + "pageBottom: " + pageBottom );
    if(0 && (footerHeight < (pageBottom - contentBase))) {
      footerPositionX = pageBottom;
    } else {
      footerPositionX = contentBase + 20;
    }
    /* short term solution to fix wrong footer positioning*/

    forumPage=false;
    classes=document.body.className.split(' ');
    for (i=0; i<classes.length; i++){
      if (classes[i]=='ForumPage'){forumPage=true;}
    }
    if (forumPage){
      footerPositionX = getBottomOfPage();
      var contentSections = new Array (document.getElementById('main_content_top'), document.getElementById('page'));
      setContentToMeetFooter(footerPositionX, contentSections);
      setMainContentToMeetFooter(footerPositionX);
    }

    /* end of wrong footer positioning fix*/

    // Position the main-footer and set #page element to surround all...

    positionElement(sections[5], footerPositionX, null);
    resizePageElement(footerPositionX);
    sections[5].style.visibility = 'visible';
    if(0 ) {
      var contentSections = new Array(sections[1],sections[2],sections[3]);      
      setContentToMeetFooter(footerPositionX, contentSections);
      setMainContentToMeetFooter(footerPositionX);
    }
  }
}

function resizePageElement(contentLength) {
  // Function does as name suggests and sets the 
  // (div)#page to greatest length if shorter.
  pageFrame = document.getElementById("page");
  footer = document.getElementById("main-footer");
  if(pageFrame && footer) {
    pageFrame.style.height = contentLength + footer.offsetHeight + "px";
  }
}

function positionElement(element, x, y) {
  //  position and element using css values.
  var pos; 
  if(element != null) {
    element.style.position = "absolute";
    if(x != null){
      pos = x + "px";
      element.style.top = pos;
    }

    if(y != null){
      pos = y+"px";
      element.style.left = pos;
    }
    element.style.display = "block";
  }
}


function getBottomOfPage() {
  // Return the height of the div#page element 
  // Unlike previous methods, this is only a few 
  // pixels difference between IE & Firefox. 

  var holder = document.getElementById('page');
  var height = holder.offsetHeight;  

  // DEBUGGING section
  //  alert("page height = " + holder.offsetHeight);

  return height;
}


function getElementTop(element) {
  // return the top position of an element.

  var top;
  if(element != null)
    top = element.offsetTop;
  else
    top = 0;

  return top;
}


function getContentBasePosition(contentSection) {
  // return the lowest base position of content.
  //alert('getContentBasePosition');
  var contentBase, currentSectionBase;
  var temp
    contentBase = 0;
  for (n=0; n < contentSection.length; n++) {
    if(contentSection[n] != null) {
      currentSectionBase = contentSection[n].offsetHeight + contentSection[n].offsetTop;
      //alert(contentSection[n].id + '=' +currentSectionBase);
      if ((currentSectionBase > contentBase) && (contentSection[n].id != "main-footer") && (contentSection[n].id != "main-background") ) {
        temp = contentSection[n];
        contentBase = currentSectionBase;
      }
    }
  }
  return contentBase;
}


function setElementHeight(element, value) {
  // NOTE: padding-top on the elements needs to be zero or the length can 
  // work out to be increased by the padding amount, thus giving an 
  // unexpected result.

  var elTop, height;
  if(element != null) {
    elTop = element.offsetTop;
    height = value - elTop;
    element.style.height = height + "px";
  }
}

function setContentToMeetFooter(fPosX, changeElements) {
  // Function sets the length of changeElements to 
  // meet with the top of the fPosX section.
  // Note: Due to padding in main-content, need to 
  // handle separately (use setMainContentToMeetFooter()).

  var contentBase = fPosX;
  for(n = 0; n < changeElements.length; n++) {
    if(changeElements[n] != null) {
      setElementHeight(changeElements[n], contentBase);
    }
  }

}

function setMainContentToMeetFooter(fPosX) {
  // Function sets the length of main-content to 
  // meet with the top of the fPosX section.

  var contentBase = fPosX;
  var mainContentChildren = sections[4].childNodes;
  for(var index in mainContentChildren){
    firstContent = mainContentChildren[index];
    // Check for first visible element (ie:  content-header, not the 'skip' anchor).
    if((firstContent.nodeType == 1 && firstContent.name != 'skip' ) && (firstContent.name!="main_content_top") )
      break;
  }
  size=contentBase-firstContent.offsetTop;
  setElementHeight(sections[4], contentBase - firstContent.offsetTop);
}

function setElementsToSameHeight(parent, className) {
  var elementArea = document.getElementById(parent);
  if(elementArea) {
    var elements = getSubElementsByClass(elementArea, className);
    var maxElementHeight = getMaximumHeight(elements);
    for(var i in elements) {
      elements[i].style.height = maxElementHeight + "px";
    }
  }
}

function setLinkTargets() {
  // Function looks through all links on a page and adds
  // correct target location, depending on whether the 
  // link is internal or external.
  var link;
  var domain = document.domain;

  for(var i in document.links) {
    link = document.links[i];

    // Internet Explorer throws up a link that doesn't have
    // .hostname, which causes an error.       
    if(link.hostname){

      // Set the target based on domain matching.
      if(link.target == "") {
        if(link.hostname != domain) {
          link.target = "_blank";
        }
        else {
          link.target = "_self";
        }
      }
    }
  }
}

function resizePageElement(contentLength) { 	
  // Function does as name suggests and sets the 	 
  // (div)#page to greatest length if shorter. 	
  pageFrame = document.getElementById("page"); 	 
  footer = document.getElementById("main-footer"); 	 
  if(pageFrame && footer) { 	 
    pageFrame.style.height = contentLength + footer.offsetHeight + "px"; 	 
  }
  //added body resizing to adjust it with page size
  document.body.style.height=contentLength + footer.offsetHeight + "px";

}

function childElementsToMyHeight(me, childClass) {
  var myHeight = me.offsetHeight;
  var children = getSubElementsByClass(me, childClass);
  //alert("myHeight : " + myHeight + "\n" +
  //    "children : " + children);
  setPixelHeights(children, myHeight);
}

function getSubElement(element) {
  var subElement = element;
  var children = element.childNodes;
  for(var i in children) {
    child = children[i];
    if(child.nodeType == 1){
      subElement = child;
      break;
    }
  }
  return subElement;
}

function getSubElements(element) {
  var subElements = new Array();
  var children = element.childNodes;
  var count = 0;
  for(var i in children) {
    child = children[i];
    if(child.nodeType == 1) {
      subElements[count] = child;
      count++;
    }
  }
  return subElements;
}

function getSubElementByClass(element, classname) {
  var elementByClass = null;
  if(element) {
    var children = element.childNodes;
    for(var i in children) {
      if(children[i].nodeType == 1) {
        if(children[i].className.indexOf(classname) >= 0) {
          elementByClass = children[i];
          break;
        }
      }
    }
  }
  return elementByClass;
}

function getSubElementsByClass(element, classname) {
  var children = element.childNodes;
  var elementsByClass = new Array();
  var index = 0;
  for(var i in children) {
    if(children[i].nodeType == 1) {
      if(children[i].className.indexOf(classname) >= 0) {
        elementsByClass[index] = children[i];
        index++;
      }
    }
  }
  return elementsByClass;
}

function setPixelHeights(elements, height) {
  for(var i in elements) {
    if(typeof(elements[i]) == "object" && elements[i] != null) {
      elements[i].style.height = height + "px";
    }
  }
}

function getMaximumHeight(elements) {
  var max = 0;
  for(var i in elements) {
    if(elements[i]) {
      if(elements[i].offsetHeight > max) {
        max = elements[i].offsetHeight;
      }
    }
  }
  return max;
}

function verticalAlign (frame, element) {  
  var frameHeight = frame.offsetHeight;
  var elementHeight = element.offsetHeight;
  var difference = frameHeight - elementHeight;
  if(difference > 1) {
    offset = difference / 2;
    element.style.marginTop = offset + "px";
  }
}

function addCrossBrowserEvent(element, event, method, bubble) {
  // Two event names can be passed to cope with IE differences.
  var eventName = event[0];

  if(bubble == null) {
    bubble = false;
  }
  if(element.addEventListener) {
    element.addEventListener(eventName, method, bubble); 
  }
  else {
    if(event.length > 1) {
      eventName = event[1];
    }
    element.attachEvent(eventName, method);
  }
}

addEvent(window, "load", sortables_init);

var SORT_COLUMN_INDEX;

function sortables_init() {
    // Find all tables with class sortable and make them sortable
    if (!document.getElementsByTagName) return;
    tbls = document.getElementsByTagName("table");
    for (ti=0;ti<tbls.length;ti++) {
        thisTbl = tbls[ti];
        if (((' '+thisTbl.className+' ').indexOf("sortable") != -1) && (thisTbl.id)) {
            //initTable(thisTbl.id);
            ts_makeSortable(thisTbl);
        }
    }
}

function ts_makeSortable(table) {
    if (table.rows && table.rows.length > 0) {
        var firstRow = table.rows[0];
    }
    if (!firstRow) return;
    
    // We have a first row: assume it's the header, and make its contents clickable links
    for (var i=0;i<firstRow.cells.length;i++) {
        var cell = firstRow.cells[i];
        var txt = ts_getInnerText(cell);
        cell.innerHTML = '<a href="#" class="sortheader" onclick="ts_resortTable(this);return false;">'+txt+'<span class="sortarrow">&nbsp;&nbsp;&nbsp;</span></a>';
    }
        if (cell.getAttribute("initialkey")) {
          ts_resortTable(cell.getElementsByTagName("a")[0]);
        }
}

function ts_getInnerText(el) {
	if (typeof el == "string") return el;
	if (typeof el == "undefined") { return el };
	if (el.innerText) return el.innerText;	//Not needed but it is faster
	var str = "";
	
	var cs = el.childNodes;
	var l = cs.length;
	for (var i = 0; i < l; i++) {
		switch (cs[i].nodeType) {
			case 1: //ELEMENT_NODE
				str += ts_getInnerText(cs[i]);
				break;
			case 3:	//TEXT_NODE
				str += cs[i].nodeValue;
				break;
		}
	}
	return str;
}

function ts_resortTable(lnk) {
    // get the span
    var span;
    for (var ci=0;ci<lnk.childNodes.length;ci++) {
        if (lnk.childNodes[ci].tagName && lnk.childNodes[ci].tagName.toLowerCase() == 'span') span = lnk.childNodes[ci];
    }
    var spantext = ts_getInnerText(span);
    var td = lnk.parentNode;
    var column = td.cellIndex;
    var table = getParent(td,'TABLE');
    
    // Work out a type for the column
    if (table.rows.length <= 1) return;
    var itm = ts_getInnerText(table.rows[1].cells[column]);
    sortfn = ts_sort_caseinsensitive;
    if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) sortfn = ts_sort_date;
    if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) sortfn = ts_sort_date;
    if (itm.match(/^[£$]/)) sortfn = ts_sort_currency;
    if (itm.match(/^[\d\.]+$/)) sortfn = ts_sort_numeric;
    SORT_COLUMN_INDEX = column;
    var firstRow = new Array();
    var newRows = new Array();
    for (i=0;i<table.rows[0].length;i++) { firstRow[i] = table.rows[0][i]; }
    for (j=1;j<table.rows.length;j++) { newRows[j-1] = table.rows[j]; }

    newRows.sort(sortfn);

    if (span.getAttribute("sortdir") == 'down') {
        ARROW = '&nbsp;&nbsp;&uarr;';
        newRows.reverse();
        span.setAttribute('sortdir','up');
    } else {
        ARROW = '&nbsp;&nbsp;&darr;';
        span.setAttribute('sortdir','down');
    }
    
    // We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
    // don't do sortbottom rows
    for (i=0;i<newRows.length;i++) { if (!newRows[i].className || (newRows[i].className && (newRows[i].className.indexOf('sortbottom') == -1))) table.tBodies[0].appendChild(newRows[i]);}
    // do sortbottom rows only
    for (i=0;i<newRows.length;i++) { if (newRows[i].className && (newRows[i].className.indexOf('sortbottom') != -1)) table.tBodies[0].appendChild(newRows[i]);}
    
    // Delete any other arrows there may be showing
    var allspans = document.getElementsByTagName("span");
    for (var ci=0;ci<allspans.length;ci++) {
        if (allspans[ci].className == 'sortarrow') {
            if (getParent(allspans[ci],"table") == getParent(lnk,"table")) { // in the same table as us?
                allspans[ci].innerHTML = '&nbsp;&nbsp;&nbsp;';
            }
        }
    }
        
    span.innerHTML = ARROW;
}

function getParent(el, pTagName) {
	if (el == null) return null;
	else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())	// Gecko bug, supposed to be uppercase
		return el;
	else
		return getParent(el.parentNode, pTagName);
}
function ts_sort_date(a,b) {
    // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
    if (aa.length == 10) {
        dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
    } else {
        yr = aa.substr(6,2);
        if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; }
        dt1 = yr+aa.substr(3,2)+aa.substr(0,2);
    }
    if (bb.length == 10) {
        dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
    } else {
        yr = bb.substr(6,2);
        if (parseInt(yr) < 50) { yr = '20'+yr; } else { yr = '19'+yr; }
        dt2 = yr+bb.substr(3,2)+bb.substr(0,2);
    }
    if (dt1==dt2) return 0;
    if (dt1<dt2) return -1;
    return 1;
}

function ts_sort_currency(a,b) { 
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
    return parseFloat(aa) - parseFloat(bb);
}

function ts_sort_numeric(a,b) { 
    aa = parseFloat(ts_getInnerText(a.cells[SORT_COLUMN_INDEX]));
    if (isNaN(aa)) aa = 0;
    bb = parseFloat(ts_getInnerText(b.cells[SORT_COLUMN_INDEX])); 
    if (isNaN(bb)) bb = 0;
    return aa-bb;
}

function ts_sort_caseinsensitive(a,b) {
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]).toLowerCase();
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]).toLowerCase();
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}

function ts_sort_default(a,b) {
    aa = ts_getInnerText(a.cells[SORT_COLUMN_INDEX]);
    bb = ts_getInnerText(b.cells[SORT_COLUMN_INDEX]);
    if (aa==bb) return 0;
    if (aa<bb) return -1;
    return 1;
}


function addEvent(elm, evType, fn, useCapture)
// addEvent and removeEvent
// cross-browser event handling for IE5+,  NS6 and Mozilla
// By Scott Andrew
{
  if (elm.addEventListener){
    elm.addEventListener(evType, fn, useCapture);
    return true;
  } else if (elm.attachEvent){
    var r = elm.attachEvent("on"+evType, fn);
    return r;
  } else {
//    alert("Handler could not be removed");
  }
} 



/*******************************
  Accessibility baseFontSizing...
 *******************************/
SIZE_UP_MSG = "Increase text size";
SIZE_DOWN_MSG = "Decrease text size";
function displayFontSwitch() {
  document.write("<span id=\"font-switch\" \n");
  document.write("       class=\"button\"\n");
  document.write("       onclick=\"switchFontSize(this);return false;\">\n");
  if(getCookie("baseFontSize") > 0) {
    document.write(SIZE_DOWN_MSG);
  }
  else {
    document.write(SIZE_UP_MSG);
  }
  document.write("</span>");
}



function switchFontSize(element) {
  var fcv = null;
  var bfs = getCookie("baseFontSize");
  if(Number(bfs)) {
    fcv = 0;
    element.firstChild.nodeValue = SIZE_UP_MSG;
  }
  else {
    fcv = 1;
    element.firstChild.nodeValue = SIZE_DOWN_MSG;
  }
  setCookie("baseFontSize", fcv, null, "/");
  setBaseFontSize(fcv);
  redrawLayout();
}

function setBaseFontSize() {
  if(current_browser.version == 6){
    setBaseFontSizeIE6();
  }else{
    var availableSizes = new Array ();
          availableSizes.push(80);
          availableSizes.push(115);
          fcv = getCookie("baseFontSize");
    if(!fcv) {
      fcv = 0;
    }
    try{
    document.body.style.fontSize = availableSizes[fcv].toString() + "%";
    } catch(ex) {
    alert(ex.message);}
  }
}

function setBaseFontSizeIE6(){
  var availableSizesIE6 = new Array();
      availableSizesIE6.push(100);
      availableSizesIE6.push(135);
      fcv = getCookie("baseFontSize");
  if (!fcv){
    fcv = 0;
  }
  document.body.style.fontSize = availableSizesIE6[fcv] + "%";

}

/*****************************
  General function for wide use
 *****************************/
function monthAsWord(m) {
  switch(m) {
    case  0: month = "January";
             break;
    case  1: month = "February";
             break;
    case  2: month = "March";
             break;
    case  3: month = "April";
             break;
    case  4: month = "May";
             break;
    case  5: month = "June";
             break;
    case  6: month = "July";
             break;
    case  7: month = "August";
             break;
    case  8: month = "September";
             break;
    case  9: month = "October";
             break;
    case 10: month = "November";
             break;
    case 11: month = "December";
             break;
    default: month = m;
  }
  return month;
}


/*
   function getCookie(name) {
   value = null;
   cookies = document.cookie.split(";");

   for(var i in cookies) {
   cookie = String(cookies[i]).split("=");
   if(cookie[0].replace(" ", "") == name) {
   value = cookie[1];
   break;
   }
   }
   return value;
   }
 */

// name - name of the desired cookie
// * return string containing value of specified cookie or null if cookie does not exist
function getCookie(name) {
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);

  if (begin == -1) {
    begin = dc.indexOf(prefix);
    if (begin != 0) return null;
  } else
    begin += 2;
  var end = document.cookie.indexOf(";", begin);
  if (end == -1)
    end = dc.length;

  return unescape(dc.substring(begin + prefix.length, end));
}


function setCookie(name, value, expires, path, domain, secure) {
  var curCookie = name + "=" + escape(value) +
    ((expires) ? "; expires=" + expires.toGMTString() : "") +
    ((path) ? "; path=" + path : "") +
    ((domain) ? "; domain=" + domain : "") +
    ((secure) ? "; secure" : "");
  document.cookie = curCookie;
}

function addEventToElement(el, ev, fun) {
  if(document.addEventListener) {
    if(ev.substr(0,2).toLowerCase() == "on") { 
      ev = ev.substr(2);
    }
    el.addEventListener(ev, fun, "false");
  }
  else {
    el.attachEvent(ev, fun);
  }
}

// Used in forms submission... 
function onlySubmitOnce() {
  if (this.submitted) {
    return false;
  } else {
    this.submitted=true;
    return true;
  }
}

function highlightLink(element, componentClass, location) {
  var currentClass = element.className;
  var activeClass = " " + componentClass + "Active";
  if(element && currentClass) {
    element.className = currentClass + activeClass;
    self.status = location;
  }
}

function unhighlightLink(element, componentClass) {
  var currentClass = element.className;
  var activeClass = " " + componentClass + "Active";
  if(element && currentClass) { 
    element.className = currentClass.replace(activeClass, "");
    self.status = "";
  }
}

function getStyleValue(el, prop) {
  var styleValue = null;
  if(el.currentStyle) {
    styleValue = el.currentStyle[prop];
  }
  else {
    if(window.getComputedStyle) {
      styleValue = document.defaultView.getComputedStyle(el, null).getPropertyValue(prop);
    }
  }
  return styleValue;
}



/******************************************************************************/
/* FOLLOWING IS EXPERIMENTAL FUNCTIONALITY FOR DISPLAY/TESTING PURPOSES ONLY. */
/******************************************************************************/
// The following two function are used for displaying help boxes in management pages.
function showHelp(link,element) {
  helpElement = document.getElementById(element);
  helpElement.style.display = "block";
  if(link.offsetLeft)
    helpElement.style.left = link.offsetLeft;
  helpElement.style.position = "absolute";
  if(link.offsetTop)
    helpElement.style.top = link.offsetTop;
}

function hideHelp(element) {
  helpElement = document.getElementById(element);
  helpElement.style.display = "none";
}

// Function display a small pop-up with a definiation of the highlighted terminology.
function explanation(keyword, temptext) {
  if(explanationElement) {
    // Close any existing explanations.
    closeExplanation();
  }
  body = document.getElementsByTagName("body")[0]
    explanationP = document.createElement("p");
  // Look up the text based on the keyword here...
  // For now (and demo purposes), use the temptext value.
  explanationText = document.createTextNode(temptext);

  closeLink = document.createElement("a");
  closeLink.href = "javascript:closeExplanation();";
  img = document.createElement("img");
  img.alt = "close";
  img.src = "/images/icon_close.gif";
  img.style.display = "block";
  img.style.cssFloat = "right";

  boxWidth = 300;

  body.appendChild(explanationP);
  explanationP.appendChild(explanationText);
  closeLink.appendChild(img);
  explanationP.appendChild(closeLink);
  explanationElement = explanationP;

  if ((body.clientWidth - posX) < boxWidth) {
    // This will be functionality to make sure it fits on screen...
    alert("smaller");
  }
  explanationP.className = "explanation";
  explanationP.style.left = posX + "px";
  explanationP.style.position = "absolute";
  explanationP.style.top = posY + "px";
  explanationP.style.width = boxWidth + "px";
  explanationP.style.zIndex = "5000";
}

function closeExplanation() {
  document.body.removeChild(explanationElement);
  explanationElement = null;
}

function stopTimer() {
  // Currently not in use - possible final function would be
  // as part of a timeout for displaying explanations...
  if (timerRunning) {
    window.clearTimeout(timerID); 
    timerRunning = false;
  }
}



var eventPosX = 0;
var eventPosY = 0;
function getEventXandY(e)
{
  var xy = new Array(2);
  if (!e) var e = window.event;

  if (e.pageX || e.pageY)
  {
    eventPosX = e.pageX;
    eventPosY = e.pageY;
  }
  else if (e.clientX || e.clientY)
  {
    eventPosX = e.clientX + document.body.scrollLeft;
    eventPosY = e.clientY + document.body.scrollTop;
  }
  //  alert("posX = " + eventPosX + "\n" +
  //        "posY = " + eventPosY);
  xy[0] = eventPosX;
  xy[1] = eventPosY;
  return xy;
}

