if (document.getElementById && document.createTextNode) {
  attachElEvent(window, "load", floatFootnotes);
}

//displays and hides footnotes inline with the text
function floatFootnotes() {
  var els = getElementsByClassName(document, "fnref", "a");
  for (var i=0; i<els.length; i++) {
    initialiseFootnote(els[i]);
  }
  var footnotes = document.getElementById("footnotes");
  footnotes.style.display = "none";
  for (var i=0; i < footnotes.childNodes.length; i++) {
    footnotes.childNodes[i].className += " footnote";
  }
}

//initialises a floating footnote for reference element el
function initialiseFootnote(el) {
  el.footnote = document.getElementById("footnote" + el.id.replace("fnref",""));
  el.removeChild(el.lastChild);
  el.onmouseover = showFootnote;
  el.onmouseout = hideFootnote;
}

//display associated footnote next to the calling element. This should be assigned to the element's onMouseOver event.
function showFootnote() {
  this.footnote.style.position = "absolute";
  this.footnote.style.top=(getPageOffsetTop(this)+this.offsetHeight+5)+"px";
  this.footnote.style.left=(getPageOffsetLeft(this))+"px";
  document.body.appendChild(this.footnote);
}

//hides the calling element's associated footnote. This should be assigned to the element's onMouseOut event.
function hideFootnote() {
  if (this.footnote.parentNode == document.body) {
    document.body.removeChild(this.footnote);
  }
} 

//returns an array of elements matching the provided node, class name and tag e.g. getElementsByClassName(document, "ext", "a");
function getElementsByClassName(node, classname, tag) {
  var a = [];
  var re = new RegExp("(^| )"+classname+"( |$)");
  if (!tag) { tag = "*"; }
  var els = node.getElementsByTagName(tag);
  for (var i=0, j = els.length; i<j; i++) {
    if (re.test(els[i].className)) { a.push(els[i]); }
  }
  return a;
}

//attach event listener of type to element el
function attachElEvent(el, type, listener) {
  if (el.addEventListener){//DOM
    el.addEventListener(type, listener, false); 
  } else if (el.attachEvent){//IE
    el.attachEvent("on" + type, listener);
  }
}

function getPageOffsetLeft(el) {
  var x = el.offsetLeft;
  if (el.offsetParent != null) { x += getPageOffsetLeft(el.offsetParent); }
  return x;
}

function getPageOffsetTop(el) {
  var y = el.offsetTop;
  if (el.offsetParent != null) { y += getPageOffsetTop(el.offsetParent); }
  return y;
}
