var preloadImages = {};
function preload(label, url)
{
	if (!(label in preloadImages))
	{
		preloadImages[label] = new Image();
		preloadImages[label].src = BaseURL + url;
	}
}

function getPreloadImage(label)
{
	if (label in preloadImages)
	{
		return preloadImages[label].src;
	}
	else if (label != 'empty')
	{
		preload('empty', 'g/px.gif');
		return getPreloadImage('empty');
	}
	else
	{
		return BaseURL + 'g/px/gif';
	}
}

//-- browser detect object
var is = {
	opera: !!window.opera,
	ie: /*@cc_on!@*/false,
	mac: navigator.userAgent.indexOf('Macintosh') > -1
}

Object.extend = function(dest, source, allowOverwrite)
{
	for (var prop in source)
	{
		if (source.hasOwnProperty(prop) && (allowOverwrite || !dest.hasOwnProperty(prop)))
			dest[prop] = source[prop];
	}

	return dest;
}

Object.extend(Array.prototype,
{
	indexOf: function(searchElement, fromIndex)
	{
		var l = this.length, i = 0;
		if (fromIndex)
		{
			i = fromIndex;
			if (i < 0)
			{
				i += l;
				if (i < 0) i = 0;
			}
		}

		while (i < l)
		{
			if (this[i] === searchElement) return i;
			i++;
		}

		return -1;
	}
});

Object.extend(String.prototype,
{
	trim: function()
	{
		return this.replace(/^\s+|\s+$/, '');
	},
	ucFirst: function()
	{
		return this.charAt(0).toUpperCase() + this.substr(1);
	},
	escapeHtml: function()
	{
		var escapeChars = {
			'&': '&amp;',
			'<': '&lt;',
			'>': '&gt;',
			'"': '&quot;'
		};

		return this.replace(/[&<>"]/g, function(c) { return escapeChars[c]; });
	},
	unescapeHtml: function()
	{
		var unescapeChars = {
			'&amp;': '&',
			'&lt;': '<',
			'&gt;': '>',
			'&quot;': '"',
			'&#039;': '\'',
			'&euro;': String.fromCharCode(8364)
		};

		return this.replace(/&(amp|lt|gt|quot|#039|euro);/g, function(c) { return unescapeChars[c]; });
	}
});

Object.extend(Function.prototype,
{
	bind: function()
	{
		var handler = this, args = [].slice.call(arguments, 0), object = args.shift();

		return function()
		{
			return handler.apply(object, args.concat([].slice.call(arguments, 0)));
		}
	}
});

RegExp.escape = function(string)
{
	return string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
}

function Set()
{
	var set = {}, i = arguments.length;
	while (i--)
		set[arguments[i]] = 1;

	return set;
}

// execute methods on DOMload
var DomLoaded =
{
	onload: [],
	loaded: function()
	{
		if (DomLoaded.done) return;
		DomLoaded.done = true;
		if (DomLoaded.timer) clearInterval(DomLoaded.timer);
		for (var i = 0; i < DomLoaded.onload.length; i++)
		{
			if (typeof DomLoaded.onload[i] == 'function')
				DomLoaded.onload[i]();
		}
		DomLoaded.onload = null;
	},
	load: function(fireThis)
	{
		DomLoaded.onload.push(fireThis);

		if (DomLoaded.onload.length == 1)
		{
			if (document.addEventListener)
				document.addEventListener('DOMContentLoaded', DomLoaded.loaded, false);
			else
			{
				DomLoaded.timer = setInterval(function()
				{
					if (document.getElementById('domLoaded'))
						DomLoaded.loaded();
				}, 10);
			}

			// generic fallback
			addEvent(window, 'load', DomLoaded.loaded);
		}
	}
}

//-- generic eventhandling
var addEvent = function()
{
	if (document.addEventListener)
	{
		return function(element, type, handler)
		{
			element.addEventListener(type, handler, false);
		}
	}
	else
	{
		function handleEvent(event)
		{
			event = event || fixEvent(window.event);

			var handlers = this.events[event.type], returnValue;
			for (var i in handlers)
			{
				if (handlers.hasOwnProperty(i) && handlers[i].call(this, event) === false)
					returnValue = false;
			}

			return returnValue;
		}
		function fixEvent(event)
		{
			event.preventDefault = preventDefault;
			event.stopPropagation = stopPropagation;

			return event;
		}
		function preventDefault() { this.returnValue = false; }
		function stopPropagation() { this.cancelBubble = true; }
		function removeAllEvents()
		{
			while ((cachedEvent = eventCache.pop()))
				removeEvent(cachedEvent.element, cachedEvent.type, cachedEvent.handler);
		}

		var guid = 1;
		var eventCache = [];

		return function(element, type, handler)
		{
			if (!handler.$$guid) handler.$$guid = guid++;
			if (!element.events) element.events = {};
			if (!element.events[type])
			{
				element.events[type] = {};
				if (element['on' + type]) element.events[type][0] = element['on' + type];
				element['on' + type] = handleEvent;
			}

			element.events[type][handler.$$guid] = handler;

			if (type != 'unload')
			{
				if (!eventCache.length)
					addEvent(window, 'unload', removeAllEvents);

				eventCache.push(
					{
						element: element,
						type: type,
						handler: handler
					}
				);
			}
		}
	}
}();

var removeEvent = function()
{
	if (document.removeEventListener)
	{
		return function(element, type, handler)
		{
			element.removeEventListener(type, handler, false);
		}
	}
	else
	{
		return function(element, type, handler)
		{
			if (element.events && element.events[type] && handler.$$guid)
				delete element.events[type][handler.$$guid];
		}
	}
}();


function getQueryString(form)
{
	var elements = form.elements, element;
	var qName, qValues, qParts = [];
	var i, j, k, o;
	for (i = 0; i < elements.length; i++)
	{
		element = elements[i];

		if (element.name && !element.disabled)
		{
			qValues = [];

			switch (element.tagName.toLowerCase())
			{
				case 'input':
					k = element.type.toLowerCase();
					if ((k == 'checkbox' || k == 'radio') && !element.checked)
						break;
				case 'textarea':
					qValues.push(element.value);
					break;
				case 'select':
					k = element.options, o = [];
					if (element.multiple)
					{
						for (j = 0; j < k.length; j++)
							if (k[j].selected) o.push(k[j]);
					}
					else
						o.push(k[element.selectedIndex]);

					for (j = 0; j < o.length; j++)
					{
						k = o[j].value;
						if (!k && !('value' in k))
							k = o.text;
						qValues.push(k);
					}

					break;
			}

			if ((k = qValues.length))
			{
				qName = encodeURIComponent(element.name);
				for (j = 0; j < k; j++)
					qParts.push(qName + '=' + encodeURIComponent(qValues[j]));
			}
		}
	}

	return qParts.join('&');
}

function HTMLBuilder(newInstance)
{
	if (this == window)
		return new HTMLBuilder();

	if (HTMLBuilder.instance && !newInstance)
		return HTMLBuilder.instance;

	this.idList = {};
	this.eventHandlers = Set(
		'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown',
		'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout',
		'onkouseover', 'onmouseup', 'onreset', 'onselect', 'onsubmit', 'onunload'
	);

	if (!newInstance)
		HTMLBuilder.instance = this;

	return this;
}
Object.extend(HTMLBuilder.prototype,
{
	built: function(object)
	{
		this.idList = {};

		return this.builtRecursive(object);
	},
	builtRecursive: function(object)
	{
		var element = null, attribute, i;

		if (object.o)
		{
			element = object.o;
		}
		else if (object.n)
		{
			if (object.n == '#text')
			{
				element = document.createTextNode(object.v || '');
			}
			else
			{
				if (object.a && 'name' in object.a)
				{
					try
					{
						element = document.createElement('<' + object.n + ' name=' + object.a['name'] + '>');
						delete object.a['name'];
					}
					catch(e) {}
				}

				if (element || (element = document.createElement(object.n)))
				{
					if (object.a)
					{
						for (attribute in object.a)
						{
							if (object.a[attribute] !== null && object.a.hasOwnProperty(attribute))
							{
								if (	attribute in this.eventHandlers &&
									typeof object.a[attribute] != 'function'
								)
								{
									element[attribute] = new Function(object.a[attribute]);
								}
								else
								{
									if (attribute == 'id')
										this.idList[object.a[attribute]] = element;

									if (attribute == 'style')
										element.style.cssText = object.a['style'];
									else
										element[attribute] = object.a[attribute];
								}
							}
						}
					}

					if (object.c && object.c.length)
					{
						if (	object.n == 'table' &&
							!(object.c[0].n in Set('tbody', 'theader', 'tfooter'))
						)
						{
							element.appendChild(
								this.built(
									{
										n: 'tbody',
										c: object.c
									}
								)
							);
						}
						else
						{
							var childNode;
							for (i = 0; i < object.c.length; i++)
							{
								if (object.c[i] && (childNode = this.builtRecursive(object.c[i])))
									element.appendChild(childNode)
							}
						}
					}
				}
			}
		}

		return element;
	},
	getIdList: function()
	{
		return Object.extend({}, this.idList);
	},
	getElementById: function(id)
	{
		return this.idList[id] || null;
	}
});

function getURLParms(href)
{
	var parms = {};
	var i = href.indexOf('?');
	if (i > -1)
	{
		var get = href.substr(i+1);
		var p1 = get.split('&'), p2;
		i = p1.length;
		while (i--)
		{
			p2 = p1[i].split('=');
			parms[p2[0]] = p2[1];
		}
	}

	return parms;
}

function appendURLParms(url, parms)
{
	var queryString = createQueryString(parms);

	if (queryString)
		queryString = (url.indexOf('?') == -1 ? '?' : '&') + queryString;

	return queryString;
}

function appendDataParms(data, parms)
{
	var queryString = createQueryString(parms);

	if (queryString)
		queryString = (data == '' ? '' : '&') + queryString;

	return queryString;
}

function createQueryString(parms)
{
	var query = [];

	for (var parm in parms)
	{
		if (parms.hasOwnProperty(parm))
			query.push(encodeURIComponent(parm) + '=' + encodeURIComponent(parms[parm]));
	}

	return query.join('&');
}

function unserialize(data)
{
	var re = /(\w):([\d.]+)[:;]/g;
	re.lastIndex = 0;
	return unserialize_do(re, data);
}

function unserialize_do(re, data)
{
	var cur, ret = '', i, key;
	if ((cur = re.exec(data)) !== null)
	{
		switch (cur[1])
		{
			case 'a':
			case 'o':
				ret = cur[1] == 'a' ? [] : {};
				i = cur[2];
				while (i--)
				{
					key = unserialize_do(re, data);
					ret[key] = unserialize_do(re, data);
				}
				break;
			case 's':
				ret = data.substr(re.lastIndex+1, cur[2]);
				re.lastIndex += cur[2] - 1;
				break;
			case 'i':
			case 'd':
				ret = cur[2] / 1;
				break;
			case 'b':
				ret = cur[2] ? true : false;
				break;
		}
	}

	return ret;
}

function print_r(ar, ind)
{
	if (typeof ind == 'undefined') ind = '';
	var s = 'Array\n' + ind + '(\n';
	for (var i in ar)
	{
		if (typeof ar[i] == 'function' || typeof ar[i] == 'undefined') continue;
		s += ind + '\t[' + i + '] => ' + (typeof ar[i] == 'object' ? print_r(ar[i], ind+'\t') : ar[i]) + '\n';
	}

	return s + ind + ')';
}

function getElementsByClassName(className, nodeName, parentElement, callback)
{
	if (!nodeName)
		nodeName = '*';

	if (!parentElement)
		parentElement = document;

	var results = [], s, i = 0, element;

	if (document.evaluate && className.indexOf('|') == -1)
	{
		s = document.evaluate(
			".//" + nodeName + "[contains(concat(' ', @class, ' '), ' " + className + " ')]",
			parentElement,
			null,
			XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
			null
		);

		while ((element = s.snapshotItem(i++)))
		{
			results.push(element);
			if (callback)
				callback(element);
		}
	}
	else
	{
		s = parentElement.getElementsByTagName(nodeName);
		var re = new RegExp('(^|\\s)' + className + '(\\s|$)'), elementClassName;

		while ((element = s[i++]))
		{
			elementClassName = element.className;
			if (	elementClassName.length &&
				(	elementClassName == className ||
					re.test(elementClassName)
				)
			)
			{
				results.push(element);
				if (callback)
					callback(element);
			}
		}
	}

	return results;
}

function is_ignorable(nod)
{
	return (nod.nodeType == 8 || (nod.nodeType == 3 && !/[^\t\n\r ]/.test(nod.data)));
}

function first_child(par, nodeName)
{
	if (par && par.nodeType == 1)
	{
		var res = par.firstChild;
		nodeName = nodeName.toLowerCase();
		do
		{
			if (	!is_ignorable(res)
				&& (!nodeName || res.nodeName.toLowerCase() == nodeName)
			)
				return res;
		}
		while ((res = res.nextSibling));
	}

	return null;
}

function node_after(sib, nodeName)
{
	if (sib)
	{
		nodeName = nodeName.toLowerCase();
		while ((sib = sib.nextSibling))
		{
			if (	!is_ignorable(sib)
				&& (!nodeName || sib.nodeName.toLowerCase() == nodeName)
			)
				return sib;
		}
	}

	return null;
}

function ellipsis(root)
{
	if (ellipsis.__native == undefined)
	{
		ellipsis.__native = true;
		if (document.defaultView && document.defaultView.getComputedStyle)
		{
			var foo = document.createElement('div');
			foo.style.cssText = 'text-overflow:ellipsis;-o-text-overflow:ellipsis';
			if (!foo.style.cssText)
				ellipsis.__native = false;
		}
	}

	if (!ellipsis.__native)
	{
		if (!root)
			getElementsByClassName('ellipsis', null, null, ellipsis_do);
		else
			ellipsis_do(root);
	}
}

function ellipsis_do(root, ellipsis_word)
{
	// speed things up
	if (root.clientWidth)
	{
		root.style.width = root.clientWidth + 'px';
		root.style.position = 'fixed';

		var s = [root], e, o, w;

		while ((e = s.pop()))
		{
			do
			{
				switch (e.nodeType)
				{
					case 1:
						if (e.style.display != 'none')
						{
							if (document.defaultView.getComputedStyle(e, null).getPropertyValue('overflow') == 'hidden')
							{
								ellipsis_overflow(e, ellipsis_word);
							}
							else
							{
								if ((o = e.nextSibling)) s.push(o);
								e = e.firstChild;
								break;
							}
						}

					default:
						e = e.nextSibling;
				}
			}
			while (e);
		}

		root.style.position = '';
	}
}

function ellipsis_overflow(p, ellipsis_word)
{
	var w = p.clientWidth;
	if (w && p.scrollWidth > w)
	{
		var s = [p], e, o, q, l;

		while ((e = s.pop()))
		{
			do
			{
				switch (e.nodeType)
				{
					case 1:
						if ((o = e.previousSibling)) s.push(o);
						e = e.lastChild;
						break;

					case 3:
						if (/[^\t\n\r ]/.test(e.data))
						{
							// Take an educated guess on what the length of the text should be
							q = e.nodeValue;
							l = Math.floor((q.length * w) / p.scrollWidth) - 1;
							if (l > 0)
							{
								do
								{
									e.nodeValue = q.substr(0, --l) + '...';
								}
								while (l && (p.scrollWidth > w || (ellipsis_word && e.nodeValue.charAt(l-1) != ' ')));

								if (l > 0) return;
							}

							e.nodeValue = '';
						}

					default:
						e = e.previousSibling;
				}
			}
			while(e);
		}
	}
}

function addClass(element, className)
{
	var classes = getClassList(element);
	if (classes.indexOf(className) == -1)
	{
		classes.push(className);
		setClassList(element, classes);
	}
}

function removeClass(element, className)
{
	var classes = getClassList(element), index;
	if ((index = classes.indexOf(className)) > -1)
	{
		delete classes[index];
		setClassList(element, classes);
	}
}

function replaceClass(element, oldclass, newclass)
{
	var classes = getClassList(element), index;
	if ((index = classes.indexOf(oldclass)) > -1 && classes.indexOf(newclass) == -1)
	{
		classes[index] = newclass;
		setClassList(element, classes);
	}
}

function hasClass(element, className)
{
	var elementClassName = element.className;
	return	elementClassName.length &&
		(	elementClassName == className ||
			elementClassName.match(new RegExp('(^|\\s)' + className + '(\\s|$)'))
		);
}

function getClassList(element)
{
	return element.className.length ? element.className.split(/\s+/) : [];
}

function setClassList(element, classes)
{
	element.className = classes.join(' ');
}

function getOffsetTop(el, offsetParent)
{
	var offsetTop = 0;
	if (!offsetParent) offsetParent = null;
	do
	{
		offsetTop += el.offsetTop
	}
	while ((el = el.offsetParent) != offsetParent);

	return offsetTop;
}

function getOffsetLeft(el, offsetParent)
{
	var offsetLeft = 0;
	if (!offsetParent) offsetParent = null;
	do
	{
		offsetLeft += el.offsetLeft
	}
	while ((el = el.offsetParent) != offsetParent);

	return offsetLeft;
}

function setRelativePosition(element, offsetElement, offsetTop, offsetLeft)
{
	var offsetParent = null;
	try { offsetParent = element.offsetParent; } catch(e) {}

	var top = getOffsetTop(offsetElement, offsetParent) + offsetTop;
	if (top < 100) top = 100;

	var left = getOffsetLeft(offsetElement, offsetParent) + offsetLeft;
	if (left < 0) left = 0;

	element.style.top = top + 'px';
	element.style.left = left + 'px';
}

function external_links(rootid)
{
	var root = document;
	if (rootid && !(root = document.getElementById(rootid))) return false;

	var c = root.getElementsByTagName('a'), a, i = 0, attr;
	var re = /(^|\s)external(\s|$)/;
	while ((a = c[i++]))
	{
		attr = a.getAttribute('rel');
		if (attr && re.test(attr))
		{
			a.target = '_blank';
		}
	}

	return true;
}

function FolderTree(id, className)
{
	this.list = document.getElementById(id);
	this.className = className || '';

	this.init();
}
Object.extend(FolderTree.prototype,
{
	init: function(id, className)
	{
		if (this.list)
		{
			preload('foldertree_closed', 'g/if/icons/folder_tree_plus.gif');
			preload('foldertree_open', 'g/if/icons/folder_tree_min.gif');
			preload('foldertree_empty', 'g/if/icons/folder_tree.gif');

			if (this.className)
				addClass(this.list, this.className);

			this.init_subs(this.list);

			addEvent(window, 'unload', this.cleanUp.bind(this));
		}
	},
	cleanUp: function()
	{
		this.list = null;
	},
	init_subs: function(list)
	{
		var li = first_child(list, 'li'), img, ul, thisTreeOpened = false, subTreeOpened = false;
		if (li)
		{
			do
			{
				// See if this tree should be opened due to its highlight
				thisTreeOpened = thisTreeOpened || hasClass(li, 'highlight');

				img = document.createElement('img');

				if ((ul = first_child(li, 'ul')))
				{
					subTreeOpened = this.init_subs(ul);
					thisTreeOpened = thisTreeOpened || subTreeOpened;

					if (!subTreeOpened)
						ul.style.display = 'none';

					if (subTreeOpened)
						img.src = getPreloadImage('foldertree_open');
					else
						img.src = getPreloadImage('foldertree_closed');

					img.style.cssText = 'cursor:pointer';
					addEvent(img, 'click', this.toggle);
				}
				else
				{
					img.src = getPreloadImage('foldertree_empty');
				}

				li.insertBefore(img, li.firstChild);
			}
			while ((li = node_after(li, 'li')));
		}

		ul = null, li = null, img = null;

		return thisTreeOpened;
	},
	toggle: function()
	{
		var related_sub = first_child(this.parentNode, 'ul');

		if (related_sub)
		{
			if (related_sub.style.display == 'none')
			{
				related_sub.style.display = 'block';
				this.src = getPreloadImage('foldertree_open');
				if (!this.ellipsed)
				{
					ellipsis(related_sub);
					this.ellipsed = true;
				}
			}
			else
			{
				related_sub.style.display = 'none';
				this.src = getPreloadImage('foldertree_closed');
			}
		}
	}
});

function imageHoverSwap(img, normalStateImg, hoverStateImg)
{
	img.src = getPreloadImage(normalStateImg);

	addEvent(img, 'mouseover', function() { this.src = getPreloadImage(hoverStateImg); });
	addEvent(img, 'mouseout', function() { this.src = getPreloadImage(normalStateImg); });
}

//-- Generic Cookie functies
function getCookie(name)
{
	var cookie = document.cookie.split('; '), i = cookie.length, crumb;
	while (i--)
	{
 		crumb = cookie[i].split('=');
		if (crumb[0] == name)
			return crumb[1] != undefined ? unescape(crumb[1]) : null;
	}

	return null;
}

function setCookie(sName, sValue)
{
	document.cookie = sName + '=' + escape(sValue) + '; expires=Fri, 31 Dec 2099 23:59:59 GMT; path=/; domain=.' + document.domain;
}

function getSessionId()
{
	var sidName = window.sidName || 'TnetId';
	return getCookie(sidName);
}

function timeDiff(starttime)
{
	return ((new Date().getTime()-starttime)/1000).toString().replace('.',',');
}

var categories = [];
var hideSections = {}, skipcookie = true;
function initSectionDisplay()
{
	if (skipcookie)
	{
		preload('sectionHideIcon', 'g/bullets/min.gif');
		preload('sectionShowIcon', 'g/bullets/plus.gif');

		var c = getCookie('klipklapcookie');
		if (c !== null)
		{
			var temp = c.split(','), i = temp.length;
			while (i--)
				hideSections[temp[i]] = 1;
		}
	}

	var l = categories.length;
	while (l--)
	{
		if (hideSections[categories[l]])
		{
			temp = document.getElementById(categories[l]);
			if (temp && typeof temp.onclick == 'function')
			{
				addClass(temp, 'pointer');
				temp.title = 'in/uitklappen';
				temp.onclick();
			}
		}
	}

	skipcookie = false;
	categories = [];
}

function toggleSectionDisplay(img)
{
	var display, cat = document.getElementById(img.id + 'List');
	if (cat)
	{
		if (img.src == getPreloadImage('sectionShowIcon'))
		{
			img.src = getPreloadImage('sectionHideIcon');
			cat.style.display = '';
			ellipsis(cat);
			delete hideSections[img.id];
		}
		else
		{
			img.src = getPreloadImage('sectionShowIcon');
			cat.style.display = 'none';
			hideSections[img.id] = 1;
		}

		if (!skipcookie)
		{
			var temp = [];
			for (var category in hideSections)
				if (hideSections.hasOwnProperty(category))
					temp.push(category);

			setCookie('klipklapcookie', temp.join(','));
		}
	}
}

function toggleStatsGeneratorTable(category)
{
	var pageviews1 = document.getElementById('generatorPageviewsRow1');
	var pageviews2 = document.getElementById('generatorPageviewsRow2');
	var servers1 = document.getElementById('generatorServersRow1');
	var servers2 = document.getElementById('generatorServersRow2');

	if(category == 'pageviews')
	{
		servers1.style.display = 'none';
		servers2.style.display = 'none';
		pageviews1.style.display = '';
		pageviews2.style.display = '';
	}
	else if(category == 'servers')
	{
		pageviews1.style.display = 'none';
		pageviews2.style.display = 'none';
		servers1.style.display = '';
		servers2.style.display = '';
	}
}

// Deprecated function
function winopen(url, width, height)
{
	if (!width) width=460;
	if (!height) height=550;
	if (url.charAt(0) == '/') url = url.substr(1);
	if (url.indexOf('http://') != 0) url = BaseURL + url;
	window.open(url, '_blank', 'toolbar=no,location=no,menubar=no,scrollbars=yes,width='+width+',height='+height+',resizable=yes,status=no');
}

function cancelEvent(e)
{
	if (e.preventDefault)
	{
		e.preventDefault();
	}
	else if (e.cancelBubble != undefined)
	{
		if (e.keyCode) e.keyCode = 0;
		e.returnValue = 0;
		e.cancelBubble = true;
	}

	return false;
}

function check_addmap_form()
{
	if (document.forms['add_map'].elements['mapnaam'].value == '')
	{
		alert('Vul een naam voor deze map in');
	}
	else
	{
		document.forms['add_map'].submit();
	}
}