/* Deze functies zorgen voor het controleren van het menu 
 *
 * Uses: DHTML_API.js
 * Uses: findPosition.js
 * Uses: cookieControl.js
 *
 *
 * -  Bouw een menu van maximaal 2 niveaus, met de volgende structuur:
 *		<a href="..." id="menu1" onClick="controller.showMenu(1);">--1e hoofdmenuitem--</a>
 *				<div id="menu1_sub">
 *					<a href="...">--sublink 1--</a>
 *					<a href="...">--sublink 2--</a>
 *					...etc
 *				</div>
 *		<a href="..." id="menu2" onClick="controller.showMenu(2);">--2e hoofdmenuitem--</a>
 *				<div id="menu2_sub">
 *					<a href="...">--sublink 1--</a>
 *					<a href="...">--sublink 2--</a>
 *					...etc
 *				</div>
 *		..etc
 *		
 *	- Wanneer de state ook daadwerkelijk moet worden hersteld na een new request, dan moet in de 
 *	  onLoad van de body tag een aanroep naar controller.restoreMenuState() staan.
 *	
 *	- De CSS stylen moeten zijn gedefineerd voor ALLE submenu items. #menu1_sub, #menu2_sub, etc
 *
 * 	- Instellingen voor het menu
 *		o GEBRUIK_FADE_EFFECT:			Wel of geen gebruik maken van het fade effect tijdens het zichtbaar maken van het submenu
 *											Opm: true of false. 
 *											Opm: Werkt alleen in IE.
 *		o GEBRUIK_FADE_DUUR:			De tijd die het moet duren voordat de fade is afgelopen. Dit is een duur in seconden. 
 *											Opm: Deze wordt alleen gebruikt als GEBRUIK_FADE_EFFECT true is. 
 *											Opm: >= 0
 *		o  GEBRUIK_ROL_EFFECT:			Wel of geen gebruik maken van het vertical afrol effect. 
 *											Opm: true of false
 *		o  GEBRUIK_FADE_DUUR:			De snelheid waarmee het roleffect moet plaatsvinden.
 *											Opm: Deze wordt alleen gebruikt als GEBRUIK_ROL_EFFECT true is. 
 *											Opm: >= 1 (traagste) en <= 100 (snelste)
 *		o  VERBERG_SUBMENU_NA_TIMEOUT:	Wel of niet verbergen van het submenu na het verstrijken van een aantal seconden nadat het zichtbaar is gemaakt.
 *											Opm: true of false
 *		o  SUBMENU_TIMEOUT_TIJD:			De tijd die moet verstrijken voordat een submenu weer wordt verborgen ndadat het zichtbaar is genmaakt.
 *											Opm: Deze wordt alleen gebruikt als VERBERG_SUBMENU_NA_TIMEOUT true is. 
 *											Opm: >= 0
 *		o  STORE_STATE:					Opslaan van de toestand van het menu, zodat deze kan worden hersteld na verversen van een pagina.
 *											Opm: Wanneer de state ook daadwerkelijk moet worden hersteld na een new request, dan moet in de onLoad van de body tag
 *												een aanroep naar  controller.restoreMenuState() staan.
 *											Opm: true of false
 *											Opm: Zet deze op false als je niet wil dat er gebruik wordt gemaakt van cookies.
 *		o  GEDRAG						De manier waarop het menu wordt gebruilkt.
 *											0:	Wanneer showMenu wordt aangeroepen wordt het menu meteen uitgeklapt en opgeslagen in de state als uitgeklapt
 *											1: (werkt nog niet)	Wanneer showMenu wordt aangeroepen wordt het menu niet uitgeklapt, maar wel in de state als zodanig opgeslagen. Wanneer de pagina wordt
 *												ververst, dan klapt het menu alsnog uit. 
 */ 
 
var GEBRUIK_FADE_EFFECT			= false;
var GEBRUIK_FADE_DUUR			= 2; /* dit is de duration in seconden. Hoger  getal geeft dus een tragere fade */
var GEBRUIK_ROL_EFFECT			= false;
var ROL_EFFECT_SNELHEID			= 5; /* 1 traagste, 100 snelste */
var VERBERG_SUBMENU_NA_TIMEOUT	= false;
var SUBMENU_TIMEOUT_TIJD		= 5000; /* In milliseconden */
var STORE_STATE					= true; 
var GEDRAG						= 0;

/* Hieronder begint de code. Niets aan veranderen! */
var ADD		= 0;
var REMOVE	= 1;

var DISABLE	= true;
var ENABLE	= false;

var model		= new Model();
var view		= new View();
var controller	= new Controller();


/**********************/
/*** Model definitie  */
/**********************/

	/* Deze functie is de definitie voor het Model Object. Dit object bevat de logica */
	function Model() {
		Model.prototype.getMenuState	= getMenuState;
		Model.prototype.setMenuState	= setMenuState;
		Model.prototype.storeMenuState	= storeMenuState;
		Model.prototype.resetMenu		= resetMenu;
	}

	function resetMenu() {
		var i = 1;
		for (;;) {			
			try {
				var menuObj = new getObj('menu' + i + '_sub');			
			} catch (error) {
				break;	/* Er bestaat geen menuitem i */
			}		
			storeMenuState(i, REMOVE);
			i++;
		}	
	}
	
	/* Retourneert een array van ids van submenu's die zichtbaar moeten zijn volgens de opgeslagen state */
	function getMenuState() {
		var arr = (getCookie("visibleMenuIds") == null? "": getCookie("visibleMenuIds")).split("-");	
		if (arr.length == 1 && arr[0] == "")	return new Array(0);
		else									return arr;
	}
	
	/*	Slaat de toestand van het menu op. Als invoer wordt een array van menuIds verwacht. 
	 *	Als op een plek in het array null staat, dan wordt deze waarde niet opgeslagen. 
	 */
	function setMenuState(state) {
		var stateAsString = "";
		for (var i =0; i < state.length; i++) 				
			stateAsString += (stateAsString != ""? "-": "") + (state[i] != null? state[i]: "");
		setCookie('visibleMenuIds', stateAsString);
	}	

	function storeMenuState(menuNr, actionType) {
		if (STORE_STATE)  {
			var visibleMenuIds		= this.getMenuState();
			var newVisibleMenuIds	= new Array(visibleMenuIds.length + 1);
			var found = false;
			for (var i =0; i < visibleMenuIds.length; i++) { 		
				found = visibleMenuIds[i] == menuNr;
				newVisibleMenuIds[i] = visibleMenuIds[i]; 
				if (actionType == REMOVE && visibleMenuIds[i] == menuNr) newVisibleMenuIds[i] = null;
			}
			if (actionType == ADD && !found) newVisibleMenuIds[visibleMenuIds.length + 1] = menuNr; 
			
			this.setMenuState(newVisibleMenuIds);
		}
	}


/**********************/
/*** View definitie   */
/**********************/

	/* Deze functie is de definitie voor het Model Object. Dit object bevat de logica */
	function View() {
		this.checkIt;
		this.rolluit;
		
		View.prototype.closeAll		= closeAll;
		View.prototype.getRows		= getRows;
		View.prototype.rolMenuUit	= rolMenuUit;
		View.prototype.showRow		= showRow;
		View.prototype.userInput	= userInput;
	}

	function closeAll() {
		var i = 1;
		for (;;) {			
			try {
				var menuObj = new getObj('menu' + i + '_sub');			
			} catch (error) {
				break;	/* Er bestaat geen menuitem i */
			}		
			menuObj.style.display = 'none';
			
			/* Alle a's onzichtbaar maken om ze straks zichtbaar te maken met een eventuele fade.
			 * Deze fade werkt met een DLL specifiek voor IE, en zorgt ervoor dat de oude inhoud 
			 * van een element wordt gefaded naar de nieuwe inhoud van een element. In dit geval 
			 * is de oude inhoud dus de onzichtbare a's en de nieuwe inhoud de zichtbare a's.
			 */
			var rows = this.getRows(i);
			for (var j=0; j < rows.length; j++)
				rows[j].style.visibility = 'hidden';		
			i++; 
		}
	}

	function userInput() {	
		if (this.checkIt) clearTimeout(this.checkIt);
		if (this.rolluit) clearTimeout(this.rolluit);
		if (VERBERG_SUBMENU_NA_TIMEOUT) this.checkIt = setTimeout('view.closeAll(1)', SUBMENU_TIMEOUT_TIJD);
	}
		
	function rolMenuUit(menunr, disableEffects) {
		if (document.getElementById) {			
			var x		= findPosX(document.getElementById('menu' + menunr));
			var y		= findPosY(document.getElementById('menu' + menunr)) + 4;		
			var menuObj	= new getObj('menu' + menunr + '_sub');

			menuObj.style.left		= x + 'px';
			menuObj.style.top		= y + 'px';
			menuObj.style.height	= '0';
			menuObj.style.overflow	= 'hidden'; /* clip werkt niet in Mozilla, dus vandaar deze constructie met overflow en height*/
			menuObj.style.display	= 'block';
			menuObj.style.filter	= 'progid:DXImageTransform.Microsoft.Fade(duration=' + GEBRUIK_FADE_DUUR + ')';

			// Alle a's zichtbaar maken met een fade (fade werkt alleen in IE)
			if (GEBRUIK_FADE_EFFECT && !disableEffects) try { menuObj.obj.filters[0].Apply(); } catch (error) {	/* Het kan zijn dat deze DLL niet is geregistreerd, of niet bestaat */}
			var rows = this.getRows(menunr);
			for (var j=0; j < rows.length; j++)
				rows[j].style.visibility = 'visible';		
			if (GEBRUIK_FADE_EFFECT && !disableEffects) try { menuObj.obj.filters[0].Play(); } catch (error) {	/* Het kan zijn dat deze DLL niet is geregistreerd, of niet bestaat */}
			
			this.showRow(0, menunr, this.getRows(menunr).length * 22, disableEffects);
		}
	}
	
	function getRows(menunr) {
		return document.getElementById('menu' + menunr + '_sub').getElementsByTagName('A');
	}

	function showRow(currentPercentage, menunr, hoogte, disableEffects) {
		if (currentPercentage < 100) {
			currentPercentage		= currentPercentage + ((GEBRUIK_ROL_EFFECT && !disableEffects)? ROL_EFFECT_SNELHEID: 100);
			var menuObj				= new getObj('menu' + menunr + '_sub');
			menuObj.style.height	= Math.round((currentPercentage / 100 ) * hoogte) + 'px';
			this.rolluit			= setTimeout('view.showRow(' + currentPercentage + ', ' + menunr + ', ' + hoogte + ', ' + disableEffects + ')', 20);	
		}
	}
	
/***************************/
/*  Controller definitie   */
/***************************/

	function Controller() {
		Controller.prototype.showMenu			= showMenu;
		Controller.prototype.restoreMenuState	= restoreMenuState;
	}

	function showMenu(menunr, disableEffects) {
		if (GEDRAG == 0) {
			model.resetMenu();
			view.closeAll();
			view.userInput();		
			model.storeMenuState(menunr, ADD);			
			view.rolMenuUit(menunr, disableEffects == null? ENABLE: disableEffects);
		} else return; // Nog te bouwen
	}
	
	function restoreMenuState() {
		var visibleMenuIds = model.getMenuState();
		for (var i=0; i < visibleMenuIds.length; i++)
			this.showMenu(parseFloat(visibleMenuIds[i]), DISABLE); // DISABLE: Alle effecten even weglaten, dan herstelt het menu zich sneller.
	}