// dette dokument indholder også event handlings funktionerne


function displayTopMenu(navid) // udføres ved load
{
  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);
  if (tree)
  {
    branch = tree;  /* ????  */
    var items = tree.getElementsByTagName('li');
    for (var i = 0; i < items.length; i++)
    {
      dropdownTrigger(tree, items[i], navid, isie); // tree = det element, der udgør menuen
	  												// navid = id'en på menuen
    }
  }
}

function dropdownTrigger(tree, li, navid, isie)
{
	var opentime, closetime;  // ifm fulltop - forsinkelse
  var a = li.getElementsByTagName('a')[0];
  var menu = li.getElementsByTagName('ul').length > 0
      ? li.getElementsByTagName('ul')[0] : null;
	  // hvis der er en undermenu bliver menu sat til ul-elementet - ellers null
  var horiz = tree.className.indexOf('horizontal') != -1;
  // if (....) horiz = true else horiz = false
  // kunne man ikke bare skrive: if tree.className == 'horizontal' { var horiz = true } else .... Prøv senere
  var issub = li.parentNode.id == navid; 
  // if (...) issub = true else issub = false
  // true = first level, false = deeper

  if (menu) // hvis der er en submenu
  {
    li.className += (li.className == '' ? '' : ' ') + 'hasmenu';
	// der tilføjes et className (og en blank hvis der er et className i forvejen)
  }

  attachEventListener(li, 'mouseover', function(e)  
  // tilføj følgende event-listener ved mouseover på listeelementet
  {
	  clearTimeout(closetime);  // ifm fulltop forsinkelse
    a.className += (a.className == '' ? '' : ' ') + 'rollover'; // for at kunne highligthe

// nedenstående test er kun sat på af hensyn til repositioning af menu, hvis over kanten
	  var target = typeof e.target != 'undefined' ? e.target : e.srcElement;
	  while (target.nodeName.toUpperCase() != 'LI')
	  {
		  target = target.parentNode;
	  }
	  if (target != li) {return;}
	  
	if (menu) // hvis der er en undermenu
    {
		if (unwantedTextEvent()) {return;} // ifm fulltop forsinkelse
		opentime = window.setTimeout(function()
		{		// ifm fulltop forsinkelse
	    menu.style.left = horiz ? 
			'auto'  // rettelse til ære for IE7 - erstatter linien nedenfor
			//(isie ? li.offsetLeft + 'px' : 'auto') 
            : '0';
		// horiz er en betingelse - hvis den er true så sættes menuens left til den omsluttende LI's 
		// aktuelle position eller auto alt efter om det er ie eller ej
		// hvis hiriz er falsk sættes menuens left til 0
		// I alle andre end IE er position relative i lister, se JSA side 331 nederst

        menu.style.top = horiz && issub ? 
			'auto'  // rettelse til ære for IE7 - erstatter linien nedenfor
			//(isie ? a.offsetHeight + 'px' : 'auto')
            //: (isie ? li.offsetTop + 'px' : '0');
			: li.offsetTop + 'px'; // erstattet linien ovenfor, så virker det rigtigt i firefox og opera også
			// rettet ifm fulltop
		// hvis horiz er true og det er den øverste menu
		// så sættes menuens top a-taggens aktuelle højde (rykkes højden ned) eller auto 
		// ellers sættes menuens top til listelementets aktuelle top eller 0 
		// Det er kun placering af den første undermenu der skiller horizontal fra vertical 
		// længere ned i hierarkiet er de to principper ens
				
		repositionMenu(menu);
		}, 250);  // ifm fulltop forsinkelse
	}
  }, false);

  attachEventListener(li, 'mouseout', function(e)
  {
	  if (unwantedTextEvent()) {return;} // ifm fulltop forsinkelse
    var related = typeof e.relatedTarget != 'undefined' ? e.relatedTarget : window.event.toElement;
    if (!li.contains(related))
	// if det element cursoren er på vej ind i ikke er indeholdt i listeelementet så er det en ægte mouseout
    {
      clearTimeout(opentime);  // ifm fulltop forsinkelse
      //branch = li;
			
      a.className = a.className.replace(/ ?rollover/g, '');  // fjern rollover className
	  
	   if (menu) // hvis der er en undermenu
      {
						
        closetime = window.setTimeout(function()  // ifm fulltop forsinkelse
        {
          menu.style.left = '-100em';  // flyt ud i det blå
		
		}, 900);   // ifm fulltop forsinkelse
	  }
	}
  }, false);

  if (!isie) 										
  // se JSA side 333 øverst
  // Det handler om, at det kun er IE der udfører contains rigtigt
  // For alle andre browsere må vi tilføje en contains function selv
  // Funktionen er recursive og kører opaf i DOMen 
  {													
    li.contains = function(node)
    {
      if (node == null) { return false; } // ikke indeholdt
      if (node == this) { return true; }  // er indeholdt da det er den samme
      else { return this.contains(node.parentNode); } // udfører denne function et niveau oppe
    };
  }													
}

function unwantedTextEvent()
{
	// for Safari se JSA side 341++
	return (navigator.vendor == 'Apple Computer, Inc.' && (event.target == event.relatedTarget.parentNode || (event.eventPhase == 3 && event.target.parentNode == event.relatedTarget)));
};

function getRoughPosition(ele, dir)
{
	var pos = dir == 'x' ? ele.offsetLeft : ele.offsetTop;
	var tmp = ele.offsetParent;  // se jsa side 247 - bruges når vi skal udregne position
	while (tmp != null)
	{
		pos += dir == 'x' ? tmp.offsetLeft : tmp.offsetTop;
		tmp = tmp.offsetParent;
	}
	return pos;
}

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;
}

function repositionMenu(menu)
{
	var extent = [getRoughPosition(menu, 'x') + menu.offsetWidth + 25, getRoughPosition(menu, 'y') + menu.offsetHeight + 25];
	var viewsize = getViewportSize();
	// nedenstående har jeg selv tilføjet, fordi jeg opererer med "page"
	var pagewidth = 0;
	var pageheight = 0;
	var page = document.getElementById("page");
	if (page)
	{
		pagewidth = page.offsetWidth;
		pageheight = page.offsetHeight;
	}
	var deadareawidth = Math.round((viewsize[0] - pagewidth) / 2);
	var deadareaheight = (viewsize[1] - pageheight);
	var actualviewsizewidth = viewsize[0];
	var actualviewsizeheight = viewsize[1];
	if (deadareawidth > 0)
	{
		actualviewsizewidth -= deadareawidth;
	}
	if (deadareaheight > 0)
	{
		actualviewsizeheight -= deadareaheight;
	}
	// nedenstående er fra bogen - (på nær actualviewsizes)
	if (extent[0] > actualviewsizewidth)
	{
		var offset = menu.offsetWidth + menu.parentNode.parentNode.offsetWidth; // overliggende ul
		if (menu.parentNode.parentNode.className.indexOf('horizontal') == -1)
		{
			var inset = menu.parentNode.offsetWidth - menu.offsetLeft;
			menu.style.left = (0 - offset + (inset * 2)) + 'px';
		}
		else // på niveau 2 er left sat til auto og ikke nul, se tidligere i programmet. 
		// Derfor skal det regnes ud anderledes. Jeg tror det er en mangel i eksemplet i bogen.
		// Jeg har selv tilføjet denne
		{
			var move = extent[0] - actualviewsizewidth;
			menu.style.left = (menu.offsetLeft - move + 25) +'px';
		}
	}
	if (extent[1] > actualviewsizeheight)
	{
		var current = menu.offsetTop;
		// parseInt(menu.style.top, 10); virker kun ved inline styles, se js rapport
		var difference = (extent[1] - actualviewsizeheight);
		menu.style.top = (current - difference) + 'px';
	}
}
							 
				
	
	
	
	


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;
}

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();
      };
    }
  }
}

addLoadListener(function() { displayTopMenu('topMenu'); });
