//ALGEMEEN

function e(id) {
	return document.getElementById(id);
}

function nul(nummer,lengte) {
	while ((nummer+"P").length - 1 < lengte) { nummer = "0" + nummer; }
	return nummer;
}

function indexUitArray(naam,arrayObj,diepNaam) {
	for (var i = 0; i < arrayObj.size; i++) {
		if (diepNaam.length > 0) {
			if (arrayObj[i][diepNaam] == naam) {
				return i;
			}
		} else if (arrayObj[i] == naam) {
			return i;
		}
	}
	return -1;
}

//mag element of string aan meegegeven worden, maakt niet uit...
function toon(id) {
	if (typeof id == 'string') {
		id = e(id);
	}
	if (id != null) {
		id.style.display = 'block';
	}
}

function verberg(id) { 
	if (typeof id == 'string') {
		id = e(id);
	}
	if (id != null) {
		id.style.display = 'none';
	}
}

function toonverberg(id1,id2) {
	toon(id1);
	verberg(id2);
}

// Class name switcher
// ----------------------

ClassName = {
	hasClass:function(element, cls) {
		var reg = new RegExp('\\b'+cls+'\\b');
		return reg.test(element.className);
	},

	addClass:function(element, cls) {
		if(!this.hasClass(element, cls)) {
			element.className += ' ' + cls;
		}
	},

	removeClass:function(element, cls) {
		var reg = new RegExp('\\b'+cls+'\\b', 'g');
		element.className = element.className.replace(reg, '');
	}
}

// EventListener
// ----------------------
EventListener = {
	addEvent:function(element, type, handler) {
		try {
			element.addEventListener(type, handler, false);
		} catch(inferiorBrowserException) {
			if(element.attachEvent) 
				element.attachEvent('on'+type, handler);
			else 
				element['on'+type] = handler;
		}
		return [element, type, handler];
	},

	removeEvent:function(event) {
		var element = event[0], type = event[1], handler = event[2];
		try {
			element.removeEventListener(type, handler, false);
		} catch(inferiorBrowserException) {
			if(element.detachEvent)
				element.detachEvent('on'+type, handler);
			else
				element['on'+type] = null;
		}
	},

	cancelEvent:function(e) {
		try {
			e.preventDefault();
			e.stopPropagation();
		} catch (someException) {
			e.returnValue = false;
		}	return false;
	}
}

// TreeController
// ----------------------

function TreeController(lists,functions) {
	//this.lists = lists;  //onnodige functie?
	this.endDragFunction = functions.endDragFunction;
	this.hoverFunction = functions.hoverFunction;
	this.dragFunction = functions.dragFunction;
	//EventListener.addEvent(list, 'click', this.scope('handleClick'));
	if (lists != null && lists.length) {
		//het is dus een array met ul-lists
		for(listnr=0;listnr<lists.length;listnr++) {
			//alle lijsten aan deze TreeController toevoegen...
			EventListener.addEvent(lists[listnr], 'mousedown', this.scope('startDrag'));
		}
	} else {
		EventListener.addEvent(lists, 'mousedown', this.scope('startDrag'));
	}
	EventListener.addEvent(lists, 'mousemove', this.scope('drag'));
	EventListener.addEvent(document, 'mouseup', this.scope('endDrag'));
}

TreeController.prototype = {
	scope:function(method) {
		var scope = this;
		return function() {
			scope[method].apply(scope, arguments);
		}
	},

	//handleClick:function(e) {
		//wordt nu in ENDDRAG (dus MOUSEUP) afgewerkt!!
	//},
	
	toggle:function(li) {
		var ul = li.getElementsByTagName('ul')[0];
		if(ClassName.hasClass(li, 'open')) {
			ClassName.removeClass(li, 'open');
			ul.style.display = 'none';
		} else {
			ClassName.addClass(li, 'open');
			ul.style.display = 'block';
		}
	},

	startDrag:function(e) {
		var target = e.target || e.srcElement;
		if(/^li$/i.test(target.nodeName)) {
			this.dragTarget = target;	
			document.dragTarget = target; //aangeven dat er in het hele document 'ergens' gedragd wordt!
		}

		return EventListener.cancelEvent(e);
	},

	drag:function(e) {
		var target = e.target || e.srcElement;		
		if (this.hoverFunction && /^li$/i.test(target.nodeName)) { this.hoverFunction( { hoverTarget:target, dragTarget:this.dragTarget, dropTarget:this.dropTarget, dropTargetOnder:this.dropTargetOnder } ); }			
	
		if(!this.dragTarget) return;
		ClassName.addClass(this.dragTarget, 'dragTarget');
	
		if(/^li$/i.test(target.nodeName) ) {
			//als we op een UL zaten, die leeg maken
			if(this.dropUL)
					ClassName.removeClass(this.dropUL, 'dropUL');
			if(this.dropTarget)
					ClassName.removeClass(this.dropTarget, 'dropTarget');
			if(this.dropTargetOnder)
					ClassName.removeClass(this.dropTargetOnder, 'dropTargetOnder');
			var pos = getRelativeCoordinates(e, target);
			if (target.scrollHeight) { var hoogte = target.scrollHeight; } else { var hoogte = target.style.pixelHeight; }
			if (pos.y - (hoogte/2) > 0) {
				//we zitten over de helft van het element, dus aangeven dat het element ERONDER gezet moet worden
				this.dropTarget = "";
				this.dropUL = "";
				this.dropTargetOnder = target;
				ClassName.addClass(target, 'dropTargetOnder');
			} else {
				//we zitten boven de helft dus gewoon dit element de dropTarget maken
				this.dropTargetOnder = "";
				this.dropUL = "";
				this.dropTarget = target;
				ClassName.addClass(target, 'dropTarget');
			}
			if (this.dragFunction) { this.dragFunction( { dragTarget:this.dragTarget, dropTarget:this.dropTarget, dropTargetOnder:this.dropTargetOnder } ); }			
		} else if (	/^ul$/i.test(target.nodeName) && target.childNodes.length == 0) {  //lege UL, met 0 kinderen
			//even van de LI's weghalen dat we op de LI zitten... we zitten namelijk op een kale UL
			if(this.dropTarget)
				ClassName.removeClass(this.dropTarget, 'dropTarget');
			if(this.dropTargetOnder)
				ClassName.removeClass(this.dropTargetOnder, 'dropTargetOnder');
			if(this.dropUL)
				ClassName.removeClass(this.dropUL, 'dropUL');
			this.dropTargetOnder = "";
			this.dropTarget = "";
			this.dropUL = target;
			ClassName.addClass(target, 'dropUL');
			if (this.dragFunction) { this.dragFunction( { dragTarget:this.dragTarget, dropUL:this.dropUL } ); }			
		}
	
		/*
		 && target != this.dropTarget
		*/

		return EventListener.cancelEvent(e);
	},

	endDrag:function(e) {
		//we hebben een mouse-up te pakken...
		//nu controleren of dit een map is en of er NIET op gedropt wordt (en dus een normale klik is... een dropTarget wordt namelijk alleen maar ingesteld als er gedragd wordt)
		var target = e.target || e.srcElement;
		if(/^li$/i.test(target.nodeName)) {
			if(ClassName.hasClass(target, 'folder') && ClassName.hasClass(target, 'dropTarget') == false && ClassName.hasClass(target, 'dropTargetOnder') == false)
				this.toggle(target);
		}
		
		if (this.dropTarget || this.dropTargetOnder || this.dropUL ) {
			try {
				ClassName.removeClass(this.dragTarget, 'dragTarget');
				if (this.dropTarget) { ClassName.removeClass(this.dropTarget, 'dropTarget'); }
				if (this.dropTargetOnder) { ClassName.removeClass(this.dropTargetOnder, 'dropTargetOnder'); }
				if (this.dropUL) { ClassName.removeClass(this.dropUL, 'dropUL'); }
				//eventueel op volgende regel deze voorwaarde toevoegen:  &&(target == this.dropTarget)
				//om te zorgen dat je de drop niet uitvoert als je de muis loslaat buiten de UL
				if(this.dragTarget && this.dropTarget) { 
					this.dropTarget.parentNode.insertBefore(this.dragTarget, this.dropTarget);
				} else if(this.dragTarget && this.dropTargetOnder) {
					//we moeten hem ergens ONDER neerzetten... Er bestaat echter geen insertAfter methode...
					//dus nu kijken of er nog een LI-element NA komt, waar we hem dan VOOR kunnen plaatsen...
					volgende = this.dropTargetOnder;
					//de volgende moet wel een LI zijn natuurlijk...
					var parent = this.dropTargetOnder.parentNode;
					while ( /^li$/i.test(volgende.nodeName) == false && volgende != parent.lastChild) {
						var volgende = volgende.nextSibling;
					}
					//nu kijken of er een volgende LI gevonden is waar we hem onder kunnen poten
					if (volgende.nodeName == "LI" && volgende != this.dropTargetOnder) {
						//volgende LI gevonden
						parent.insertBefore(this.dragTarget, volgende);
					} else {
						//geen LI gevonden
						//nu kijken of de dropTargetOnder aan het einde van de rij was, dan moeten we appendChild gebruiken... anders gewoon voor het volgende element plakken
						if (this.dropTargetOnder == parent.lastChild) {
							//er is wél LI gevonden, en dit is de laatste van de rij... dan dus aan het einde van de rij toevoegen
							parent.appendChild(this.dragTarget);
						} else {
							parent.insertBefore(this.dragTarget, this.dropTargetOnder.nextSibling);
						}	
					}
				} else if(this.dragTarget && this.dropUL ) {
					this.dropUL.appendChild(this.dragTarget, this.dropUL);
				}
				if (this.endDragFunction) { this.endDragFunction( { dragTarget:this.dragTarget, dropTarget:this.dropTarget, dropTargetOnder:this.dropTargetOnder, dropUL:this.dropUL } ); }
			} catch(someException) {}
		}
		this.dropTarget = null;
		this.dropTargetOnder = null;
		this.dropUL = null;
		this.dragTarget = null;
		document.dragTarget = null; //aangeven dat er in het hele document niet meer gedragd wordt!
	}
}

//POSITIE DOM GERELATEERD

	/**
	 * Retrieve the absolute coordinates of an element.
	 *
	 * @param element
	 *   A DOM element.
	 * @return
	 *   A hash containing keys 'x' and 'y'.
	 */
	function getAbsolutePosition(element) {
	  var r = { x: element.offsetLeft, y: element.offsetTop };
	  if (element.offsetParent) {
	    var tmp = getAbsolutePosition(element.offsetParent);
	    r.x += tmp.x;
	    r.y += tmp.y;
	  }
	  return r;
	};

	/**
	 * Retrieve the coordinates of the given event relative to the center
	 * of the widget.
	 *
	 * @param event
	 *   A mouse-related DOM event.
	 * @param reference
	 *   A DOM element whose position we want to transform the mouse coordinates to.
	 * @return
	 *    A hash containing keys 'x' and 'y'.
	 */
	function getRelativeCoordinates(event, reference) {
	  var x, y;
	  event = event || window.event;
	  var el = event.target || event.srcElement;

	  if (!window.opera && typeof event.offsetX != 'undefined') {
	    // Use offset coordinates and find common offsetParent
	    var pos = { x: event.offsetX, y: event.offsetY };

	    // Send the coordinates upwards through the offsetParent chain.
	    var e = el;
	    while (e) {
	      e.mouseX = pos.x;
	      e.mouseY = pos.y;
	      pos.x += e.offsetLeft;
	      pos.y += e.offsetTop;
	      e = e.offsetParent;
	    }

	    // Look for the coordinates starting from the reference element.
	    var e = reference;
	    var offset = { x: 0, y: 0 }
	    while (e) {
	      if (typeof e.mouseX != 'undefined') {
	        x = e.mouseX - offset.x;
	        y = e.mouseY - offset.y;
	        break;
	      }
	      offset.x += e.offsetLeft;
	      offset.y += e.offsetTop;
	      e = e.offsetParent;
	    }

	    // Reset stored coordinates
	    e = el;
	    while (e) {
	      e.mouseX = undefined;
	      e.mouseY = undefined;
	      e = e.offsetParent;
	    }
	  } else {
	    // Use absolute coordinates
	    var pos = getAbsolutePosition(reference);
	    x = event.pageX  - pos.x;
	    y = event.pageY - pos.y;
	  }
	  // Subtract distance to middle
	  return { x: x, y: y };
	}

// AJAX

//waar eventuele dumptekst heengezonden kan worden...
document.writeln("<div id='leeg_dump' style='display:none;'></div>");

	var xmlhttp
	/*@cc_on @*/
	/*@if (@_jscript_version >= 5)
	  try {
	  xmlhttp=new ActiveXObject("Msxml2.XMLHTTP")
	 } catch (e) {
	  try {
	    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
	  } catch (E) {
	   xmlhttp=false
	  }
	 }
	@else
	 xmlhttp=false
	@end @*/
	if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
	 try {
	  xmlhttp = new XMLHttpRequest();
	 } catch (e) {
	  xmlhttp=false
	 }
	}
	
	function xmlhttp_object() {
		/*@cc_on @*/
		/*@if (@_jscript_version >= 5)
		  try {
		  this.obj=new ActiveXObject("Msxml2.XMLHTTP")
		 } catch (e) {
		  try {
		    this.obj=new ActiveXObject("Microsoft.XMLHTTP")
		  } catch (E) {
		   this=false
		  }
		 }
		@else
		this=false
		@end @*/
		if (!this.obj && typeof XMLHttpRequest!='undefined') {
		   try {
		     this.obj = new XMLHttpRequest();
		   } catch (e) {
		     this.obj=false
		   }
		}	
	}

function bezig_met_laden(divid) { 
    document.getElementById(divid).innerHTML = "bezig met laden...";
}

function laadpagina_zeker(pagina,divid,postget,postdata,callback) {

	var vraaga = new xmlhttp_object();
	vraaga.pagina = pagina;
	vraaga.divid = divid;
	//VOLGENDE REGEL IS OPTIONEEL
	if (typeof laatst_geklikt == "string") { vraaga.nummer = laatst_geklikt; }
	if (typeof callback == "string") { vraaga.callback = callback; } else { vraaga.callback = ""; }
	if (typeof postget == "undefined") {
		postget = "GET";
	} else {
		if (postget == "POST" || postget == "GET") { } else {
			postget = "GET";
		}
	}
	
	vraaga.obj.open(postget, pagina ,true);
	if (postget == "POST" && !typeof(postdata) == "undefined") { vraaga.obj.send(postdata); }
	bezig_met_laden(divid);
	 vraaga.obj.onreadystatechange=function() {
	  if (vraaga.obj.readyState==4) {
	     if (vraaga.obj.status==200) {
	        var tekst = vraaga.obj.responseText;
	        document.getElementById(vraaga.divid).innerHTML = tekst;
	        if (typeof pagina_geladen === 'undefined') { } else {
				//VRAAG.NUMMER IS OPTIONEEL
				if (vraaga.callback == "nee") {
				
				} else if (vraaga.callback == "") {
					pagina_geladen(vraaga.pagina,vraaga.divid,tekst,vraaga.nummer); //functie aanroepen dat ie klaar is. Kan de gebruiker zelf invullen evt...
				} else {
					eval(callback);
				}
			}
	     } else { document.getElementById(vraaga.obj.divid).innerHTML = "fout bij laden van opgevraagde pagina: " + vraag.status; }
	  }
	 }
	 vraaga.obj.send(null);

}

function laadpagina(pagina,divid) {

xmlhttp.pagina = pagina;
xmlhttp.divid = divid;
//VOLGENDE REGEL IS OPTIONEEL
xmlhttp.nummer = laatst_geklikt;

xmlhttp.open("GET", pagina ,true);
bezig_met_laden(divid);
 xmlhttp.onreadystatechange=function() {
  if (xmlhttp.readyState==4) {
     if (xmlhttp.status==200) {
        var tekst = xmlhttp.responseText;
        document.getElementById(xmlhttp.divid).innerHTML = tekst;
        if (typeof pagina_geladen === 'undefined') { } else {
			//XMLHTTP.NUMMER IS OPTIONEEL
			pagina_geladen(xmlhttp.pagina,xmlhttp.divid,tekst, xmlhttp.nummer); //functie aanroepen dat ie klaar is. Kan de gebruiker zelf invullen evt...
		}
     } else { document.getElementById(xmlhttp.divid).innerHTML = "fout bij laden van opgevraagde pagina: " + xmlhttp.status; }
  }
 }
 xmlhttp.send(null)

}

function laad2paginasnaelkaar(pagina,divid,pagina2,divid2) {

	var vraaga = new xmlhttp_object();
	var vraag = vraaga.obj;
	vraag.pagina2 = pagina2;
	vraag.divid2 = divid2;
	vraag.pagina = pagina;
	vraag.divid = divid;
	//VOLGENDE REGEL IS OPTIONEEL
	if (typeof laatst_geklikt == "string") { vraag.nummer = laatst_geklikt; }
	if (typeof callback == "string") { vraag.callback = callback; } else { vraag.callback = ""; }
	if (typeof postget == "undefined") {
		postget = "GET";
	} else {
		if (postget == "POST" || postget == "GET") { } else {
			postget = "GET";
		}
	}

	vraag.open(postget, pagina ,true);
	if (postget == "POST" && !typeof(postdata) == "undefined") { vraag.send(postdata); }
	bezig_met_laden(divid);
	 vraag.onreadystatechange=function() {
	  if (vraag.readyState==4) {
		 if (vraag.status==200) {
			var tekst = vraag.responseText;
	        document.getElementById(vraag.divid).innerHTML = tekst;
	        if (typeof pagina_geladen === 'undefined') { } else {
				//VRAAG.NUMMER IS OPTIONEEL
				if (vraag.callback == "nee") {
				
				} else {
					pagina_geladen(vraag.pagina,vraag.divid,tekst,vraag.nummer); //functie aanroepen dat ie klaar is. Kan de gebruiker zelf invullen evt...
				}
			}
			laadpagina_zeker(vraag.pagina2, vraag.divid2);
		} else { document.getElementById(vraag.divid).innerHTML = "fout bij laden van opgevraagde pagina: " + vraag.status; }
	  }
	 }
	 vraag.send(null)
}

//COOKIE GEBEUREN

function maak_Cookie(naam,waarde,dagen) {
	if (dagen) {
		var datum = new Date();
		datum.setTime(datum.getTime()+(dagen*24*60*60*1000));
		var verloopt = "; expires="+datum.toGMTString();
	}
	else var verloopt = "";
	document.cookie = naam+"="+waarde+verloopt+"; path=/";
}

function lees_Cookie(naam) {
	var nameEQ = naam + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function verwijder_Cookie(naam) {
	maak_Cookie(naam,"",-1);
}

//DATUM / TIJD

function datum_tijdnu() {
	var tijd = new Date();
	return nul(tijd.getHours(),2) + ":" + nul(tijd.getMinutes(),2) + ":" + nul(tijd.getSeconds(),2);
}