/**
 * Function which will include javascript files in the same way that
 * PHP's include() works. Use either absolute paths or paths relative
 * to the page in which this script is embedded.
 */
function includeScript(src)
{
	var script = document.createElement('script');
	script.src = src;
	script.type = 'text/javascript';
	var head = document.getElementsByTagName('head')[0];
	head.appendChild(script);
	return true;
}

function includeStyleSheet(src)
{
	if (document.createStyleSheet)
		var stylesheet = document.createStyleSheet(src);

	else
	{
		var styles = "@import url('"+src+"');";
		var stylesheet = document.createElement('link');
		stylesheet.rel = 'stylesheet';
		stylesheet.href = 'data:text/css,' + encodeURIComponent(styles);
		document.getElementsByTagName("head")[0].appendChild(stylesheet);
	}
}


/**
 * Zet een data structuur om in een JSON string.
 * Alleen variabelen van het type 'function' worden niet omgezet.
 *
 * WAARSCHUWING: gebruik deze functie alleen als je zeker weet dat er geen
 * recursie in de datastructuur zit, anders blijft-ie eeuwig doorgaan.
 */
function jsonEncode(data)
{
	var parts = [ ];

	if (data instanceof Array)
	{
		for (var i = 0; i < data.length; i++)
			parts.push(jsonEncode(data[i]));

		return '[' + parts.join(',') + ']';
	}

	if (typeof data == 'object')
	{
		for (var i in data)
			parts.push('"'+jsonEscape(i)+'":' + jsonEncode(data[i]));

		return '{' + parts.join(',') + '}';
	}

	if (typeof data == 'number')
		return data;

	if (data === false)
		return 'false';

	if (data === true)
		return 'true';

	if (typeof data == 'function')
		return '"[function]"';

	return '"' + jsonEscape(data) + '"';
}


/**
 * http://kevin.vanzonneveld.net
 * +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
 * +   improved by: Ates Goral (http://magnetiq.com)
 * +   improved by: marrtins
 * +   improved by: Nate
 * +   improved by: Onno Marsman
 * +   input by: Denny Wardhana
 * +   improved by: Brett Zamir (http://brett-zamir.me)
 * *     example 1: addslashes("kevin's birthday");
 * *     returns 1: 'kevin\'s birthday'
 */
function jsonEscape(str)
{
	return (str+'').replace(/([\\"])/g, "\\$1").replace(/\u0000/g, "\\0").replace(/\n/g, '\\n');
}


// Function comes from quirksmode.org
function getInnerSize()
{
	var x, y;
	if (self.innerHeight) // all except Explorer
	{
		x = self.innerWidth;
		y = self.innerHeight;
	}
	else if (document.documentElement && document.documentElement.clientHeight) // Explorer 6 Strict Mode
	{
		x = document.documentElement.clientWidth;
		y = document.documentElement.clientHeight;
	}
	else if (document.body) // other Explorers
	{
		x = document.body.clientWidth;
		y = document.body.clientHeight;
	}
	return { 'x': x, 'y': y };
}

function getDocumentSize()
{
	var x, y;
	var test1 = document.body.scrollHeight;
	var test2 = document.body.offsetHeight
	if (test1 > test2) // all but Explorer Mac
	{
		x = document.body.scrollWidth;
		y = document.body.scrollHeight;
	}
	else // Explorer Mac; would also work in Explorer 6 Strict, Mozilla and Safari
	{
		x = document.body.offsetWidth;
		y = document.body.offsetHeight;
	}
	return { 'x': x, 'y': y };
}

function getScrollOffset(obj)
{
	// Als er een obj meegeven is, dan de scrollPosities van dat
	// object opzoeken. Anders gaan we ervan dat het window object
	// bedoeld wordt.

	var x = 0, y = 0;

	if (typeof obj == 'object' && obj.nodeType && obj.nodeType == Node.ELEMENT_NODE)
	{
		x = obj.scrollLeft;
		y = obj.scrollTop;
	}
	else if (typeof (window.pageYOffset) == 'number') // Netscape
	{
		x = window.pageXOffset;
		y = window.pageYOffset;
	}
	else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) // IE6 standards mode
	{
		x = document.documentElement.scrollLeft;
		y = document.documentElement.scrollTop;
	}
	else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) // W3C DOM
	{
		x = document.body.scrollLeft;
		y = document.body.scrollTop;
	}
	return { 'x': x, 'y': y };
}

function getRelativePosition(obj, relObj)
{
	// getBoundingClientRect geeft de absolute positie ten opzichte van de viewport en
	// niet ten opzichte van het document!

	// getBoundingClientRect geeft de absolute positie van alle vier kanten van het
	// element: left, top, right en bottom. Maar de rechthoek is wel erg strak genomen
	// een geeft bij spans (ook andere inline elementen ???) 2px teveel aan.

	if (obj.getBoundingClientRect && relObj.getBoundingClientRect)
	{
		var objRect = obj.getBoundingClientRect();
		var relObjRect = relObj.getBoundingClientRect();

		var x = objRect.left - relObjRect.left;
		var y = objRect.top - relObjRect.top;

		if (obj.tagName == 'SPAN' && computedStyle(obj, 'display') == 'inline')
		{
			x -= 2;
			y -= 2;
		}

		if (relObj.tagName == 'SPAN' && computedStyle(relObj, 'display') == 'inline')
		{
			x += 2;
			y += 2;
		}
	}

	else
	{
		var objPos = getAbsolutePosition(obj);
		var relObjPos = getAbsolutePosition(relObj);

		var x = objPos.x - relObjPos.x;
		var y = objPos.y - relObjPos.y;
	}

	return { 'x': x, 'y': y };
}

function getAbsolutePosition(obj)
{
	// Het langslopen van alle offsetParents werkt wel in IE, maar gaat soms fout.
	// IE6 en IE7 hebben een bug, waardoor bij een aantal inline elementen die geen
	// 'position'-stijl hebben, de waarde voor offsetTop en offsetLeft onjuist is.
	// Het lijkt erop dat de offsetTop en offsetLeft van het parent-element er al
	// bij in zitten. Deze bug is tamelijk zeldzaam en het is niet helemaal duidelijk
	// of er nog meer situaties zijn waarin die optreedt en misschien is de fix niet
	// helemaal goed, maar in ieder geval werkt-ie voor Toerengine voldoende. Voor zover
	// ik weet treedt het op bij SPANs en bij TRs, maar ook weer niet altijd. Dus het
	// is eigenlijk niet duidelijk wanneer de bug optreedt en wanneer niet. -- Maarten
//	if (computedStyle(obj, 'display') == 'inline')
//		alert('Functie \'getAbsolutePosition\' niet gebruiken voor inline elementen!');

	var x = 0;
	var y = 0;

	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			x += obj.offsetLeft;
			y += obj.offsetTop;
			obj = obj.offsetParent;
		}
	}
	else if (obj.x && obj.y)
	{
		x += obj.x;
		y += obj.y;
	}

	return { 'x': x, 'y': y };
};

function computedStyle(obj, styleProperty)
{
	if (obj.currentStyle)  // IE
	{
		// IE wil graag de notatie 'paddingTop'
		var prop = styleProperty.replace(/-([a-z])/g, function(wholeMatch, ref1) { return ref1.toUpperCase(); });
		var styleValue = obj.currentStyle[prop];
	}

	else if (typeof getComputedStyle !== 'undefined')  // Mozilla, Opera
	{
		// De andere browsers willen 'padding-top'
		styleValue = document.defaultView.getComputedStyle(obj, null).getPropertyValue(styleProperty);
	}

	else
		styleValue = '';

	return styleValue;
}

function setOpacity(obj, level)
{
	if (isIE && !isIE6 && !isIE7)  // dus IE 8 of hoger
		obj.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity='+(level*100)+')';
	else if (isIE)  // IE6 of IE7
		obj.style.filter = 'alpha(opacity='+(level*100)+')';
	else
	{
		obj.style.opacity = level;
		obj.style.MozOpacity = level;
		obj.style.KhtmlOpacity = level;
	}

	return true;
}


function showHideSelects(action)
{
	var selectElements = document.getElementsByTagName('select');

	if (action == 'hide')
	{
		for (var i = 0; i < selectElements.length; i++)
		{
			if (!selectElements[i].className || !selectElements[i].className.match(/frameworkHidden/))
			{
				selectElements[i].className += ' frameworkHidden';
				if (selectElements[i].style.visibility && selectElements[i].style.visibility == 'visible')
				{
					selectElements[i].className += ' frameworkHiddenWasVisible';
					selectElements[i].style.visibility = 'hidden';
				}
			}
		}
	}
	else if (action == 'show')
	{
		for (var i = 0; i < selectElements.length; i++)
		{
			if (selectElements[i].className.match(/frameworkHiddenWasVisible/))
			{
				selectElements[i].className = selectElements[i].className.replace(/ ?frameworkHiddenWasVisible/, '');
				selectElements[i].style.visibility = 'visible';
			}
			selectElements[i].className = selectElements[i].className.replace(/ ?frameworkHidden/, '');
		}
	}
}


// Browser detectie
var isIE = false;
var isIE6 = false;
var isIE7 = false;
var isIE8 = false;
var isIE9 = false;
var isOpera = false;
var isChrome = false;
var isSafari = false;
var isFirefox = false;
var isMozilla = false;
(function()
{
	if (!navigator.userAgent)
		return false;

	if (navigator.userAgent.indexOf("Opera") >= 0)
	{
		isOpera = true;
		return true;
	}

	var index = navigator.userAgent.indexOf("MSIE");
	if (index >= 0)
	{
		isIE = true;
		isIE6 = parseFloat(navigator.userAgent.substring(index+5), 10) < 7;
		isIE7 = !isIE6 && parseFloat(navigator.userAgent.substring(index+5), 10) < 8;
		isIE8 = !isIE6 && !isIE7 && parseFloat(navigator.userAgent.substring(index+5), 10) < 9;
		isIE9 = !isIE6 && !isIE7 && !isIE8;
		return true;
	}

	if (navigator.userAgent.indexOf("Chrome") >= 0)
	{
		isChrome = true;
		return true;
	}

	if (navigator.userAgent.indexOf("Safari") >= 0)
	{
		isSafari = true;
		return true;
	}

	if (navigator.userAgent.indexOf("Firefox") >= 0)
	{
		isFirefox = true;
		isMozilla = true;
		return true;
	}

	if (navigator.appName == 'Netscape')
	{
		isMozilla = true;
		return true;
	}

	return false;
})();


// Paar constantes definieren, die alle browsers
// van nature ondersteunen, behalve IE.
if (!window.Node)
	var Node =
	{
		'ELEMENT_NODE': 1,
		'ATTRIBUTE_NODE': 2,
		'TEXT_NODE': 3,
		'COMMENT_NODE': 8,
		'DOCUMENT_NODE': 9,
		'DOCUMENT_FRAGMENT_NODE': 11
	};

if (isIE && typeof window.console == 'undefined')
{
	// Er kwamen meldingen binnen met 'console is niet gedefinieerd'. Vreemd, want de console wordt helemaal
	// niet gebruikt in deze website. Het sloopt helaas wel de werking van de site. Daarom zelf maar een
	// console.log gedefinieerd om te kijken waar die meldingen vandaag komen. Resultaat: een hele lading
	// meldingen van 'DivX HiQ Debug: HiQ supported site definition updated 12 Minutes(s) ago'. De DivX plugin
	// is dus de schuldige (in de meeste gevallen; heb ook een paar meldingen ontvangen van
	// 'document.attachevent', herkomst onbekend). DIVX, FIX DIT!! DEZE MELDINGEN HOREN NIET THUIS IN
	// PRODUCTIESOFTWARE!! Heb inmiddels genoeg meldingen gezien. De zelfgedefinieerde console.log blijft in
	// werking, maar verstuurt geen meldingen meer.
	window.console = { 'log': function(logMessage) { return true; } };
}

/**
 * Vervang alle letters met accenten door dezelfde letter zonder accent.
 *
 * Deze functie werkt met charcodes en is dus gevoelig voor charsets.
 * De tabel hier is geschikt voor Latin1.
 */
function removeAccents(str)
{
	// Lijst met reeksen charcodes. Achter elke regel staat welke chars
	// hij matcht (als je tenminste Latin1 gebruikt in je text editor).
	// LET OP: De tekens staan waarschijnlijk niet op volgorde.
	// Tussen haakjes staan de ALT-codes (onder Windows).
	var Match = [
		/[\xC0-\xC5]/g,       // Ä(142) Å(143) Á(181) Â(182) À(183) Ã(199)
		/[\xE0-\xE5]/g,       // â(131) ä(132) à(133) å(134) á(160) ã(198)
		/[\xC8-\xCB]/g,       // É(144) Ê(210) Ë(211) È(212)
		/[\xE8-\xEB]/g,       // é(130) ê(136) ë(137) è(138)
		/[\xCC-\xCF]/g,       // Í(214) Î(215) Ï(216) Ì(222)
		/[\xEC-\xEF]/g,       // ï(139) î(140) ì(141) í(161)
		/[\xD2-\xD6]|\xD8/g,  // Ö(153) Ø(157) Ó(224) Ô(226) Ò(227) Õ(229)
		/[\xF2-\xF6]|\xF8/g,  // ô(147) ö(148) ò(149) ø(155) ó(162) õ(228)
		/[\xD9-\xDC]/g,       // Ü(154) Ú(233) Û(234) Ù(235)
		/[\xF9-\xFC]/g,       // ü(129) û(150) ù(151) ú(163)

		/\xC7/g,        // Ç(128)
		/\xE7/g,        // ç(135)
		/\xC6/g,        // Æ(146)
		/\xE6/g,        // æ(145)
		/\xDD/g,        // Ý(237)
		/\xDF/g,        // ß(225)
		/\xFD|\xFF/g,   // ÿ(152) ý(236)
		/\xD1/g,        // Ñ(165)
		/\xD1/g         // ñ(164)
	];

	// Het aantal items in 'Replace' moet overeenkomen met het aantal
	// in 'Match' en in de goede volgorde staan.
	var Replace = [ 'A', 'a', 'E', 'e', 'I', 'i', 'O', 'o', 'U', 'u', 'C', 'c', 'AE', 'ae', 'Y', 'ss', 'y', 'N', 'n' ];

	for (var i = 0; i < Match.length; i++)
		str = str.replace(Match[i], Replace[i]);

	return str;
};


function xmlEscape(str)
{
	var Match = [ /&/g, /</g, />/g, /'/g, /"/g ];
	var Replace = [ '&amp;', '&lt;', '&gt;', '&#039;', '&quot;' ];

	for (var i = 0; i < Match.length; i++)
		str = str.replace(Match[i], Replace[i]);

	return str;
}

