
// Add event listener. 
// - target : Target element
// - eventType: Event like "click", "change", etc
// - functionRef: Event function
// - capture: apply during capture (true) or bubble (false).  In doubt use false.
function attachEventListener(target, eventType, functionRef, capture)
{
  if (typeof target.addEventListener != 'undefined')
  {
    target.addEventListener(eventType, functionRef, capture);
  }
  else if (typeof target.attachEvent != 'undefined')
  {
    target.attachEvent('on' + eventType, functionRef);
  }
  else
  {
    eventType = 'on' + eventType;
    if (typeof target[eventType] == 'function')
    {
      var oldListener = target[eventType];

      target[eventType] = function()
      {
        oldListener();

        return functionRef();
      }
    }
    else
    {
      target[eventType] = functionRef;
    }
  }
  return true;
}


// add methods to the window.onload
function addLoadListener(fn)
{
  if (typeof window.addEventListener != 'undefined')
  {
    window.addEventListener('load', fn, false);
  }
  else if (typeof document.addEventListener != 'undefined')
  {
    document.addEventListener('load', fn, false);
  }
  else if (typeof window.attachEvent != 'undefined')
  {
    window.attachEvent('onload', fn);
  }
  else
  {
    var oldfn = window.onload;
    if (typeof window.onload != 'function')
    {
      window.onload = fn;
    }
    else
    {
      window.onload = function()
      {
        oldfn();
        fn();
      };
    }
  }
}

// Returns size array (width, height) of viewpart. 
function getViewportSize()
{
  var size = [0,0];
  if (typeof window.innerWidth != 'undefined')
  {
    size = [
        window.innerWidth,
        window.innerHeight
    ];
  }
  else if (typeof document.documentElement != 'undefined'
      && typeof document.documentElement.clientWidth != 'undefined'
      && document.documentElement.clientWidth != 0)
  {
    size = [
        document.documentElement.clientWidth,
        document.documentElement.clientHeight
    ];
  }
  else
  {
    size = [
        document.getElementsByTagName('body')[0].clientWidth,
        document.getElementsByTagName('body')[0].clientHeight
    ];
  }
  return size;
}

// Returns x or y position of element 
// - ele : Element
// - dir : Direction 'x' or 'y'
function getRoughPosition(ele, dir)
{
	var pos = dir == 'x' ? ele.offsetLeft : ele.offsetTop;
	var tmp = ele.offsetParent;
	while (tmp != null)
	{
		pos += dir == 'x' ? tmp.offsetLeft : tmp.offsetTop;
		if(tmp.offsetLeft > 0)
		{
			tmp = null;
		}
		else
		{
			tmp = tmp.offsetParent;
		}
	}
	return pos;
}


/// DROP DOWN MENUS /////

var branch;

// Setup dropdown menu 
// - navid : Menu id
function dropdownMenu(navid)
{
 var isie = typeof document.all != 'undefined'
     && typeof window.opera == 'undefined'
     && navigator.vendor != 'KDE';

  if (typeof document.getElementById == 'undefined'
      || (navigator.vendor == 'Apple Computer, Inc.'
      && typeof window.XMLHttpRequest == 'undefined')
      || (isie && typeof document.uniqueID == 'undefined'))
  {
    return;
  }

  var tree = document.getElementById(navid).getElementsByTagName('ul')[0];
  if (tree)
  {
    branch = tree;
  	var items = tree.getElementsByTagName('li');
    for (var i = 0; i < items.length; i++)
    {
      dropdownTrigger(tree, items[i], navid, isie);
    }
  }
}

// Setup dropdown branch trigger 
// - tree : Menu 
// - li : List item
// - navid : Menu id
// - isie : Is IE
function dropdownTrigger(tree, li, navid, isie)
{
  var opentime;
  var closetime;
  var a = li.getElementsByTagName('a')[0];
  var menu = li.getElementsByTagName('ul').length > 0
      ? li.getElementsByTagName('ul')[0] : null;
  var issub = li.parentNode.parentNode.id == navid;

  attachEventListener(li, 'mouseover', function(e)
  {
	if (unwantedTextEvent()) { return; }
    clearTimeout(closetime);
    if (branch == li) { branch = null; }
    li.className += (li.className == '' ? '' : ' ') + 'activeBranch';
    a.className += (a.className == '' ? '' : ' ') + 'activeBranch';
    
    var target = typeof e.target != 'undefined' ? e.target : window.event.srcElement;
    while (target.nodeName.toUpperCase() != 'LI')
    {
      target = target.parentNode;
    }
    if (target != li) { return; }
    
	if (menu)
    {
      	opentime = window.setTimeout(function()
	    {
	        if (branch)
	        {
	          clearMenus(branch);
	          branch = null;
	        }
	
	        menu.className += (menu.className == '' ? '' : ' ') + 'activeMenu';
	
	        menu.style.left = '0';
       		menu.style.top = issub ? '100%' : '0';
       		
       		if (!issub)
       		{
       			repositionMenu(menu);
       		}
	
	        if (typeof document.uniqueID != 'undefined')
	        {
	          createIframeLayer(menu);
	        }
	      }, 150);
    }
  }, false);

  attachEventListener(li, 'mouseout', function(e)
  {
    if (unwantedTextEvent()) { return; }
  	
  	var related = typeof e.relatedTarget != 'undefined' ? e.relatedTarget : window.event.toElement;
    if (!li.contains(related))
    {
      clearTimeout(opentime);
      branch = li;
    	
      li.className = li.className.replace(/ ?activeBranch/g, '');
	  a.className = a.className.replace(/ ?activeBranch/g, '');
	  if (menu)
      {
         closetime = window.setTimeout(function()
         {
        	menu.className = menu.className.replace(/ ?activeMenu/g, '');
        	
        	menu.style.left = '-1000em';
        	menu.style.top = '-1000em';
        	
       		removeIframeLayer(menu);
       	 }, 150);
      }
    }
  }, false);

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

// Reposition menus if off screen 
// - menu : Menu to check
function repositionMenu(menu, viewsize)
{
	var extent = [
      getRoughPosition(menu, 'x') + menu.offsetWidth + 25,
      getRoughPosition(menu, 'y') + menu.offsetHeight + 25
  ];
  
  var viewsize = getViewportSize();
  
  if (extent[0] > viewsize[0])
  {
  	var offset = menu.offsetWidth
        + menu.parentNode.parentNode.offsetWidth;
    var inset = menu.parentNode.offsetWidth
        - menu.offsetLeft;
    menu.style.left = (0 - offset + (inset * 2)) + 1 + 'px';

  }

  if (extent[1] > viewsize[1])
  {
    var current = parseInt(menu.style.top, 10);
    var difference = extent[1] - viewsize[1];
    menu.style.top = (current - difference) + 'px';
  }  
}

// Clear menus from screen 
// - menu : Menu to check
function clearMenus(root)
{
  var menus = root.getElementsByTagName('ul');
  for (var i = 0; i < menus.length; i++)
  {
    menu = menus[i];
  	menu.className = menu.className.replace(/ ?activeMenu/g, '');
  	
  	menu.style.left = '-1000em';
    menu.style.top = '-1000em';
  	
    removeIframeLayer(menus[i]);
  }
}

// Identify unwanted events coming from text nodes in Safari
function unwantedTextEvent()
{
  return (navigator.vendor == 'Apple Computer, Inc.'
      && (event.target == event.relatedTarget.parentNode
      || (event.eventPhase == 3
      && event.target.parentNode == event.relatedTarget)));
}


// Creates iframe behind menu, bug fix for IE select z-index issue 
// - menu : Menu 
function createIframeLayer(menu)
{
	var layer = document.createElement('iframe');
	layer.tabIndex = '-1';
	layer.src = 'javascript:false;';
	menu.parentNode.appendChild(layer);
	
	layer.style.left = menu.offsetLeft + 'px';
	layer.style.top = menu.offsetTop + 'px';
	layer.style.width = menu.offsetWidth + 'px';
	layer.style.height = menu.offsetHeight + 'px';
}

// Removes iframe created by createIframeLayer method 
// - menu : Menu 
function removeIframeLayer(menu)
{
   var layers = menu.parentNode.getElementsByTagName('iframe');
   while (layers.length > 0)
   {
     layers[0].parentNode.removeChild(layers[0]);
   }
}


// Return array with element size [0] = width, [1] = height
// - elementID : id of html element 
function getElementSize(elementID)
{
	var size = new Array(0,0);
	if(typeof document.getElementById)
	{
		var element = document.getElementById(elementID);
		if(element)
		{
			size[0] = element.offsetWidth;	
			size[1] = element.offsetHeight;
		}
	}
	return size;
}






// Focus form id based on its id.
// - fieldID : Field id.
function focusFormFieldByID(fieldID)
{
	if (typeof document.getElementById) 
	{ 
		var field = document.getElementById(fieldID); 
		if(field)
		{
			field.focus();
		}
	}
}


// Set onclick function, can check for external links. 
document.onclick = function(e)
{
  var target = e ? e.target : window.event.srcElement;

  while (target && !/^(a|body)$/i.test(target.nodeName))
  {
    target = target.parentNode;
  }

  if (target && target.getAttribute('rel')
      && target.rel == 'external')
  {
    var external = window.open(target.href);

    return external.closed;
  }
}
