   // flwg 2 functions move an element horizontally or vertically w/ ease off
   // tnx to <http://domscripting.com/domsters/scripts/home.js>
function moveElementX(elementID, finalX, delta, fn)
{
   var nodeToMove = document.getElementById(elementID);

   var xpos = parseInt(nodeToMove.offsetLeft);

   if (xpos < finalX)
      xpos += Math.ceil((finalX - xpos) / delta);
   if (xpos > finalX)
      xpos -= Math.ceil((xpos - finalX) / delta);
   nodeToMove.style.left = xpos + 'px';

   if (xpos == finalX)
   {
      clearInterval(nodeToMove.movement);
      if (fn)
         fn();
   }
}

function moveElementY(elementID, finalY, delta, fn)
{
   var nodeToMove = document.getElementById(elementID);

   var ypos = parseInt(nodeToMove.offsetTop);

   if (ypos < finalY)
      ypos += Math.ceil((finalY - ypos) / delta);
   if (ypos > finalY)
      ypos -= Math.ceil((ypos - finalY) / delta);
   nodeToMove.style.top = ypos + 'px';

   if (ypos == finalY)
   {
      clearInterval(nodeToMove.movement);
      if (fn)
         fn();
   }
}

   // return string w/out HTML tags or w/ unescaped single quotes
function getTrueString(str, isHtml)
{
   return isHtml ? str.replace(/<[^>]*>/gi, '') : str.replace(/\\'[']/, '$1, $2');
}

   // use with 'event.keyCode'
function getKey(keyCode)
{
   switch(keyCode)
   {
      case  27: return 'escape';

      case 112: return 'f1';
      case 113: return 'f2';
      case 114: return 'f3';
      case 115: return 'f4';
      case 116: return 'f5';
      case 117: return 'f6';
      case 118: return 'f7';
      case 119: return 'f8';
      case 120: return 'f9';
      case 121: return 'f10';
      case 122: return 'f11';
      case 123: return 'f12';

      case  19: return 'pause';
      case  44: return 'printscreen';
      case 145: return 'scrolllock';

      case   8: return 'backspace';
      case  45: return 'insert';
      case  46: return 'delete';
      case  36: return 'home';
      case  35: return 'end';
      case  33: return 'pageup';
      case  34: return 'pagedown';

      case  37: return 'left';
      case  38: return 'up';
      case  39: return 'right';
      case  40: return 'down';

      case  13: return 'enter';
      case  20: return 'capslock';
      case   9: return 'tab';
      case  32: return 'space';

      default:  return null;
   }
}

   // thanks to David Andersson <http://liorean.web-graphics.com/>
function getIFrameDocRef(ref)
{
   return (typeof ref.contentDocument != 'undefined')
      ? ref.contentDocument
      : (typeof ref.contentWindow != 'undefined')
         ? ref.contentWindow.document
         : (typeof ref.document != 'undefined')
            ? ref.document
            : null;
}

   // thanks to Paul Novitsky paul@novitskisoftware.com
function getElementsByClassName(argClassName, argTagName)
{
// requested class name, optionally bracketed by spaces to handle multiple classes
   var reClassMatch = new RegExp('(^| )' + argClassName + '( |$)');

   var aResult = new Array();

   var sTagName = '*';
   if (argTagName)
      sTagName = argTagName;

   var aEls = document.getElementsByTagName(sTagName);
   for (var iEl = 0; iEl < aEls.length; iEl++)
      if (reClassMatch.test(aEls[iEl].className))
         aResult[aResult.length] = aEls[iEl];

   if (aResult.length == 0)
      aResult = null;

   return aResult;
}

   // tnx to Simon Willison <http://www.sitepoint.com/blog-post-view.php?id=171578>
function addLoadEvent(fn)
{
   var oldonload = window.onload;
   if (typeof window.onload == 'function')
      window.onload = function() { oldonload(); fn(); };
   else
      window.onload = fn;
}

// written by Dean Edwards, 2005 with input from Tino Zijdel - crisp@xs4all.nl
// <http://dean.edwards.name/weblog/2005/10/add-event/>
// <http://therealcrisp.xs4all.nl/upload/addEvent_dean.html>
function addEvent(element, type, handler)
{
   if (element.addEventListener)
      element.addEventListener(type, handler, false);
   else
   {
      if (!handler.$$guid)
         handler.$$guid = addEvent.guid++;
      if (!element.events)
         element.events = {};

      var handlers = element.events[type];
      if (!handlers)
      {
         handlers = element.events[type] = {};
         if (element['on' + type])
            handlers[0] = element['on' + type];
         element['on' + type] = handleEvent;
      }

      handlers[handler.$$guid] = handler;
   }
}
addEvent.guid = 1;

function removeEvent(element, type, handler)
{
   if (element.removeEventListener)
      element.removeEventListener(type, handler, false);
   else if (element.events && element.events[type] && handler.$$guid)
      delete element.events[type][handler.$$guid];
}

function handleEvent(event)
{
   event = event || fixEvent(window.event);
   var returnValue = true;
   var handlers = this.events[event.type];

   for (var i in handlers)
   {
      if (!Object.prototype[i])
      {
         this.$$handler = handlers[i];
         if (this.$$handler(event) === false)
            returnValue = false;
      }
   }

   if (this.$$handler)
      this.$$handler = null;

   return returnValue;
}

function fixEvent(event)
{
   event.preventDefault  = fixEvent.preventDefault;
   event.stopPropagation = fixEvent.stopPropagation;
   return event;
}
fixEvent.preventDefault  = function() { this.returnValue = false; };
fixEvent.stopPropagation = function() { this.cancelBubble = true; };

function sendToDevNull(event)
{
   event = event || fixEvent(window.event);
   event.preventDefault();
   event.stopPropagation();
   return false;
}

function getXploderEvent()
{
/* due to micro$uxx' inane desire to do everything differently, the event is a property of 'window' rather than a global object;
   so, since a frame is a window object, to query events from frame A in frame B or from an iFrame *outside the iFrame* I first
   have to figger out to which frame the desired event belongs [sigh...]
*/
   if (BrowserDetect.browser == 'explorer' && BrowserDetect.version < 6)    // 'Object doesn't support this property or method' -> top.frames[i].event
      return fixEvent(window.event);

   for (var i = 0; i < top.frames.length; i++)
      if (top.frames[i].event)
         return fixEvent(top.frames[i].event);

   return fixEvent(window.event);
}

   // flwg function removes spurious textnodes & comments in w3c compliant browsers [tnx to John Resig]
function cleanWhitespace(element)
{
   element = element || document;

   var temp;
   var currentElement = element.firstChild;
   while (currentElement != null)
   {
      temp = currentElement.nextSibling;

   // the node is a text node and contains nothing but whitespace or is a comment
      if (currentElement.nodeType == 3 && !/\S/.test(currentElement.nodeValue) || currentElement.nodeType == 8)
         element.removeChild(currentElement);
      else if (currentElement.nodeType == 1)
         cleanWhitespace(currentElement);

      currentElement = temp;
   }
}

function getScreenX(windowObj)
{
   windowObj = windowObj || window;

   return windowObj.Left ? windowObj.Left : screenX;
}

function getScreenY(windowObj)
{
   windowObj = windowObj || window;

   return windowObj.Top ? windowObj.Top : screenY;
}

function getOuterWidth(windowObj)
{
   windowObj = windowObj || window;

   if (windowObj.outerWidth)
      return windowObj.outerWidth;
   else if (windowObj.document.documentElement && windowObj.document.documentElement.offsetWidth)
      return windowObj.document.documentElement.offsetWidth;
   else if (windowObj.document.body)
      return windowObj.document.body.offsetWidth;

   return null;
}

function getOuterHeight(windowObj)
{
   windowObj = windowObj || window;

   if (windowObj.outerHeight)
      return windowObj.outerHeight;
   else if (windowObj.document.documentElement && windowObj.document.documentElement.offsetHeight)
      return windowObj.document.documentElement.offsetHeight;
   else if (windowObj.document.body)
      return windowObj.document.body.offsetHeight;

   return null;
}

   // flwg 6 functions tnx to <http://www.quirksmode.org/viewport/compatibility.html>
function getInnerWidth(windowObj)
{
   windowObj = windowObj || window;

   if (windowObj.innerWidth)
      return windowObj.innerWidth;
   else if (windowObj.document.documentElement && windowObj.document.documentElement.clientWidth)
      return windowObj.document.documentElement.clientWidth;
   else if (windowObj.document.body)
      return windowObj.document.body.clientWidth;

   return null;
}

function getInnerHeight(windowObj)
{
   windowObj = windowObj || window;

   if (windowObj.innerHeight)
      return windowObj.innerHeight;
   else if (windowObj.document.documentElement && windowObj.document.documentElement.clientHeight)
      return windowObj.document.documentElement.clientHeight;
   else if (windowObj.document.body)
      return windowObj.document.body.clientHeight;

   return null;
}

function getPageXOffset(windowObj)
{
   windowObj = windowObj || window;

   if (windowObj.pageXOffset)
      return windowObj.pageXOffset;
   else if (windowObj.document.documentElement && windowObj.document.documentElement.scrollLeft)
      return windowObj.document.documentElement.scrollLeft;
   else if (windowObj.document.body)
      return windowObj.document.body.scrollLeft;

   return null;
}

function getPageYOffset(windowObj)
{
   windowObj = windowObj || window;

   if (windowObj.pageYOffset)
      return windowObj.pageYOffset;
   else if (windowObj.document.documentElement && windowObj.document.documentElement.scrollTop)
      return windowObj.document.documentElement.scrollTop;
   else if (windowObj.document.body)
      return windowObj.document.body.scrollTop;

   return null;
}

function getPageWidth(windowObj)
{
   windowObj = windowObj || window;

   if (windowObj.document.documentElement)
   {
      if (windowObj.document.documentElement.offsetWidth < windowObj.document.documentElement.scrollWidth)
         return windowObj.document.documentElement.scrollWidth;
      else
         return windowObj.document.documentElement.offsetWidth;
   }
   else
   {
      if (windowObj.document.body.offsetWidth < windowObj.document.body.scrollWidth)
         return windowObj.document.body.scrollWidth;
      else
         return windowObj.document.body.offsetWidth;
   }

   return null;
}

function getPageHeight(windowObj)
{
   windowObj = windowObj || window;

   if (windowObj.document.documentElement)
   {
      if (windowObj.document.documentElement.offsetHeight < windowObj.document.documentElement.scrollHeight)
         return windowObj.document.documentElement.scrollHeight;
      else
         return windowObj.document.documentElement.offsetHeight;
   }
   else
   {
      if (windowObj.document.body.offsetHeight < windowObj.document.body.scrollHeight)
         return windowObj.document.body.scrollHeight;
      else
         return windowObj.document.body.offsetHeight;
   }

   return null;
}

   // flwg 2 function tnx to <http://www.quirksmode.org/js/events_properties.html>
   // adapted for xPloder 6 'strict' mode
function getMouseX(event)
{
   event = event || window.event;

   if (event.pageX)
      return event.pageX;
   else if (event.clientX && document.documentElement && document.documentElement.scrollLeft)
      return event.clientX + document.documentElement.scrollLeft;
   else if (event.clientX && document.body)
      return event.clientX + document.body.scrollLeft;

   return null;
}

function getMouseY(event)
{
   event = event || window.event;

   if (event.pageY)
      return event.pageY;
   else if (event.clientY && document.documentElement && document.documentElement.scrollTop)
      return event.clientY + document.documentElement.scrollTop;
   else if (event.clientY && document.body)
      return event.clientY + document.body.scrollTop;

   return null;
}

   // flwg 2 functions tnx to <http://www.quirksmode.org/js/findpos.html>
function getPosX(obj)
{
   var trueLeft = 0;
   while (obj.offsetParent)
   {
      trueLeft += obj.offsetLeft;
      obj       = obj.offsetParent;
   }
   return trueLeft;
}

function getPosY(obj)
{
   var trueTop = 0;
   while (obj.offsetParent)
   {
       trueTop += obj.offsetTop;
       obj      = obj.offsetParent;
   }
   return trueTop;
}

   // flwg 2 functions prevent popups and tooltips from disappearing under viewport edges
function fitObjInViewportWidth(Xpos, obj, windowObj)
{
   windowObj = windowObj || window;

   var totalWidth = Xpos + obj.offsetWidth;
   var pageWidth  = getPageXOffset(windowObj) + getInnerWidth(windowObj) - getScrollbarWidth(windowObj);

   var newXpos = Xpos;
   if (pageWidth < totalWidth)
      newXpos = pageWidth - obj.offsetWidth;     // correct for right underlap
   if (newXpos < getPageXOffset(windowObj))
      newXpos = getPageXOffset(windowObj);       // correct for left underlap

   return newXpos;
}

function fitObjInViewportHeight(Ypos, obj, windowObj)
{
   windowObj = windowObj || window;

   var totalHeight = Ypos + obj.offsetHeight;
   var pageHeight  = getPageYOffset(windowObj) + getInnerHeight(windowObj) - getScrollbarWidth(windowObj);

   var newYpos = Ypos;
   if (pageHeight < totalHeight)
      newYpos = pageHeight - obj.offsetHeight;   // correct for bottom underlap
   if (newYpos < getPageYOffset(windowObj))
      newYpos = getPageYOffset(windowObj);       // correct for top underlap

   return newYpos;
}

function getScrollbarWidth(windowObj)
{
   windowObj = windowObj || window;

   return BrowserDetect.browser == 'explorer'   // xPloder is unreliable in quirks mode: document.body.offsetWidth does not change when a scrollbar is necessitated by the doc's width
          ? windowObj.document.documentElement
             ? document.documentElement.offsetWidth - document.documentElement.clientWidth
             : document.body.offsetWidth - document.body.clientWidth
          : windowObj.innerWidth - document.documentElement.clientWidth;
}

function setOpacity(obj, newOpacity)
{
        if ('opacity' in obj.style)      obj.style.opacity      = newOpacity;
   else if ('MozOpacity' in obj.style)   obj.style.MozOpacity   = newOpacity;
   else if ('KhtmlOpacity' in obj.style) obj.style.KhtmlOpacity = newOpacity;
   else if ('filter' in obj.style)       obj.style.filter       = 'alpha(opacity=' + (newOpacity * 100) + ')';
}

function getPath(obj)
{
   obj = obj || window;
   var pName = obj.location ? obj.location.pathname.toLowerCase() : obj.src;   // do this for imgs as well as for pages
   var path  = pName.match(/vitaal\//) ? pName.substring(pName.lastIndexOf('vitaal/') + 7, pName.lastIndexOf('/') + 1) : pName.substring(1, pName.lastIndexOf('/') + 1);
   return path;
}

   // figger out '../' prefix
function getDirLevel()
{
   var path = getPath();
   var prefix = '';
   for (var i = 0; i < path.length; i++)
      if (path.charAt(i) == '/')
         prefix += '../';
   return prefix;
}
