function tii_dom_createElement (nodeName, attributes)
{
	var isopera = typeof window.opera != 'undefined';
	var isie = typeof document.all != 'undefined'
   		&& !isopera && navigator.vendor != 'KDE';
		
	var newElement;
	try
	{
		newElement = document.createElement (nodeName);
	}
	catch (error)
	{
		return null;
	}
	
	var attributesLength = attributes.length;
	for (var i = 0; i < attributesLength; i++)
	{
		var attribute = attributes [i] [0];
		var value = attributes [i] [1];
		newElement.setAttribute (attribute, value);
		switch (attribute)
		{
			case 'id':
				newElement.id = value;
				break;
			case 'class':
				if (isie)
				{
					newElement.setAttribute ('className', value);
				}
				newElement.className = value;
				break;
			case 'style':
				newElement.style.cssText = newElement.style.cssText + ' ' + value;
				break;
			case 'for':
				if (isie)
				{
					newElement.setAttribute ('htmlFor', value);
				}
				newElement.htmlFor = value;
		}
	}
	
	return newElement;
}

function tii_dom_removeWhitespaceTextNodes (node)
{
  for (var x = 0; x < node.childNodes.length; x++)
  {
    var child = node.childNodes [x];
    if (child.nodeType == 3 && !/\S/.test (child.nodeValue))
    {
      node.removeChild (node.childNodes [x]);
      x--;
    }
    if (child.nodeType == 1)
    {
      tii_dom_removeWhitespaceTextNodes (child);
    }
  }
}
function tii_callFunctionOnWindowLoad (functionToCall)
{
  if (typeof window.addEventListener != 'undefined')
  {
    window.addEventListener ('load', functionToCall, false);
  }
  else if (typeof document.addEventListener != 'undefined')
  {
    document.addEventListener ('load', functionToCall, false);
  }
  else if (typeof window.attachEvent != 'undefined')
  {
    window.attachEvent ('onload', functionToCall);
  }
  else
  {
    var oldFunctionToCall = window.onload;
    if (typeof window.onload != 'function')
    {
      window.onload = functionToCall;
    }
    else
    {
      window.onload = function ()
      {
        oldFunctionToCall ();
        functionToCall ();
      };
    }
  }
}

function tii_callFunctionOnElementLoad (targetId, functionToCall)
{
	var myArguments = arguments;
	tii_callFunctionOnWindowLoad (function ()
		{
			window.loaded = true;
		});
	var targetElement = document.getElementById (targetId);
	if (targetElement == null && !window.loaded)
	{
		var pollingInterval = setInterval (function ()
			{
				if (window.loaded)
				{
					clearInterval (pollingInterval);
				}
				targetElement = document.getElementById (targetId);
				if (targetElement != null)
				{
					clearInterval (pollingInterval);
					var argumentsTemp = new Array ();
					var argumentsTempLength = myArguments.length - 2;
					for (var i = 0; i < argumentsTempLength; i++)
					{
						argumentsTemp [i] = myArguments [i + 2];
					}		
					functionToCall.apply (this, argumentsTemp);
				}
			}, 10);
	}
}

function tii_addEventHandlerOnElementLoad (targetId, eventType, functionToCall, bubbleEventUpDOMTree)
{
	tii_callFunctionOnWindowLoad (function ()
		{
			window.loaded = true;
		});
	var targetElement = document.getElementById (targetId);
	if (targetElement == null && !window.loaded)
	{
		var pollingInterval = setInterval (function ()
			{
				if (window.loaded)
				{
					clearInterval (pollingInterval);
				}
				targetElement = document.getElementById (targetId);
				if (targetElement != null)
				{
					clearInterval (pollingInterval);
					tii_addEventHandler (targetElement, eventType, functionToCall, bubbleEventUpDOMTree);
				}
			}, 10);
	}
}

function tii_addEventHandler (targetElement, eventType, functionToCall, bubbleEventUpDOMTree)
{
  if (typeof targetElement.addEventListener != 'undefined')
  {
    targetElement.addEventListener (eventType, functionToCall, bubbleEventUpDOMTree);
  }
  else if (typeof targetElement.attachEvent != 'undefined')
  {
    targetElement.attachEvent ('on' + eventType, functionToCall);
  }
  else
  {
    eventType = 'on' + eventType;
    if (typeof targetElement [eventType] == 'function')
    {
      var oldListener = targetElement [eventType];
      targetElement [eventType] = function ()
      {
        oldListener ();
        return functionToCall ();
      }
    }
    else
    {
      targetElement [eventType] = functionToCall;
    }
  }

  return true;
}

function tii_removeEventHandler (targetElement, eventType, functionToRemove, bubbleEventUpDOMTree)
{
  if (typeof targetElement.removeEventListener != "undefined")
  {
    targetElement.removeEventListener (eventType, functionToRemove, bubbleEventUpDOMTree);
  }
  else if (typeof targetElement.detachEvent != "undefined")
  {
    targetElement.detachEvent ("on" + eventType, functionToRemove);
  }
  else
  {
    targetElement ["on" + eventType] = null;
  }
  
  return true;
}
var tii_pnav_branch;
var tii_pnav_previousLink;
var tii_pnav_previousLinkTracker;
var tii_pnav_dontResetCurrentLink = false;

function tii_pnav_initializeDropdownMenu (primaryNavId, hideOrShowMenuFunction, changeStateFunction)
{
  var isopera = typeof window.opera != 'undefined';
  var isie = typeof document.all != 'undefined'
    && !isopera && navigator.vendor != 'KDE';
  var issafari = navigator.vendor == 'Apple Computer, Inc.';

  if (typeof document.getElementById == 'undefined'
      || (issafari && typeof window.XMLHttpRequest == 'undefined')
      || (isie && typeof document.uniqueID == 'undefined'))
  {
    return;
  }
  
  var tree = document.getElementById (primaryNavId);
  if (tree)
  {
    tii_pnav_branch = tree;
    var items = tree.getElementsByTagName('li');
    for (var i = 0; i < items.length; i++)
    {
      tii_pnav_setDropdownTrigger (tree, items[i], primaryNavId, isie, hideOrShowMenuFunction, changeStateFunction);
    }

    if (!isopera)
    {
      tii_dom_removeWhitespaceTextNodes (tree);

      var keyevent = issafari || isie ? 'keydown' : 'keypress';
      tii_addEventHandler(document, keyevent, function(e)
      {
        var target = typeof e.target != 'undefined'
            ? e.target : e.srcElement;
        if (tree.contains(target) && target.getAttribute('href'))
        {
		  /*
		  	 keycode 27 = escape key
		  			 37 = left arrow key
		  			 38 = up arrow key
		  			 39 = right arrow key
		  			 40 = down arrow key
		  */
          if (/^(27|37|38|39|40)$/.test(e.keyCode.toString()))
          {
            tii_pnav_setArrowKeyNavigation(tree, target, e.keyCode, isie, hideOrShowMenuFunction, changeStateFunction);

            if (typeof e.preventDefault != 'undefined')
            {
              e.preventDefault();
            }
            return false;
          }
        }
        return true;

      }, false);
    }
	
    if (!isie)
    {
      tree.contains = function (node)
      {
        if (node == null) { return false; }
        if (node == this) { return true; }
        else { return this.contains (node.parentNode); }
      };
    }
  }
}

function tii_pnav_setDropdownTrigger (tree, li, navid, isie, hideOrShowMenuFunction, changeStateFunction)
{
  var opentime, closetime;
  var a = li.getElementsByTagName('a')[0];
  var menu = li.getElementsByTagName('ul').length > 0
      ? li.getElementsByTagName('ul')[0] : li.parentNode.parentNode.id == navid
	  ? li : null;
  var issub = li.parentNode.id == navid;
  
  tii_addEventHandler(a, 'focus', function(e)
  {
    clearTimeout(closetime);
	tii_pnav_resetPreviousLink (a, isie, hideOrShowMenuFunction, changeStateFunction);
    if (menu)
    {
	  changeStateFunction.call (this, a.parentNode, false, 2);
      tii_pnav_makeMenuVisible (menu, issub, li, a, isie, hideOrShowMenuFunction, changeStateFunction);
    }
	else
	{
		var liGrandPar = li.parentNode.parentNode;
		changeStateFunction.call (this, a.parentNode, true, 2);
		changeStateFunction.call (this, liGrandPar, false, 1);
		var currentLi = a.parentNode;
		var currentPrimaryLi = tii_pnav_getPrimaryLi (a);
		var currentUl = currentLi.parentNode;
		var currentPrimaryA = currentPrimaryLi.firstChild;
		if (currentLi != currentPrimaryLi && currentUl.className == '')
		{
			tii_pnav_makeMenuVisible (currentUl, issub, currentPrimaryLi, currentPrimaryA, isie, hideOrShowMenuFunction, changeStateFunction);
			changeStateFunction.call (this, currentPrimaryLi, false, 1);
		}
	}
  }, false);

  tii_addEventHandler(a, 'blur', function(e)
  {
 	  if (a.className.indexOf ('lastpnitem') > -1 && tii_pnav_previousLinkTracker != null &&
	  	  tii_pnav_previousLinkTracker.className.indexOf ('lastpnitem') < 0)
      {
		  if (!tii_pnav_dontResetCurrentLink)
		  {
			  tii_pnav_resetCurrentLink (a, hideOrShowMenuFunction, changeStateFunction);
		  }
      }
  }, false);
  
  tii_addEventHandler(li, 'mouseover', function(e)
  {
    if (tii_pnav_isUnwantedTextEvent ()) { return; }
    clearTimeout(closetime);
    if (tii_pnav_branch == li) { tii_pnav_branch = null; }

    var target = typeof e.target != 'undefined' ? e.target : window.event.srcElement;
    while (target.nodeName.toUpperCase() != 'LI')
    {
      target = target.parentNode;
    }
    if (target != li) { return; }

	tii_pnav_resetPreviousLink (a, isie, hideOrShowMenuFunction, changeStateFunction);

    if (menu)
    {
	  changeStateFunction.call (this, a.parentNode, false, 2);
      opentime = window.setTimeout(function()
      {
        tii_pnav_makeMenuVisible (menu, issub, li, a, isie, hideOrShowMenuFunction, changeStateFunction);
      }, 1);
    }
	else
	{
		changeStateFunction.call (this, li.parentNode.parentNode, false, 1);
	}
  }, false);

  tii_addEventHandler(li, 'mouseout', function(e)
  {
    if (tii_pnav_isUnwantedTextEvent ()) { return; }

    var related = typeof e.relatedTarget != 'undefined' ? e.relatedTarget : window.event.toElement;
    if (!li.contains(related))
    {
      clearTimeout (opentime);
      tii_pnav_branch = li;
      if (menu)
      {
		changeStateFunction.call (this, a.parentNode, false, 0);
        closetime = window.setTimeout (function ()
        {
		  tii_pnav_resetCurrentLink (a, hideOrShowMenuFunction, changeStateFunction);
        }, 1);
      }
	  else
	  {
		changeStateFunction.call (this, a.parentNode, true, 0);
	  }	  
    }
  }, false);

  if (!isie)
  {
    li.contains = function(node)
    {
      if (node == null) { return false; }
      if (node == this) { return true; }
      else { return this.contains(node.parentNode); }
    };
  }
}

function tii_pnav_setArrowKeyNavigation (tree, link, keycode, isie, hideOrShowMenuFunction, changeStateFunction)
{
  var currentPrimaryLi = tii_pnav_getPrimaryLi (link);
  var openClosedPrimary = false;
 
  if (link.parentNode != currentPrimaryLi && link.parentNode.parentNode.className == '')
  {
	  link = currentPrimaryLi.firstChild;
	  openClosedPrimary = true;
  }

  var li = link.parentNode;
  var menu = li.getElementsByTagName('ul').length > 0
      ? li.getElementsByTagName('ul')[0] : null;
  var parent = li.parentNode;
  var isTopLevel = parent.parentNode == tree;

  if (menu)
  {
	  changeStateFunction.call (this, li, false, 0);
  }
  else
  {
	  changeStateFunction.call (this, li, true, 0);
  }

  if (link.className.indexOf ('lastpnitem') > -1)
  {
	  tii_pnav_dontResetCurrentLink = true;
  }
  else
  {
	  tii_pnav_dontResetCurrentLink = false;
  }
  
  switch (keycode)
  {
	case 27:
	  tii_pnav_dontResetCurrentLink = false;
	  tii_pnav_resetCurrentLink (link, hideOrShowMenuFunction, changeStateFunction);
	  break;
	  
    case 37:
	  if (menu || isTopLevel)
	  {
		  tii_pnav_moveToPrevious (li);
	  }
	  else
	  {
		  tii_pnav_moveToPrevious (parent.parentNode);
	  }
      break;

    case 38:
	  if (menu || isTopLevel)
	  {
		changeStateFunction.call (this, link.parentNode, false, 2);
	  }
	  else
	  {
    	  if (li == li.parentNode.firstChild)
	      {
    	    parent.parentNode.firstChild.focus ();
	      }
		  else
		  {
		    tii_pnav_moveToPrevious (li);
		  }
	  }
      break;

    case 39:
	  if (menu || isTopLevel)
	  {
		  tii_pnav_moveToNext (li);
	  }
	  else
	  {
		  tii_pnav_moveToNext (parent.parentNode);
	  }
      break;
	  
    case 40:
	  tii_pnav_dontResetCurrentLink = false;
	  if (menu && openClosedPrimary)
	  {
		openClosedPrimary = false;
		menu.parentNode.firstChild.focus ();
	  }
      if (menu || isTopLevel)
      {
        menu.firstChild.firstChild.focus ();
      }
	  else
	  {
		tii_pnav_moveToNext (li);
	  }
      break;
  }  
}

function tii_pnav_makeMenuVisible (menu, issub, li, a, isie, hideOrShowMenuFunction, changeStateFunction)
{
  if (typeof li.offsetLeft == 'undefined')
  {
	  return;
  }

  changeStateFunction.call (this, a.parentNode, false, 2);

  hideOrShowMenuFunction (menu, false, li);
  menu.style.top = a.offsetHeight + 'px';
}

function tii_pnav_resetPreviousLink (a, isie, hideOrShowMenuFunction, changeStateFunction)
{
	if (tii_pnav_previousLink)
	{
		var prevLi = tii_pnav_previousLink.parentNode;
		var currentLi = a.parentNode;
		var prevPrimaryLi = tii_pnav_getPrimaryLi (tii_pnav_previousLink);
		var currentPrimaryLi = tii_pnav_getPrimaryLi (a);
		
		if (prevLi != prevPrimaryLi)
		{
			changeStateFunction.call (this, prevLi, true, 0);
		}
		
		var hideMenu = prevPrimaryLi != currentPrimaryLi || a == null;
		
		if (hideMenu || (prevLi != prevPrimaryLi && currentLi == currentPrimaryLi))
		{
			changeStateFunction.call (this, prevPrimaryLi, false, 0);

			if (hideMenu)
			{
				var ul = prevPrimaryLi.getElementsByTagName('ul').item (0);
				if (ul)
				{
					hideOrShowMenuFunction (ul, true, null);
				}
			}
		}		
	}
	tii_pnav_previousLinkTracker = tii_pnav_previousLink;
	tii_pnav_previousLink = a;
}

function tii_pnav_resetCurrentLink (a, hideOrShowMenuFunction, changeStateFunction)
{
	var currentLi = a.parentNode;
	var currentPrimaryLi = tii_pnav_getPrimaryLi (a);
	changeStateFunction.call (this, currentPrimaryLi, false, 0);
	if (currentLi != currentPrimaryLi)
	{
		changeStateFunction.call (this, currentLi, true, 0);
	}
	
	var ul = currentPrimaryLi.getElementsByTagName('ul').item (0);
	if (ul)
	{
        closetime = window.setTimeout(function()
      		{
				hideOrShowMenuFunction (ul, true, null);
	        }, 1);
	}	
}

function tii_pnav_getPrimaryLi (a)
{
	if (a.parentNode.parentNode.parentNode.nodeName.toUpperCase ()== 'DIV')
	{
		return a.parentNode;
	}
	else
	{
		return a.parentNode.parentNode.parentNode;
	}
}

function tii_pnav_moveToPrevious (li)
{
      var previous = li.previousSibling;
      if (!previous)
      {
        previous = li.parentNode.childNodes
            [li.parentNode.childNodes.length - 1];
      }
      previous.firstChild.focus ();
}

function tii_pnav_moveToNext (li)
{
    var next = li.nextSibling;
    if (!next)
    {
      next = li.parentNode.childNodes.item (0);
    }
    next.firstChild.focus ();
};

function tii_pnav_isUnwantedTextEvent ()
{
  return (navigator.vendor == 'Apple Computer, Inc.'
      && (event.target == event.relatedTarget.parentNode
      || (event.eventPhase == 3
      && event.target.parentNode == event.relatedTarget)));
}
