function extraActionsThruXmlHttp(targets)
{
	addEventToTargets(targets, 'click', _extraActionsThruXmlHttp, 'div.extra-actions ul.links li[class] a');
};

function _extraActionsThruXmlHttp(e)
{
	/*var e = e || fixEvent(e);*/

	var container = new DOMQuery("div.extra-actions").get(0);

	var item = this;

	var li = getSiblingNode(item, 'up', 'li');
	if(!li)
		return;

	var topicid = item.href.replace(/.+(insert_topicreport|insert_bookmark|add_keywords|delete_keywords|insert_notification|rate|set_topic_posthistory|rate)(\/\D+)?\/(\d+)(.+)?/, '$3');
	if(!topicid)
		return;

	var classNames = jscss('get', li), request, formName;
	for(var i = 0; i < classNames.length;i++)
	{
		switch(classNames[i])
		{
			case 'topic-add-keyword':
				request = 'action=add_keywords&data%5Btype%5D=topic&data%5Bid%5D='+topicid;
				formName = 'form-add-keywords';
				var onsubmitcallback = function ()
				{
					var keywords = new DOMQuery('dl.topic-keywords dd').get(0);

					if(!keywords)
						return;

					var newKeywords = new DOMQuery('form#form-add-keywords input#keywords').get(0).value;
					var listTopicsUrl = new DOMQuery('a', keywords).get(0).href;

					newKeywords = newKeywords.split(' ');

					for(var j = 0; j < newKeywords.length; j++)
						keywords.appendChild(createDOMNode('a', { 'href' : listTopicsUrl.replace(/=.+/i, '=' + newKeywords[j]) }, [ ' ' + newKeywords[j] ]));
				};
			break;
			case 'topic-delete-keyword':
				request = 'action=delete_keywords&data%5Btype%5D=topic&data%5Bid%5D='+topicid;
				formName = 'form-delete-keywords';
				var onsubmitcallback = function ()
				{
					var keywords = new DOMQuery('dl.topic-keywords dd').get(0);

					if(!keywords)
						return;

					var newKeywords = new DOMQuery('form#form-delete-keywords input#keywords').get(0).value;
					var listTopicsUrl = new DOMQuery('a', keywords).get(0).href;

					newKeywords = newKeywords.split(' ');

					for(var j = 0; j < newKeywords.length; j++)
						keywords.appendChild(createDOMNode('a', { 'href' : listTopicsUrl.replace(/=.+/i, '=' + newKeywords[j]) }, [ ' ' + newKeywords[j] ]));
				};
			break;
			case 'topic-report':
				request = 'action=insert_topicreport&data%5Btopicid%5D='+topicid;
				formName = 'form-insert-topicreport';
			break;
			case 'topic-bookmark':
				request = 'action=insert_bookmark&data%5Btopicid%5D='+topicid;
				formName = 'form-insert-bookmark';
			break;
			case 'topic-notification':
				request = 'action=insert_notification&data%5Btype%5D=topic&data%5Bid%5D='+topicid;
				formName = 'form-insert-notification';
			break;
			case 'topic-posthistory':
				request = 'action=set_topic_posthistory&data%5Btopicid%5D='+topicid;
				formName = 'form-posthistory-set';
			break;
			case 'topic-rate':
				request = 'action=rate&data%5Btype%5D=topic&data%5Bid%5D='+topicid;
				formName = 'form-rate';
			break;
		}

		if(request)
			break;
	}

	if(!request)
		return;

	var result = xmlHttpForm( this, request, container, formName, onsubmitcallback );

	if(result)
		e.preventDefault();
};

function updateMessagesThruXmlHttp(targets)
{
	var items = getTargets(targets, "ol.messages li.message ul.message-links li.message-edit a");
	for(var i = 0, item;(item=items.get(i));i++)
	{
		addEvent(item, 'click',
			function(e)
			{
				var messageid = this.href.replace(/.+update_message\/(\d+)(.+)?/, '$1');
				if(!messageid)
					return true;

				var container = new DOMQuery("ol.messages li#message-" + messageid +" div.message-content").get(0);

				var result = xmlHttpForm(
						this,
						'action=update_message&data%5Bmessageid%5D='+messageid,
						container,
						'form-update-message',
						function()
						{
							var request = 'action=view_message&data%5Bmessageid%5D='+messageid;
							var resultreq = httpreq_string(request, null, null, false);

							var target = new DOMQuery('div.message-content-content', container).get(0);
							while(target.childNodes.length > 0)
							{
								target.removeChild(target.firstChild);
							}

							var source = new DOMQuery('div#core form.primary-input dl.property-list dt:first-child + dd', resultreq.responseXML).get(0);
							while(source.childNodes.length > 0)
							{
								target.appendChild( source.removeChild(source.firstChild) );
							}
						}
				);

				if(result)
					e.preventDefault();
			}
		);
	}
};



function xmlHttpForm(invoker, request, container, formIdentifier, onsubmitcallback)
{
	if(formIdentifier)
	{
		var oldForm = new DOMQuery('form#'+formIdentifier, container).get(0);
		if(oldForm)
		{
			oldForm.parentNode.removeChild(oldForm);
			jscss('remove', invoker, 'request-active');
			return true;
		}
	}

	if(!container)
		return false;

	var items = new DOMQuery('form.primary-input, a[class^="request"]', container);
	for(var i = 0, item;(item = items.get(i));i++)
	{
		switch(item.tagName.toLowerCase())
		{
			case 'form':
				item.parentNode.removeChild(item);
			break;
			case 'a':
				jscss('remove', item, 'request-active');
			break;
		}
	}

	jscss('add', invoker, 'request-active');

	var onsubmit = function(e)
	{
		if(e.defaultPrevented)
			return false;

		jscss('add', invoker, 'request-running');

		/* find out wether preview or submit has been hit */
		if(e && e.type == "submit" && typeof e.explicitOriginalTarget != 'undefined' && e.explicitOriginalTarget.name == "data[preview]")
			return true;

		var request = gatherHttpForm(this);
		updatereq = httpreq_string(request, null, null, false);
		if(updatereq.getResponseHeader('X-Errormessage'))
		{
			alert( updatereq.getResponseHeader('X-Errormessage') );
			jscss('remove', invoker, 'request-running');
		}
		else
		{
			if(onsubmitcallback)
			{
				onsubmitcallback();
			}

			this.parentNode.removeChild(this);

			jscss('remove', invoker, 'request-running');
			jscss('add', invoker, 'request-completed');
			setTimeout(function() { jscss('remove', invoker, 'request-completed'); jscss('remove', invoker, 'request-active'); }, 5000);
		}

		e.preventDefault();
	};

	return requestForm(request, container, onsubmit, invoker);
};

function requestForm(requestURL, container, onsubmit, invoker)
{
	jscss('add', invoker, 'request-running');
	var formreq = httpreq_string(requestURL, null, null, false, 'GET');

	if( formreq.readyState == 4 )
	{
		if(formreq.getResponseHeader('X-Errormessage'))
		{
			alert( formreq.getResponseHeader('X-Errormessage') );
			jscss('remove', invoker, 'request-running');
			return true;
		}
		else
		{
			var form = getElementFromXHR(formreq, 'form.primary-input', container);

			if(!form)
			{
				return false;
			}

			jscss('add', form, 'extrequest');

			container.appendChild( form );

			/*
				To prevent the onsubmit() function to submit the form using a XHR,
				we have to store wether any previous action has stopped the default action
				(submitting of the form).
				So, we attach a special event at the propagation-phase (before all events[]
				do their work) at the parentNode, and modify the event-object to store
				wether preventDefault() has been called.
				Then, the second event-listener is called during the bubble-phase - and it
				checks wether the event has determined preventDefault() has been called.

				However... IE must die!
				It doesn't support propagation for submit-events, so we use the addEvent's behaviour
				of calling the functions in sequence of assignment to emulate the behaviour.
			*/

			var eventTarget = form;
			if(form.addEventListener)
			{
				var eventTarget = eventTarget.parentNode;
			}

			/* only attach the handler on the container once */
			if(eventTarget.tagName == 'form' || typeof eventTarget.__preventDefaultHandler == 'undefined')
			{
				addEvent.eventListenerUseCapture = true;
				addEvent(eventTarget, 'submit', function(e)
				{
					e.__preventDefault = e.preventDefault;
					e.preventDefault = function()
					{
						e.defaultPrevented = true;
						e.__preventDefault();
					};
				});
				addEvent.eventListenerUseCapture = false;
				eventTarget.__preventDefaultHandler = true;
			}

			_init(events, form.parentNode);

			addEvent(form, 'submit', onsubmit);

			jscss('remove', invoker, 'request-running');

			return true;
		}
	}
};

function gatherHttpForm(form)
{
	var items = form.elements;
	var str = [ ];

	for(var i = 0, item;(item=items[i]);i++)
	{
		switch( item.tagName.toLowerCase() )
		{
			case 'input':
				switch(item.type)
				{
					case 'text':
					case 'hidden':
					case 'password':
						str.push(item.name+'='+ escape( item.value ) );
					break;
					case 'radio':
					case 'checkbox':
						if(item.checked)
						{
							str.push(item.name+'='+ encodeURI( item.value ) );
						}
					break;
					case 'file':
						if(item.value)
						{
							throw new Error("I can't handle file-uploads; I'll submit the form using a normal request.");
						}
					break;
				}
			break;
			case 'select':
				str.push(item.name+'='+ encodeURI( item.options[item.selectedIndex].value ) );
			break;
			case 'textarea':
				str.push(item.name+'='+ encodeURI( item.value ) );
			break;
		}
	}

	return str.join('&');
};

function httpreq_xml(request, callback, url, async)
{
	var xmlurl = url || board_script_url + '/../xml_input.php';
  	var xmlParser, xmlDocument, req;

	if(window.XMLHttpRequest)
	{
		/* safari 1.3/2.0 doesn't support DOMParser */
		if(typeof DOMParser == "undefined")
			return false;

		req = new XMLHttpRequest();
		xmlParser = new DOMParser();
		xmlDocument = xmlParser.parseFromString(request, 'text/xml');
	}
	else if(window.ActiveXObject)
	{
		req = new ActiveXObject("MSXML2.XMLHTTP.3.0");

		xmlDocument = new ActiveXObject('Msxml2.DOMDocument.3.0');
		xmlDocument.async = false;
		xmlDocument.loadXML(request);
	}

	xmlDocument.insertBefore(xmlDocument.createProcessingInstruction("xml", "version='1.0'"), xmlDocument.firstChild);

	if(callback)
		req.onreadystatechange = callback;

	req.open("POST", xmlurl, (typeof async == "boolean" ? async : true) );

	if(window.XMLHttpRequest)
	{
		req.setRequestHeader('Content-Type', 'text/xml; utf-8');
	}

	req.send(request);

	return req;
};

function httpreq_string(request, callback, url, async, method)
{
  	var req;
	var xmlurl = url || board_script_url;
	method = method || "POST";
  	async = (typeof async == "boolean" ? async : true);

	if(window.XMLHttpRequest)
	{
		req = new XMLHttpRequest();
	}
	else if(window.ActiveXObject)
	{
		req = new ActiveXObject("MSXML2.XMLHTTP.3.0");
	}

	if(callback)
		req.onreadystatechange = callback;

	if(req.overrideMimeType)
		req.overrideMimeType('text/xml');

	request += '&dont_meta_refresh=1';

	if(method == "GET")
	{
		req.open(method, xmlurl + '?' + request, async );
		req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
		req.send(null);
	}
	else
	{
		req.open(method, xmlurl, async );
		req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
		req.send(request);
	}

	return req;
};

/* the container specifies the desired endpoint for the node */
function getElementFromXHR(transport, selector, container)
{
	var root;
	if(isWebKit || !transportHasValidResponseXML(transport))
	{
		root = document.createElement('div');
		root.innerHTML = transport.responseText;
	}
	else
	{
		root = transport.responseXML;
	}

	var element = new DOMQuery(selector, root).get(0);
	if(!element)
		return;

	if(isWebKit || !transportHasValidResponseXML(transport))
	{
		return element;
	}

	var _element;

	if(!container)
		container = document.body;

	try
	{
		_element = container.ownerDocument.adoptNode( element, true );
	}
	catch(e)
	{
		_element = container.ownerDocument.importNode( element, true );
	}

	return container.namespaceURI == _element.namespaceURI ? _element : importNodeCurrentNS( _element );
};

function transportHasValidResponseXML(transport)
{
	if ( typeof transport.responseXML != 'undefined' || transport.responseXML.firstChild.tagName == 'parsererror' || transport.responseXML.documentElement == null || transport.responseXML.documentElement == 'undefined')
		return false;

	return true;
};

function importNodeCurrentNS(node)
{
	var clone;

	switch(node.nodeType)
	{
		default:
		case 8: /* comment */
			return;
		case 3: /* text */
			return document.createTextNode( node.nodeValue );
		case 1: /* node */
			clone = document.createElement( node.tagName );
	}

	for(var i=0, attribute; (attribute=node.attributes[i]); i++)
	{
		clone.setAttribute(attribute.name, attribute.value);
	}

	for(var j=0, subNode, importedSubNode; (subNode=node.childNodes[j]); j++)
	{
		importedSubNode = arguments.callee( node.childNodes[j] );
		if(importedSubNode)
			clone.appendChild( importedSubNode );
	}

	return clone;
};
/* ripped from http://www.onlinetools.org/articles/unobtrusivejavascript/cssjsseparation.html */
/* 31-10-2005 13:59 replaced with tino's code, see below */
/*
	a
		defines the action you want the function to perform.
	o
		the object in question.
	c1
		the name of the first class
	c2
		the name of the second class

	Possible actions are:

	swap
		replaces class c1 with class c2 in object o.
	add
		adds class c1 to the object o.
	remove
		removes class c1 from the object o.
	check
		test if class c1 is already applied to object o and returns true or false
	toggle
		test if class c1 is already applied to object o and remove if so, otherwise add class c1
*/
function jscss(a,o,c1,c2)
{
	switch (a)
	{
		case 'add':
			jscss.addClass(o, c1);
			break;
		case 'remove':
			jscss.removeClass(o, c1, c2);
			break;
		case 'check':
			return jscss.hasClass(o, c1);
			break;
		case 'checkParents':
			do
			{
				if (jscss.hasClass(o, c1))
					return true;

				if(o.tagName.toLowerCase() == 'body')
					return false;
			}
			while(o = o.parentNode);
			return false;
			break;
		case 'toggle':
			var operation = 'add';

			if(jscss('check', o, c1))
				operation = 'remove';

			jscss(operation, o, c1, c2);
			break;
		case 'swap':
			jscss.replaceClass(o, c2, c1);
			break;
		case 'get':
			return jscss.getClassList(o);
			break;
	}
	return null;
};

/* taken from http://therealcrisp.xs4all.nl/meuk/classdealer.js */
/* author: Tino Zijdel, 2005 */
jscss.addClass = function (element, classname)
{
	var classes = jscss.getClassList(element);
	if (classes.indexOf(classname) == -1)
	{
		classes[classes.length] = classname;
	}

	jscss.setClassList(element, classes);
};

jscss.removeClass = function (element, classname)
{
	var classes = jscss.getClassList(element), index;
	if ((index = classes.indexOf(classname)) > -1)
	{
		delete classes[index];
	}

	jscss.setClassList(element, classes);
};

jscss.replaceClass = function (element, oldclass, newclass)
{
	var classes = jscss.getClassList(element), index;
	if ((index = classes.indexOf(oldclass)) > -1 && classes.indexOf(newclass) == -1)
	{
		classes[index] = newclass;
	}

	jscss.setClassList(element, classes);
};

jscss.getClassList = function (element)
{
	if (element.className)
		return element.className.split(/\s+/);
	return [];
};

jscss.setClassList = function (element, classes)
{
	element.className = classes.join(' ');
};

jscss.hasClass = function (element, classname)
{
	var wantedClasses = new Array();
	if (classname.indexOf(' ') > -1)
	{
		wantedClasses = classname.split(/\s+/);
	} else {
		wantedClasses[0] = classname;
	}

	var classes = jscss.getClassList(element);

	for (var i = 0; i < wantedClasses.length; i++)
	{
		if (classes.indexOf(wantedClasses[i]) == -1)
		{
			return false;
		}
	}

	return true;
};

if (!Array.prototype.indexOf)
{
	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;
	};
}

if (!Array.prototype.lastIndexOf)
{
	Array.prototype.lastIndexOf = function(searchElement, fromIndex)
	{
		var i = this.length;
		if (!fromIndex) fromIndex = 0;
		else if (fromIndex < 1)
		{
			fromIndex += i;
			if (fromIndex < 0) fromIndex = 0;
		}

		while (i-- > fromIndex)
		{
			if (this[i] === searchElement) return i;
		}

		return -1;
	};
}

if (!Array.getUnique)
{
	Array.prototype.getUnique = function()
	{
		var new_array = [];

		for (var i=0; i < this.length; i++)
			if (new_array.indexOf(this[i]) == -1)
				new_array.push(this[i]);

		return new_array;
	}
}

/* todo: optimize passing of variables to DOMQuery.cssToXPath */
function DOMQuery(selector, contextNode, ns)
{
	if(typeof contextNode == "undefined")
	{
		contextNode = DOMQuery.prototype.scope;
	}

	if(!DOMQuery.hasXPath)
	{
		if(typeof Element != 'undefined' && typeof Element.getElementsBySelector != 'undefined')
		{
			this.resultType = 'getElementsBySelector';

			/* prototype's highest point where getElementsBySelector is to be found is... */
			if(contextNode == document)
				contextNode = document.documentElement;

			try
			{
				this.result = $(contextNode).getElementsBySelector.apply($(contextNode), selector.split(',') );
			}
			catch(e)
			{
				this.result = [];
				this.length = 0;
				throw e;
			}
			this.length = this.result.length;
		}
		else if(typeof cssQuery != 'undefined')
		{
			this.resultType = 'cssQuery';
			this.result = cssQuery(selector, contextNode);
			this.length = this.result.length;
		}
		else if(typeof jQuery != 'undefined')
		{
			this.resultType = 'jQuery';
			this.result = jQuery(selector, contextNode);
			this.length = this.result.size();
		}

	}
	else
	{
		try
		{
			var owner = '';
			if(typeof contextNode.contentType != 'undefined')
				owner = contextNode.contentType;
			else if (contextNode.ownerDocument != null && typeof contextNode.ownerDocument.contentType != 'undefined')
				owner = contextNode.ownerDocument.contentType;
			else
				owner = 'text/html';

			var namespace = ns ? ns : (['application/xml', 'application/xhtml+xml', 'text/xml'].indexOf(owner) > -1) ? 'html:' : '';

			/* namespace = 'html:'; */

			var xpath = this.cssToXPath(selector, contextNode, namespace);

			this.result = document.evaluate(xpath, contextNode, this.NSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

			this.length = this.result.snapshotLength;
			this.resultType = 'XPath';
		}
		catch(e)
		{
			if (showAlertOnXpathError)
				alert('XPath error:'+selector+'\n'+xpath+'\n'+e);
		}
	}
};

	DOMQuery.prototype.get = function (index)
	{
		switch(this.resultType)
		{
			case 'XPath':
				return this.result.snapshotItem(index);
			case 'cssQuery':
			case 'getElementsBySelector':
				return this.result[index];
			case 'jQuery':
				return this.result.get(index);
			default:
				throw new Error("Unknown resultType: "+this.resultType);
		}
	};

	DOMQuery.prototype.scope = document;

	DOMQuery.prototype.NSResolver = function (prefix)
	{
		if(prefix == 'html')
		{
			return 'http://www.w3.org/1999/xhtml';
		}
		else
		{
			 //this shouldn't ever happen
			return null;
		}
	};

	DOMQuery.hasXPath = (document.evaluate && document.implementation.hasFeature('xpath','3.0'));

	/* static / across all instances */
	DOMQuery.cachedXPaths = [ {}, {} ];

	/*if(typeof globalStorage != 'undefined' && typeof globalStorage['www.office.parse.nl'].cachedXPaths != 'undefined')
	{
		DOMQuery.cachedXPaths = globalStorage['www.office.parse.nl'].cachedXPaths.parseJSON();
	}

	DOMQuery.storeCachedXPaths = function()
	{
		if(typeof globalStorage != 'undefined')
			globalStorage['www.office.parse.nl'].cachedXPaths = DOMQuery.cachedXPaths.toJSONString();
	};*/

	/* tnx to http://www.joehewitt.com/ */
	DOMQuery.prototype.cssToXPath = function (rule, contextNode, namespace)
	{
		var namespaceSpecified = false;
		if(namespace == 'undefined')
			namespace = '';
		if(namespace != "")
			namespaceSpecified = true;

		var xpath = DOMQuery.cachedXPaths[ namespaceSpecified ? 0 : 1 ][rule];

		if(typeof xpath == 'string')
		{
			return xpath;
		}

		var _rule = rule;

		var regElement = /^([#.]?)([a-z0-9\\*_-]*)((\|)([a-z0-9\\*_-]*))?/i;
		var regAttr1 = /^\[([^\]]*)\]/i;
		var regAttr2 = /^\[\s*([^\^\$~*=\s]+)\s*([\^\$~*]?=)\s*(["]?)([^"]+)\3\s*\]/i;
		var regPseudo = /^:([a-z-]+)(\((["]?)([^)]+)\3\))?/i;
		var regCombinator = /^(\s*[>+\s])?/i;
		var regComma = /^\s*,/i;

		var index = 1;
		var parts = [".//", "*"], subparts = [], collection = [];
		var lastRule = null;
		var limit = false;

		while (rule.length && rule != lastRule)
		{
			lastRule = rule;

			// Trim leading whitespace
			rule = rule.replace(/^\s*|\s*$/g,"");
			if (!rule.length)
				break;

			subparts = [];

			// Match the element identifier
			var m = regElement.exec(rule);
			if (m)
			{
				if (!m[1])
				{
					if (m[5])
						parts[index] = namespace + m[5];
					else
						parts[index] = namespace + m[2];
				}
				else if (m[1] == '#')
				{
					subparts.push("@id='" + m[2] + "'");
				}
				else if (m[1] == '.')
					subparts.push("contains(concat(' ', @class, ' '),' " + m[2] + " ')");

				rule = rule.substr(m[0].length);
			}

			// Match attribute selectors
			m = regAttr2.exec(rule);
			if (m)
			{
				switch(m[2])
				{
					case '*=': /* contains */
						subparts.push("contains(@" + m[1] + ", \"" + m[4] + "\")");
					break;
					case '~=': /* contains in space-separated value */
						subparts.push("contains(concat(' ', @" + m[1] + ", ' '), \" " + m[4] + " \")");
					break;
					case '|=': /* its value either being exactly "val" or beginning with "val" immediately followed by "-"  */
						subparts.push("@" + m[1] + " = \"" + m[4] + "\") or starts-with(concat(@" + m[1] + ", '-'), \"" + m[4] + "\"))");
					break;
					case '$=': /* ends with */
						/* not supported: http://developer.mozilla.org/en/docs/XPath:Functions*/
						/*subparts.push("ends-with(\""+m[4]+"\", @"+m[1]+")");*/
						subparts.push("substring(@" + m[1] + ", string-length(@" + m[1] + ") - " + (m[4].length - 1) + ") = \"" + m[4] + "\"");
					break;
					case '^=': /* starts with */
						subparts.push("starts-with(@"+m[1]+", \""+m[4]+"\")");
					break;
					default:
						subparts.push("@" + m[1] + "=\"" + m[4] + "\"");
					break;
				}

				rule = rule.substr(m[0].length);
			}
			else
			{
				m = regAttr1.exec(rule);
				if (m)
				{
					subparts.push("@" + m[1] + "");
					rule = rule.substr(m[0].length);
				}
			}

			m = regPseudo.exec(rule);
			while (m)
			{
				rule = rule.substr(m[0].length);
				/* position() == 5 of pos[5] ? */
				/* check msdn! */
				switch(m[1])
				{
					case 'first-child':
						subparts.push("position() = 1");
					break;
					case 'last-child':
						subparts.push("last()");
					break;
					case 'only-child':
						subparts.push("position() = 1");
						subparts.push("last()");
					break;
					case 'enabled':
					case 'disabled':
					case 'checked':
						subparts.push("@" + m[1] + " != \"\"");
					break;
					case 'empty':
						subparts.push("count(.) = 0");
					break;
					case 'lang':
						subparts.push("@lang=\""+m[4]+"\"");
					break;
					case 'contains':
						subparts.push("contains(text(), \""+m[4]+"\")");
					break;
					/* http://www.w3.org/TR/css3-selectors/#nth-child-pseudo */
					case 'nth-child':

						/* let op: tagname kan ook iets zijn als 'html div bla:nth-child(2n+1)', dus 'parent' klopt niet!!!! */
						/*position is dan ook tov div, niet bla's parent */

						switch(m[4])
						{
							/* special / frequently used cases */
							case 'odd':
							case '2n+1':
								subparts.push("position() mod 2 > 0");
								break;
							case 'even':
							case '2n':
							case '2n+0':
								subparts.push("position() mod 2 = 0");
								break;
							/* If both a and b are equal to zero, the pseudo-class represents no element in the document tree. .*/
							case '0n+0':
								subparts.push("false()");
								break;
							default:
								var found;
								/* When a=0, no repeating is used, so for example :nth-child(0n+5) matches only the fifth child. */
								if(found = m[4].match(/^(0n\+)?([0-9]+)$/))
								{
									subparts.push("position() = " + found[2]);
								}
								/* When a=1, the number may be omitted from the rule. */
								else if(found = m[4].match(/^(^|1)n$/))
								{
									;
								}
								/* If b=0, then every ath element is picked. In such a case, the b part may be omitted. */
								else if(found = m[4].match(/^([0-9]+)n(\+0|$)$/))
								{
									subparts.push("position() mod " + found[1] + " = 0");
								}
								/* The value a can be negative  */
								else if(found = m[4].match(/^-n\+([0-9]+)$/))
								{
									subparts.push("position() <= " + found[1]);
								}
								/* this matches the bth child of an element after all the children have been split into groups of a elements each. */
								else if(found = m[4].match(/^([0-9]+)n([+-])([0-9]+)$/))
								{
									subparts.push("position() = floor(length(../TAGNAME)/" + found[1] + ") * " + found[1] + " " + found[2] + " " + found[3] );
								}
								else
								{
									/*throw new Error("unsupported nth-child selector: "+ m[4];)*/
								}
						}
					break;

					case 'target':
						/* should read current anchor and find matching element */
					case 'hover':
					case 'root':
						/* unsupported atm http://www.quirksmode.org/css/root.html */
					default:
						throw new Error("unsupported pseudo class: "+ m[1]);
					break;
				}

				m = regPseudo.exec(rule);
			}

			if(subparts.length > 0)
			{
				parts.push('[' + subparts.join(" and ") + ']');
			}

			// Match combinators
			m = regCombinator.exec(rule);
			if (m && m[0].length)
			{
	            if(limit)
	         {
	             parts.push(limit);
	             limit = false;
	            }

				if (m[0].indexOf(">") != -1)
				{
					parts.push("/");
				}
				else if (m[0].indexOf("+") != -1)
				{
					parts.push("/following-sibling::");
					// following-sibling selects all following siblings, we need only the first next sibling
					limit = '[1]';
				}
				else
				{
					parts.push("//");
				}

				index = parts.length;
				parts.push("*");
				rule = rule.substr(m[0].length);
			}

			m = regComma.exec(rule);
			if (m)
			{
				if(limit)
				{
					parts.push(limit);
					limit = false;
				}

				collection.push( parts.join("") );

				parts = [".//", "*"];

				index = parts.length-1;
				rule = rule.substr(m[0].length);
			}
		}

	    if(limit)
			parts.push(limit);

		collection.push( parts.join("") );

		xpath = collection.join(" | ");

		DOMQuery.cachedXPaths[ namespaceSpecified ? 0 : 1 ][_rule] = xpath;

		/*DOMQuery.storeCachedXPaths();*/

		return xpath;
	};

function getTargets(targets, defaultDOMQuery)
{
	if(targets)
	{
		if(typeof targets == 'string')
			return new DOMQuery(targets);
		else
			return targets;
	}
	else
	{
		if(typeof defaultDOMQuery == 'string')
			return new DOMQuery(defaultDOMQuery);
		else
			return defaultDOMQuery;
	}

	return new DOMQuery('');
};

function addClassToTargets(query, classname)
{
	var items = new DOMQuery(query);

	for(var i=0, item; (item=items.get(i)); i++)
	{
		jscss('add', item, classname, '');
	}
};

function addEventToTargets(targets, type, handler, defaultDOMQuery)
{
	var elements = getTargets(targets, defaultDOMQuery), el;

	for(var i=0;(el=elements.get(i));i++)
	{
		addEvent(el, type, handler);
	}

	return elements;
};

// written by Dean Edwards, 2005
// with input from Tino Zijdel - crisp@xs4all.nl
// http://dean.edwards.name/weblog/2005/10/add-event/
function addEvent(element, type, handler)
{
	if (element.addEventListener) {
		element.addEventListener(type, handler, arguments.callee.eventListenerUseCapture);
	}
	else
	{
		if (!handler.$$guid) handler.$$guid = addEvent.guid++;
		if (!element.events) element.events = {};
		var handlers = element.events[type];
		if (!handlers)
		{
			handlers = element.events[type] = {};
			if (element['on' + type]) handlers[0] = element['on' + type];
			element['on' + type] = handleEvent;
		}

		handlers[handler.$$guid] = handler;
	}
}
addEvent.guid = 1;
addEvent.eventListenerUseCapture = false;

function removeEvent(element, type, handler)
{
	if (element.removeEventListener)
		element.removeEventListener(type, handler, false);
	else if (element.events && element.events[type] && handler.$$guid)
		delete element.events[type][handler.$$guid];
};

function handleEvent(event)
{
	event = event || fixEvent(window.event);
	var returnValue = true;
	var handlers = this.events[event.type];

	for (var i in handlers)
	{
		if (!Object.prototype[i])
		{
			this.$$handler = handlers[i];
			if (this.$$handler(event) === false) returnValue = false;
		}
	}

	if (this.$$handler) this.$$handler = null;

	return returnValue;
};

function fixEvent(event)
{
	event.preventDefault = fixEvent.preventDefault;
	event.stopPropagation = fixEvent.stopPropagation;
	return event;
}

fixEvent.preventDefault = function()
{
	this.returnValue = false;
};

fixEvent.stopPropagation = function()
{
	this.cancelBubble = true;
};

// This little snippet fixes the problem that the onload attribute on the body-element will overwrite
// previous attached events on the window object for the onload event
if (!window.addEventListener)
{
	document.onreadystatechange = function()
	{
		if (window.onload && window.onload != handleEvent)
		{
			addEvent(window, 'load', window.onload);
			window.onload = handleEvent;
		}
	};
};

function getObj(ev, ob)
{
	if(!ob)
	{
		var targ;
		if (!ev) ev = window.event;

		if (ev.target) targ = ev.target;
		else if (ev.srcElement) targ = ev.srcElement;

		if (targ && targ.nodeType == 3) // defeat Safari bug
			targ = targ.parentNode;

		return targ;
	}
	else
	{
		return ob;
	}
};

function loadScript(url, prependBoardUrl)
{
	if(prependBoardUrl)
		url = board_template_url + url;

	var e = createDOMNode('script', {"type" : 'text/javascript', "src" : url}, []);

	document.getElementsByTagName("head")[0].appendChild(e);
};

function currentStyle(element, property)
{
	return parseInt(window.getComputedStyle ? window.getComputedStyle(element,'').getPropertyValue(property) : element.currentStyle.getAttribute(property));
};

function empty()
{
	if(this && this.value == this.defaultValue )
	{
		this.value = '';
	}
};

function unhtmlspecialchars(str)
{
	str = str.replace(/&amp;/gi, '&');
	str = str.replace(/&lt;/gi, '<');
	str = str.replace(/&gt;/gi, '>');
	return str;
};

/* tnx crisp */
function htmlspecialchars(input)
{
	input = input.replace(/&/g,'&amp;');
	input = input.replace(/>/g,'&gt;');
	input = input.replace(/</g,'&lt;');
	input = input.replace(/"/g,'&quot;');

	/* " < fix syntax highlighting */

	return input;
};

function getCookie(sName)
{
	var aCookie = document.cookie.split('; '), i = aCookie.length, aCrumb;
	while (i--)
	{
		aCrumb = aCookie[i].split('=');
		if (sName == aCrumb[0])
			return typeof aCrumb[1] != 'undefined'? unescape(aCrumb[1]) : null;
	}

	return null;
}

/*
 * Find the next sibling node (skipping text nodes) or a sibling with a specific tag name
 */
function getSiblingNode(startpoint, direction, tagName)
{
	var o = startpoint, tagEmpty = (tagName == undefined || tagName.length == 0);

	if (tagName != undefined)
		tagName = tagName.toLowerCase();

	do
	{
		if (direction == 'previous')
		{
			o = o.previousSibling;
		}
		else if ( direction == "next" )
		{
			o = o.nextSibling;
		}
		else if ( direction == "up" )
		{
			o = o.parentNode;
		}

		if ( o && o.nodeType == 1)
		{
			if (tagEmpty || o.tagName.toLowerCase() == tagName )
				return o;
		}

	} while (o);

	return null;
}

/*
example syntax:

var test = createDOMNode( 'div', {"class" : 'waa', "event" : ['click', _func] },
			[
				createDOMNode( 'span', {"class" : 'woei'},
				[
					'snotbeuken'
				]),
				'waa',
				123
			]);
creates:
text = <div class="waa"><span class="woei">snotbeuken>waa123</div>
*/
function createDOMNode(tagname, options, children)
{
	var option, child, me;

	if(isIE && typeof options['type'] == 'string' && (options['type'] == 'radio' || options['type'] == 'submit'))
	{
		/* IE doesn't like dynamically generated [s]radiobuttons[/] anything, so we have to set 'name' manually */
		me = document.createElement(
				'<input' +
				' type="'+options['type'] + '"' +
				' name="' + options['name'] + '"' +
				 (typeof options['checked'] != 'undefined' ? ' checked' : '') +
				'>'
			);
	}
	else if(tagname != null)
	{
		me = document.createElement(tagname);
	}
	else
	{
		me = document.createDocumentFragment();
	}

	for(option in options)
	{
		if(!options.hasOwnProperty(option))
			continue;

		if(option == 'event')
		{
			addEvent(me, options[option][0], options[option][1]);
		}
		else
		{
			if (option == 'class')
			{
				me.setAttribute('className', options[option]);
			}
			else if (option == 'style' && me.style.setAttribute)
			{
				me.style.setAttribute('cssText', options[option]);
				continue;
			}

			me.setAttribute(option, options[option]);
		}
	}

	for(var i = 0; (child=children[i]); i++)
	{
		if( ["string", "number"].indexOf(typeof child) > -1 )
		{
			child = document.createTextNode(child);
		}
		me.appendChild(child);
	}

	return me;
};

function setCookie(sName, sValue)
{
	document.cookie = sName + '=' + escape(sValue) + '; expires=Fri, 31 Dec 2099 23:59:59 GMT; path=/';
}

// transparantPNG - Based on http://www.schillmania.com/projects/png/ but very much completely rewritten
// Apply a filter in IE to make png's (both images and background-images) transparant
function transparantPNG(targets)
{
	if (!isIE || !isWin || !isNotIE7)
		return;

	// Here you can decide which elements to search for png's (you can use * but that will be very slow)
	var elements = getTargets(targets, '.transparantPNG');
	var imagesource;

	for (var i=0, object; (object=elements.get(i)); i++)
	{
		if (object.getAttribute('src'))
		{
			imagesource = object.getAttribute('src');
			object.src = board_template_url + 'img/layout/iefix/transparantPNG.gif';
		}
		else if (object.currentStyle.backgroundImage.toString() && object.currentStyle.backgroundImage.toString() != "none")
		{
			var cssBackground = object.currentStyle.backgroundImage.toString();
			var j = cssBackground.indexOf('url("')+5;
			imagesource = cssBackground.substr(j,cssBackground.length-j-2);
			object.style.backgroundImage = 'none';
		}
		else
		{
			return false;
		}

		object.style.writingMode = 'lr-tb';
		object.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+imagesource+"',sizingMethod='image')";

		object.style.border = '0';
	}
}

var texts = new Array();
function getText(a, b, c)
{
	if(typeof texts[a] == 'undefined' || typeof texts[a][b] == 'undefined' || !texts[a][b] )
		return '[text not found: '+a+'::'+b+']';

	if ( c )
		return texts[a][b].replace('%s',c);
	else
		return texts[a][b];
}

// Dean Edwards/Matthias Miller/John Resig
/* http://dean.edwards.name/weblog/2006/06/again/ */
function init()
{
	// quit if this function has already been called
	if (arguments.callee.done)
		return;

	// flag this function so we don't do the same thing twice
	arguments.callee.done = true;

	// kill the timer
	if (_timer)
		clearInterval(_timer);

	_init(events);
};

function rand ( n )
{
	return ( Math.floor ( Math.random ( ) * n + 1 ) );
}

var timings = [];
var eventTiming = false;

if (typeof showAlertOnXpathError == "undefined")
	var showAlertOnXpathError = false;

var isIE, isNotIE7, isGecko, isWebKit, isWin;

function _init(events, scope)
{
	if(!document.body)
		return;

	var time1, time2, funcname;
	var funcPattern = /function ([a-zA-Z]+)/, total = 0, duration = 0;

	if(!arguments.callee.initalInit)
	{
		isIE = navigator.userAgent.indexOf('MSIE') != -1 && navigator.userAgent.indexOf('Opera') == -1;
		isNotIE7 = isIE && navigator.userAgent.indexOf('MSIE 7.0') == -1;
		isGecko = navigator.userAgent.indexOf('Gecko') != -1;
		isWebKit = navigator.userAgent.indexOf('WebKit') != -1;
		isWin = navigator.userAgent.indexOf('Windows') != -1;
		jscss('add', document.body, 'javascript', '');

		arguments.callee.initalInit = true;
	}

	if(scope)
	{
		var previousScope = DOMQuery.prototype.scope;
		DOMQuery.prototype.scope = scope;
	}

	for(var i=0; i<events.length; i++)
	{
		try
		{
			if(eventTiming)
			{
				funcname = events[i].toString().match(funcPattern)[1];
				timings[i] = funcname + ' ???';
				time1 = new Date().getTime();
			}

			if(typeof events[i] == 'function')
				events[i]();
			else if(typeof events[i] == 'object')
				events[i][0].apply(window, events[i][1]);

			if(eventTiming)
			{
				time2 = new Date().getTime();
				duration = (time2 - time1);
				total += duration;

				for(j=(funcname.length + duration.toString().length); j<50; j++)
					funcname += ' ';

				timings[i] = funcname + duration + ' ms\n';
			}
		}
		catch (e)
		{
			/* we don't need to pass the scope again */
			arguments.callee( events.slice(i + 1) );
			if(scope)
			{
				DOMQuery.prototype.scope = previousScope;
			}
			throw e;
		}
	}

	if(scope)
	{
		DOMQuery.prototype.scope = previousScope;
	}

	if(eventTiming)
		document.body.appendChild(createDOMNode('pre', {}, timings));

/*	window.status = 'xpath: ' + DOMQuery.hasXPath + ' - total JS events: '+total+'ms' ; */

}

/* for Mozilla/Opera9 */
if (document.addEventListener)
{
	document.addEventListener("DOMContentLoaded", init, false);
}

/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
	document.write("<script id=__ie_onload defer src=//:><\/script>");
	var script = document.getElementById("__ie_onload");
	script.onreadystatechange = function()
	{
		if (this.readyState != "complete")
			return;

		if(typeof initReadyStateDetectionCallback != 'function' || initReadyStateDetectionCallback())
		{
			init();
			return;
		}

		var _timer = setInterval(function()
		{
			if(initReadyStateDetectionCallback())
			{
				init(); // call the onload handler
			}
		}, 10);
	};
/*@end @*/

/* for Safari */
if (/WebKit/i.test(navigator.userAgent))
{ // sniff
	var _timer = setInterval(function()
	{
		if (/loaded|complete/.test(document.readyState))
		{
			init(); // call the onload handler
		}
	}, 10);
};

/* for other browsers */
window.onload = init;
function linkTitleInStatusbar(targets)
{
	addEventToTargets(targets, 'mouseover', showTitleInStatusbar, 'a');
	addEventToTargets(targets, 'mouseout', clearStatusbar, 'a');
};

function showTitleInStatusbar()
{
	if(this.title.length == 0)
		return;

	if(this.accessKey.length == 1)
	{
		window.status = this.title + ' - sneltoets: Alt + '+this.accessKey;
	}
	else
	{
		window.status = this.title + ' - ' + this.href;
	}
};

function clearStatusbar()
{
	window.status = '';
	return true;
};

var maxImageWidth = 595;
var maxImageHeight = 2000;
var imagesToScale = [];
function scaleImages(targets)
{
	imagesToScale = getTargets(targets, 'ol div.message-content img');
	if(imagesToScale.length > 0)
		addEvent(window, 'load', _scaleImages);
};

function _scaleImages()
{
	for(var i=0, image;(image=imagesToScale.get(i));i++)
	{
		scaleImage(image);
	}
	imagesToScale = [];
};

function scaleImage(img)
{
	if (maxImageWidth == 0 || maxImageHeight == 0)
		return;

	if (img.width > maxImageWidth || img.height > maxImageHeight)
	{
		var scaleRatio = maxImageWidth / maxImageHeight;
		var ratio = img.width / img.height;
		img.originalWidth = img.width;
		img.originalHeight = img.height;

		if (ratio > scaleRatio)
		{
			img.width = maxImageWidth;
			img.height = maxImageWidth / ratio;
		}
		else
		{
			img.height = maxImageHeight;
			img.width = maxImageHeight * ratio;
		}

		if (img.parentNode.nodeName.toUpperCase() != 'A')
		{
			addEvent(img, 'click', popupImage);
			jscss('add', img, 'enlargeable');
			img.title += getText('extra', 'click_to_enlarge');
		}
	}
};

function popupImage()
{
	window.open(this.src, 'img', 'width='+(this.originalWidth+16)+',height='+(this.originalHeight+16)+',left=0,top=0');
};

function makeSmileysClickable(targets)
{
	addEventToTargets(targets, 'click', _insertSmiley, 'div#smileys img');
};

function _insertSmiley()
{
	putStr(' ' +  this.alt + ' ');
	hideSmileys();
};

function localAnchors()
{
	/* strict checking for the moment, should be evaluated at a later point */
	if(!jscss('check', document.body, 'list_message') && !jscss('check', document.body, 'list_messages'))
		return;

	var container = new DOMQuery('ol#messages').get(0);
	if(!container)
		return;

	var items = new DOMQuery('address.posted-at a, blockquote.quote-blockquote a.messagelink', container);
	var pattern = /list_message\//;
	for(var i = 0, item; (item=items.get(i)); i++)
	{
		if(pattern.test(item.pathname))
		{
			addEvent(item, 'click', function(e) { if(!_localAnchors(this)) { e.preventDefault(); } } );
		}
	}
};

function _localAnchors(x)
{
	var id = x.hash.substring(1), anchors = document.anchors;

	for(var i=0, anchor; (anchor=anchors[i]); i++)
	{
		if(anchor.name == id)
		{
			window.location.hash = id;
			return false;
		}
	}
};

function slashdotLinks(targets)
{
	var items = getTargets(targets, 'ol.messages a.link'), a = createDOMNode('a', {"href" : board_script_url}, []), span, clone, shortname;
	for(var i=0, item; (item = items.get(i)); i++)
	{
		if(a.hostname != item.hostname)
		{
			if(item.href == item.text || item.hostname == item.text)
				continue;

			shortname = hostnameToShortname(item.hostname);
			span = createDOMNode('span', {}, [item.cloneNode(true), ' [' + shortname + ']']);
			item.parentNode.replaceChild(span, item);
		}
	}
};
/* these regexp's have been copied from slashcode which is GPL */
/* file: utils/domainTagifyComments */
function hostnameToShortname(hostname)
{
	if(/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname))
		return hostname;

	var result;

	for(var i=1; i<=3; i++)
	{
		switch(i)
		{
			case 1:
				result = hostname.match(/([\w-]+\.[a-z]{3,4})$/i);
			break;
			case 2:
				result = hostname.match(/([\w-]+\.[a-z]{2,4}\.[a-z]{2})$/i);
			break;
			case 3:
				result = hostname.match(/([a-z]+\.[a-z]{2})$/i);
			break;
		}
		if(result)
			return result[1];
	}

	var items = hostname.split('.');
	if(items.length >= 3)
		return items.reverse().slice(0,3).reverse().join('.');

	return hostname;
};

function externalLinksInPopup(targets)
{
	var items = getTargets(targets, 'ol.messages a.link'), a = createDOMNode('a', {"href" : board_script_url}, []);

	for(var i=0, item; (item = items.get(i)); i++)
	{
		if(a.hostname != item.hostname)
		{
			addEvent(item, 'click', function(e) { if(!_localAnchors(this)) { window.open(this.href, 'popupexternal'); e.preventDefault(); } } );
		}
	}
};

function indicateSecureLink(targets)
{
	var items = getTargets(targets, 'ol.messages a.link'), a = createDOMNode('a', {"href" : board_script_url}, []);

	for(var i=0, item; (item = items.get(i)); i++)
	{
		if(a.hostname != item.hostname && item.protocol == 'https:')
		{
			jscss('add', item, 'secure-link');
		}
	}

};

function searchPopup(targets)
{
	addEventToTargets(targets, 'click', function() { try {_searchPopup(this);} catch (e) {} return false;}, 'div#navigation li#search-link a');
	addEventToTargets(targets, 'dblclick', function() { document.location.href = items[0].href; } , 'div#navigation li#search-link a');
};

function _searchPopup(x)
{
	var hiddenElements = [ ['action', 'find'], ['data[searchtype]', 'search'] ], input, fieldsetNodes = [];
	for(var i =0, item; (item = hiddenElements[i]);i++)
	{
		fieldsetNodes[fieldsetNodes.length] = createDOMNode('input', {"type" : 'hidden', "name" : item[0], "value" : item[1]}, []);
	}

	var form = createDOMNode('form', {"action" : board_script_url},
				[
					createDOMNode('fieldset', {},
					[
						/*fieldsetNodes,*/
						createDOMNode('input', {"type" : 'text', "name" : 'data[q]',"size" : 40, "id" : 'search-link-input', "defaultValue" : getText('extra', 'searchPopup'), "event" : ['focus', empty]}, [])
					]),

				]);

	x.parentNode.appendChild(form);

	new DOMQuery('input#search-link-input').get(0).focus();

	return false;
};

function closeAndSubmit(targets)
{
	var items = getTargets(targets, 'div#topic-admin input#status');
	if(items.length == 0)
		return;

	if(items.get(0).nextSibling.options[items.get(0).nextSibling.selectedIndex].value != 'Closed')
	{
		var input = createDOMNode('input', {"type" :'submit', "accessKey" :'c', "value" :getText('extra','close_and_submit'), "event" :['click', function() { _closeAndSubmit(this.form); }] }, []);
		items.get(0).parentNode.appendChild(input);
	}
};

function _closeAndSubmit(form)
{
	var items = new DOMQuery('input#status + select', form);
	if(items.length == 0)
		return;

	var select = items.get(0), opts = select.options;
	for(var i=0, option; (option=opts[i]); i++)
	{
		if(	option.value == 'Closed')
		{
			select.selectedIndex = i;
			select.previousSibling.checked = true;
			break;
		}
	}
};

function indicateAccesskey(targets)
{
	var items = getTargets(targets, 'input[accesskey]');

	var replacement, indicatorCharPos, textOnButton;
	for(var i=0, item; (item=items.get(i)); i++)
	{
		switch(item.type)
		{
			case 'submit':
			case 'reset':
				textOnButton = item.value;
				indicatorCharPos = textOnButton.toLowerCase().indexOf(item.accessKey);

				if(indicatorCharPos >= 0 )
				{
					replacement =	createDOMNode('button', {"accessKey" : item.accessKey, "name" : item.name, "id" : item.id, "type" : item.type, "class" : item.className},
									[
										textOnButton.substring(0, indicatorCharPos),
										createDOMNode('span', {"class" : 'accesskey'}, [textOnButton.charAt(indicatorCharPos)]),
										textOnButton.substring(indicatorCharPos+1)
									]);
				}
				else
				{
					replacement =	createDOMNode('button', {"accessKey" : item.accessKey, "name" : item.name, "id" : item.id, "type" : item.type, "class" : item.className},
									[
										textOnButton,
										' ',
										createDOMNode('span', {"class" : 'accesskey'}, [getText('extra', 'accesskey_indicator', item.accessKey)])
									]);
				}

				/* ie moet echt dood ofzo */
				/* ie pakt de 'type' attribute niet mee */
				if(isIE)
				{
					if(item.type == 'submit')
						addEvent(replacement, 'click', function() { this.form.submit(); } );
					else if(item.type == 'reset')
						addEvent(replacement, 'click', function() { this.form.reset(); } );
				}

				item.parentNode.replaceChild(replacement, item);
				break;
		}
	}

	return true;
};

function allPagesNavigation(targets)
{
	addEventToTargets(targets, 'click', _allPagesNavigation, 'dl.topic-navigation span.cutoff');
};

function _allPagesNavigation()
{
	var dl = getSiblingNode(this, 'up', 'dl');

	var link = new DOMQuery('dd a', dl);

	if(link.length == 0)
		return;
	else
		link = link.get(0);

	/* number is stored in dl's pages-... */
	var maxPage = dl.className.match(/pages\-([0-9]+)/)[1];

	var pageNumber = prompt(getText('extra','enter_page_number', maxPage), '1');
	if(!pageNumber)
		return;

	pageNumber = parseInt(pageNumber);

	if(isNaN(pageNumber) || pageNumber < 1 || pageNumber > maxPage)
	{
		alert(getText('extra', 'page_number_incorrect'));
		return;
	}

	var matches = link.href.match(/^([^0-9]+\/[0-9]+)(\/[0-9]+)?(.*)$/);
	var _link = matches[1] + '/' + pageNumber + matches[3];

	document.location.href = _link;
};

function highlightReferrerQuery()
{
	var q = '', item = null, el = [];
	var ref = document.referrer;
	if(ref != '')
	{
		ref = createDOMNode('a', {'href' : ref}, []).search.substr(1).split('&');
		/* ref now contains a list of a=b, x=y, ... sets */
		for(var i=0; (item = ref[i]); i++)
		{
			el = item.split('=');
			if(['q', 'p', 'query'].indexOf(el[0]) > -1)
			{
				q = el[1];
				break;
			}
		}

		if(q == '')
			return;

		/* tnx to http://svn.fucoder.com/fucoder/se-hilite/se_hilite_src.js */
		q = decodeURIComponent(q);
		q = q.replace(/\'|"/g, '');
		q = q.split(/[\s,\+\.]+/);

		highlightStrings(document.body, q );
	}
};

function highlightStrings(el, strs)
{
	var regexp, metch, words, replacement;
	for(var i=0, item; (item = el.childNodes[i]); i++)
	{
		if(item.nodeType == 3)
		{
			regexp = new RegExp('\\b('+strs.join('|')+')\\b', 'ig');
			if(words = item.nodeValue.split( regexp ))
			{
				/* now highlight the individual words */
				replacement = [];
				for(var j=0, word; (word = words[j]); j++)
				{
					replacement.push( strs.indexOf(word) > -1 ? createDOMNode('span', {'class' : 'highlight1'}, [word]) : word );
				}

				item.parentNode.replaceChild(createDOMNode('span', {'class' : 'highlighting'}, replacement), item);
			}
		}
		else if(item.nodeType == 1)
		{
			highlightStrings(item, strs);
		}
	}
};

function resolveIP2Hostname()
{
	var items = new DOMQuery('li.message-ip a');

	for(var i=0, item; (item=items.get(i)); i++)
	{
		addEvent(item, 'mouseover', _resolveIP2Hostname);
		addEvent(item, 'mouseout', _resolveIP2Hostname);
	}
};

var _resolveIP2HostnameXHR;
function _resolveIP2Hostname(ev)
{
	var target = this;

	switch(ev.type)
	{
		case 'mouseover':
			_resolveIP2HostnameXHR = setTimeout( function()
				{
					var callback = function()
					{
						if (typeof req != 'undefined' && req != null && req.readyState == 4)
						{
							var result = req.responseText.match(/<dd class="lookup_user">(.+)<\/dd>/);
							alert(result[1]);
						}
					};
					var req = httpreq_string('', callback, target.href, false);
				}, 250);
		break;
		case 'mouseout':
			clearTimeout(_resolveIP2HostnameXHR);
		break;
	}
};

function autocomplete(targets)
{
	var items = getTargets(targets, 'input[suggestions]');

	for(var i=0, item; (item=items.get(i));i++)
	{
		if(item.getAttribute('readonly'))
			addEvent(item, 'focus', autocompleteSuggest);
		else
			addEvent(item, 'keyup', autocompleteSuggest);

		addEvent(item, 'keydown', dontSubmit);
		addEvent(item, 'blur', hideAutocompleteSuggest);
		item.setAttribute('autocomplete', 'off');
	}
};

function dontSubmit(e)
{
	var e = e || fixEvent(window.event);
	if(e.keyCode == 13 && this.suggesting)
	{
		e.preventDefault();
	}
};

function hideAutocompleteSuggest()
{
	var list = new DOMQuery('div.autocomplete', document.body).get(0);
	if (list)
	{
		list.noFocus = true;
		if (list.noMouse)
			list.parentNode.removeChild(list);
	}
};

function autocompleteSuggest(e)
{
	var e = e || fixEvent(window.event), li_item;

	var list = new DOMQuery('div.autocomplete', document.body).get(0);
	switch(e.keyCode)
	{
		case 27: /* esc */
			if (!list)
				return;

			list.parentNode.removeChild(list);
			this.suggesting = false;
			return;
		break;
		case 40: /* down */
		case 38: /* up */
			if (!list)
				return;

			var items = new DOMQuery('li', list);
			for(var i=0, item; (item=items.get(i));i++)
			{
				if(!jscss('check', item, 'selected'))
					continue;

				var j = i;
				if(e.keyCode == 38) /* previous */
					j--;
				else				/* next */
					j++;

				var newSelection = items.get(j);
				if(newSelection)
				{
					jscss('remove', item, 'selected', '');
					jscss('add', newSelection, 'selected');

 					var corr = newSelection.offsetTop + newSelection.offsetHeight - list.scrollTop - list.offsetHeight;
					if (corr>0)
						list.scrollTop += corr;
					corr = list.scrollTop - newSelection.offsetTop;
 					if (corr>0)
 						list.scrollTop -= corr;
				}
				break;
			}
			return;
		break;
		case 13: /* enter */
			if (!list)
				return;

			var currentSelection = new DOMQuery('li.selected', list).get(0);

			if(!currentSelection)
				return;

			var no_input = (this.value.substr(-1) == ' ');

			var values = this.value.replace(/\s+$/, '').split(/\s+/);

			if (!no_input)
				values.pop(); /* current word */

			values.push(currentSelection.getAttribute('keyword'));
			this.value = values.join(' ') + ' ';

			list.parentNode.removeChild(list);
			this.suggesting = false;
			return;
		break;
	}


	var choices = this.getAttribute('suggestions').replace(/^\s+|\s+$/g, '').toLowerCase().split(/\s+/);
	var suggestions = [];

	var values = this.value.split(/\s+/);
	var value = values.pop();
	if(!value)
		value = '';
	value = value.toLowerCase();
	var input = this; /* copy for scope reference */
	var readonly = false;

	if(input.getAttribute('readonly'))
		readonly = true;

	for(var i=0; i<choices.length;i++)
	{
		if(choices[i].indexOf(value) != 0 && !readonly)
			continue;

		li_item =
			createDOMNode(
				'li',
				{
					'class' : (suggestions.length == 0 ? 'selected' : '') + (values.indexOf(choices[i]) >= 0 ? ' picked' : ''),
					'keyword'	: choices[i],
					'event' : ['click', function()
					{
						var values = input.value.replace(/\s+$/, '').split(/\s+/);
						var list = new DOMQuery('div.autocomplete', document.body).get(0);

						if(readonly)
						{
							for(var i = 0; i < values.length; i++)
							{
								if(values[i].toLowerCase() == this.getAttribute('keyword').toLowerCase())
								{
									values.splice(i,1);
									var removed = true;
									break;
								}
							}
						}
						else if (value.length > 0)
							values.pop(); /* current word */

						if(!removed)
							values.push( this.getAttribute('keyword').toLowerCase() );

						input.value = values.join(' ') + ' ';
						if (list)
							list.parentNode.removeChild(list);
					}]
				},
				[choices[i]]
			);

		addEvent(
			li_item,
			'mouseover',
			function ()
			{
				jscss('remove', new DOMQuery('li.selected', this.parentNode).get(0), 'selected', '');
				jscss('add', this, 'selected');
			}
		);

		suggestions.push(li_item);
	}

	if(list)
		list.parentNode.removeChild(list);
	this.suggesting = false;

	if(suggestions.length > 0)
	{
		var autocompleteList = createDOMNode('div', {'class' : 'autocomplete'}, [createDOMNode('ul', {}, suggestions)] );
		document.body.appendChild(autocompleteList);
		var pos = findPos(this);
		if (isIE)
			autocompleteList.style.left = (pos.x - document.body.offsetLeft) +'px';
		else
			autocompleteList.style.left = (pos.x + 6) +'px';

		autocompleteList.style.top = (pos.y + this.offsetHeight + 4) +'px';

		addEvent(autocompleteList, 'mouseover', autocompleteListMouseOver);
		addEvent(autocompleteList, 'mouseout', autocompleteListMouseOut);

		autocompleteList.noMouse = true;

		this.suggesting = true;
	}
};

function autocompleteListMouseOver()
{
	this.noMouse = false;
};

function autocompleteListMouseOut()
{
	this.noMouse = true;
	if (this.noFocus)
		this.parentNode.removeChild(this);
};

function findPos(obj)
{
	var curleft = curtop = 0;
	if (obj.offsetParent)
	{
		curleft = obj.offsetLeft;
		curtop = obj.offsetTop;
		while (obj = obj.offsetParent)
		{
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		}
	}
	return {x: curleft, y: curtop};
}

function stretchTextareas(targets)
{
	addEventToTargets(targets, 'keyup', stretchTextarea, 'textarea');
	addEventToTargets(targets, 'change', stretchTextarea, 'textarea');
};

function stretchTextarea()
{
	var lines = this.value.match(/([\r\n])/g);
	if(lines == null)
		return;

	this.style.height = Math.max(50, lines.length + 8) + 'em';

	this.scrollIntoView(false);
};

function xhrPagination(targets)
{
	if(['list_messages', 'list_message'].indexOf(board_action) == -1)
		return;

	addEventToTargets(targets, 'click', _xhrPagination, 'dl.topic-navigation dd a');
};

function _xhrPagination(e)
{
	if(['last'].indexOf(this.getAttribute('rel')) > -1 || document.location.pathname.match(/list_messages\/[0-9]+\/last/) ) /* we don't handle 'last' cause it's "special" */
		return;

	if(!arguments.callee.initialPage)
	{
		/* determine the page currently shown */
		arguments.callee.initialPage = parseInt(new DOMQuery('dl.topic-navigation dd a.current-page').get(0).href.match(/list_messages\/[0-9]+\/([0-9]+)/)[1]) + 1;
		arguments.callee.totalPages = parseInt(new DOMQuery('dl.topic-navigation').get(0).className.match(/pages-([0-9]+)/)[1]);
		new DOMQuery('ol.messages').get(0).setAttribute('page', arguments.callee.initialPage);
	}

	if(jscss('check', this, 'placeholder'))
	{
		var thisPage = this.getAttribute('page');
	}
	else
	{
		var thisPage = parseInt(this.getAttribute('href').match(/list_messages\/[0-9]+\/([0-9]+)/)[1]) + 1;
	}

	if(thisPage - 1 >= arguments.callee.totalPages || new DOMQuery('ol.messages[page="'+thisPage+'"]').get(0)) // duplicate request / out-of-bounds
	{
		e && e.preventDefault();
		return;
	}

	var request = httpreq_string('', null, this.getAttribute('href'), false, "GET");
	var messages = getElementFromXHR(request, 'ol.messages');
	var thisPage = parseInt(getElementFromXHR(request, 'dl.topic-navigation dd a.current-page').href.match(/list_messages\/[0-9]+\/([0-9]+)/)[1]) + 1;
	if(!messages) // should we show x-errormessage?
		return;

	// fill blanks
	var containers = new DOMQuery('ol.messages');
	var placeholders = [];
	if(thisPage > arguments.callee.initialPage) /* we're paging ahead */
	{
		var lastContainer = containers.get(containers.length - 1);
		/* we're skipping the current lastPageAvailable and do create one for the thisPage as we'll need the reference later */
		for(var i = parseInt(lastContainer.getAttribute('page')) + 1; i <= thisPage; i++)
		{
			placeholders.push( createDOMNode('p', {'class' : 'placeholder clickable', 'page' : i, 'event' : ['click', arguments.callee], 'href' : this.href.replace(/(list_messages\/[0-9]+\/)([0-9]+)/, '$1' + (i-1) ) }, ['Skipped page: ' + i]) );
		}

		// append the placeholders
		if(placeholders.length)
		{
			lastContainer.parentNode.insertBefore( createDOMNode(null, {}, placeholders), lastContainer.nextSibling );
		}
	}
	else /* we're paging backwards */
	{
		var firstContainer = containers.get(0);
		/* we're skipping the current lastPageAvailable and do create one for the thisPage as we'll need the reference later */
		for(var i = parseInt(firstContainer.getAttribute('page')) - 1; i >= thisPage; i--)
		{
			placeholders.unshift( createDOMNode('p', {'class' : 'placeholder clickable', 'page' : i, 'event' : ['click', arguments.callee], 'href' : this.href.replace(/(list_messages\/[0-9]+\/)([0-9]+)/, '$1' + (i-1) ) }, ['Skipped page: ' + i]) );
		}

		// prepend the placeholders
		if(placeholders.length)
		{
			firstContainer.parentNode.insertBefore( createDOMNode(null, {}, placeholders), firstContainer.previousSibling );
		}
	}

	var placeholder = new DOMQuery('p.placeholder[page="'+thisPage+'"]').get(0);
	if(!placeholder) /* something went pearshaped */
		return;

	messages.setAttribute('page', thisPage);
	placeholder.parentNode.insertBefore(messages, placeholder);
	placeholder.parentNode.removeChild(placeholder);

	var nextLinks = new DOMQuery('dl.topic-navigation dd a[rel="next"]');
	for(var i = 0, nextLink; (nextLink = nextLinks.get(i)); i++)
	{
		nextLink.href = nextLink.href.replace(/(list_messages\/[0-9]+\/)([0-9]+)/, '$1' + thisPage )
	}

	var currentPages = new DOMQuery('dl.topic-navigation dd a[href*="list_messages/'+this.getAttribute('href').match(/list_messages\/([0-9]+)/)[1]+'/'+(thisPage-1)+'"]');
	for(var i = 0, currentPage; (currentPage = currentPages.get(i)); i++)
	{
		jscss('add', currentPage, 'current-page');
	}

	if(messages.scrollIntoView)
		messages.scrollIntoView();

	_init(events, messages);
	e && e.preventDefault();
	/*if(events.indexOf(pageIndicator) > -1)
	{
		updatePageIndicator();
	}*/
};


/* this is UNFINISHED */
function pageIndicator()
{
	if(arguments.callee.initialRun)
		return;

	document.body.appendChild(
		createDOMNode('div', {'id' : 'container', 'style' : 'width: 50px; height: 200px; border: 1px solid black; position: absolute; top: 0; left: 275px;'}, [
		])
	);

	updatePageIndicator();
	arguments.callee.initialRun = true;
}

function updatePageIndicator()
{
	var container = new DOMQuery('div#container').get(0);
	while(container.firstChild)
		container.removeChild(container.firstChild);

	var messageCount = 13; // should be dynamic
	var perPage = 5; // should be dynamic

	var containerHeight = currentStyle(container, 'height');
	var perPixel = containerHeight / messageCount;

	var availablePage = createDOMNode('div', {'class' : 'viewport', 'style' : 'width: 48px; height: 0; border: 1px solid red; position: absolute; top: 0; left: 0; background-color: yellow; opacity: .6'}, []);
	var items = new DOMQuery('ol.messages');
	for(var i = 0, item; (item = items.get(i)); i++)
	{
		var messagesVisible = new DOMQuery('li.message', item).length;
		var currentPage = parseInt(item.getAttribute('page'));
		if(!currentPage) // this only happens when someone has not executed _xhrPagination
		{
			currentPage = parseInt(new DOMQuery('dl.topic-navigation dd a.current-page').get(0).href.match(/list_messages\/[0-9]+\/([0-9]+)/)[1]) + 1;
		}

		var clone = availablePage.cloneNode(true);
		clone.style.height = Math.floor(messagesVisible * perPixel) + 'px';
		clone.style.top = Math.floor((currentPage - 1) * perPage * perPixel) + 'px';

		container.appendChild(clone);
	}

	var viewport = createDOMNode('div', {'class' : 'viewport', 'style' : 'width: 48px; height: 0; border: 1px solid red; position: absolute; top: 0; left: 0; background-color: blue; opacity: .7'}, []);
	viewport.style.height = 30 + 'px';
	container.appendChild(viewport);
}
var documents_data = Array();

function scrollToAnchor()
{
	if (!location.hash)
		return;

	var link          = location.hash.substr(1);

	if (!link.match(/^[0-9a-z]+$/))
	{
		return;
	}

	var element       = new DOMQuery("a#" +link );
	var scrollElement = element.get(0);

	if (!scrollElement)
		return;

	addEvent(
		window,
		'load',
		function() { scrollElement.scrollIntoView(); }
	);
}

function loginForm()
{
	/* checks if field isn't filled by browser's autocomplete feature */
	var f = new DOMQuery('input#quick-login-form-user').get(0);

	if(f && f.value == '')
	{
		f.value = getText('forms', 'username');
		addEvent(f, 'focus', _clearFieldSetTypePassword);
	}

	f = new DOMQuery('input#quick-login-form-password').get(0);

	if(f && f.value == '')
	{
		try
		{
			f.type = 'text';
		}
		catch(e)
		{
			;
		}
		f.defaultValue = getText('forms', 'password');

		addEvent( f, 'click', _clearFieldSetTypePassword);
		addEvent( f, 'focus', _clearFieldSetTypePassword);
	}
};

function _clearFieldSetTypePassword()
{
	var password_input = new DOMQuery('input#quick-login-form-password').get(0);
	var username_input = new DOMQuery('input#quick-login-form-user').get(0);

	if ( username_input.value != getText('forms', 'username') )
		return;

	try
	{
		 password_input.value = ''; password_input.type = 'password';
	}
	catch(e)
	{
		;
	}
	username_input.value = '';
};

function boardForumPulldown()
{
	if(this.tagName.toLowerCase() != 'select')
		return;

	if(Number(this.value) > 0)
	{
		document.location.href =  board_script_url +'/list_topics/' + this.value;
	}
	else if(this.value != '')
	{
		document.location.href = this.value;
	}
};

function createFooter()
{
	var footer = new DOMQuery('div#footer').get(0);

	if (!footer)
		return;

	/* Add RSS link */
	var item = new DOMQuery('head link[type="application/rss+xml"]');

	if(item.length > 0)
	{
		var rss = item.get(0);

		var a = createDOMNode('a', {"href" : rss.href, "type" : rss.type, "title" : rss.title, "class" : 'rss-link'}, ['RSS']);

		footer.insertBefore(a, footer.firstChild);
	}

	var form = new DOMQuery('div#navigation form');
	if(form.length > 0)
	{
		footer.insertBefore(form.get(0).cloneNode(true), footer.firstChild);
	}
};

function topicNavigationPulldown(targets)
{
	addEventToTargets(targets, 'submit', function(){ return _handleTopicNavigationPulldown(this);}, 'form.topic-navigation');
	addEventToTargets(targets, 'change', function(){ return _handleTopicNavigationPulldown(this.form);}, 'form.topic-navigation select');
};

function _handleTopicNavigationPulldown(form)
{
	document.location.href = form.attributes['action'].value + form.elements['action'].value +'/'+ form.elements['data[topicid]'].value +'/'+ form.elements['data[offset]'].value;
	return false;
};

function pulldownAutoSubmits(targets)
{
	addEventToTargets(targets, 'change', _handlePullDowns, 'select.faq-list, form.topic-navigation select, form#more-topic select, select#calendar-select-date, select.page-dropdown');
	addEventToTargets(null, 'change', boardForumPulldown, 'select.jump-to-action');
};

function _handlePullDowns()
{
	if(this.tagName.toLowerCase() == 'select')
		this.form.submit();
};

function toggleAuthorLinks(targets)
{
	var items = getTargets(targets, 'ol.messages div.author-nickname');

	if(items.length == 0)
		return;

	for(var i = 0, item; (item=items.get(i)); i++)
	{
		addEvent(item, 'click', _toggleAuthorLinks);
		jscss('add', item, 'author-links-toggle', '');
	}
};

function _toggleAuthorLinks()
{
	var item = new DOMQuery('ul.author-links', getSiblingNode(this, 'up', 'li')).get(0);

	if (item)
	{
		jscss('toggle', item, 'author-links-expanded');
	}
	jscss('toggle', this, 'author-links-toggle-open');
};

function followTopicLinks()
{
	var subitems = new DOMQuery('a', this);
	if(subitems.length == 1)
	{
		window.location.href = subitems.get(0).href;
	}
}

var toggleVisibilityCookie;
function toggleVisibility(targets)
{
	var items = getTargets(
		targets,
		'h3[id] + fieldset, h3[id] + dl.property-list, tr[id].category-name td, div.extra-actions ul li#forum-tagcloud, div.discussion-folders ul.folders li[id]'
	);

	if(items.length == 0)
		return;

	getToggleVisibilityCookie();

	for(var i = 0, item;(item=items.get(i));i++)
	{
		switch(item.tagName.toLowerCase())
		{
			case 'li':
			case 'td':
				addEvent(item, 'click', _toggleVisibility);
				jscss('add',item,'toggle-icon','');

				if(toggleVisibilityCookie.indexOf(item.tagName.toLowerCase() == 'li' ? item.id : item.parentNode.id) > -1)
					_toggleVisibility(true, item);
			break;
			default:
				addEvent(item.previousSibling, 'click', _toggleVisibility);
				jscss('add',item.previousSibling,'toggle-icon','');

				if(toggleVisibilityCookie.indexOf(item.previousSibling.id) > -1)
					_toggleVisibility(true, item.previousSibling);
			break;
		}
	}
};

function _toggleVisibility(init, x)
{
	if(typeof x == 'undefined')
		x = this;

	/* don't toggle when the user clicks a link */
	if(typeof init == 'object')
	{
		var target = init.srcElement || init.target;
		if(target.tagName.toLowerCase() == 'a')
			return;
	}

	var tagname = x.tagName.toLowerCase();

	if(tagname == 'td')
	{
		if(init != true)
			storeToggleVisibility(x.parentNode.id, jscss('check', x, 'toggle-alternate-icon'));

		var node = x.parentNode;

		while( node.nextSibling && (node = node.nextSibling) && !jscss('check', node, 'category-name') )
		{
			jscss('toggle', node, 'display-none','');
		}
	}
	else
	{
		if(init != true)
		{
			storeToggleVisibility(x.id, jscss('check', x, 'toggle-alternate-icon'));
		}

		if(tagname == 'li')
		{
			jscss('toggle', x, 'display-no-childs');
		}
		else
		{
			jscss('toggle', x.nextSibling, 'display-none','');
		}
	}

	if(typeof init == 'object')
	{
		init.stopPropagation();
	}

	jscss('toggle', x, 'toggle-alternate-icon','');

	return;
};

function storeToggleVisibility(x, del)
{
	toggleVisibilityCookie = toggleVisibilityCookie.getUnique();

	if(toggleVisibilityCookie.indexOf(x) > -1 && del)
	{
		var newCookie = [];
		for(var i=0, item;(item=toggleVisibilityCookie[i]);i++)
		{
			if( item != x )
				newCookie.push(item);
		}

		toggleVisibilityCookie = newCookie;
	}
	else
	{
		if (toggleVisibilityCookie.indexOf(x) == -1)
			toggleVisibilityCookie.push(x);
	}

	setCookie('toggle', toggleVisibilityCookie.join(':'));
};

function getToggleVisibilityCookie()
{
	var c = getCookie('toggle');
	toggleVisibilityCookie = [];

	if(c)
		toggleVisibilityCookie = c.split(':');
};

function disabledOption()
{
	if(jscss('check', this.options[this.selectedIndex], 'disabled', ''))
	{
		this.selectedIndex = -1;
		alert(getText('normal', 'disabled_option'));
	}
};

function fixBrowserIssues()
{
	var i = 0, items, item;

	if(board_action == 'error_general')
	{
		var reference = new DOMQuery('ul.error-links li.home').get(0);
		if(reference)
		{
			reference.parentNode.appendChild(
				createDOMNode('li', {"class" : "back"}, [
					createDOMNode('span', {"class" : "clickable", "event" : ['click', function() { history.go(-1);}] }, [ getText('normal', 'back') ])
				])
			);
		}
	}

	if(isIE)
	{
		items = new DOMQuery('dt.required');
		var req = null;
		for(i = 0;(item=items.get(i));i++)
		{
			req = createDOMNode('span', {"class" : 'required'}, [' *']);
			item.appendChild(req);
		}

		items = new DOMQuery('button');
		for(i = 0 ; (item=items.get(i));i++)
		{
			addEvent(item, 'click', function() { this.value = this.attributes['value'].value; });
		}

		/* IE has problems with unicode characters in forms with 'multipart' encoding
		   It 'ignores' the first input field, so we add a bogus one for IE to forget */
		items = new DOMQuery('form');
		for(i = 0 ; (item=items.get(i));i++)
		{
			if(typeof item == 'undefined')
				continue;

			if ( typeof item.enctype != 'undefined' && item.enctype == 'multipart/form-data' )
			{
				var input = createDOMNode('input', {"type" : 'hidden', "name" : 'ie-dummy'}, []);

				if ( item.elements[0] )
					item.insertBefore(input, item.elements[0]);
				else
					item.insertBefore(input);
			}
		}

		var disabled = new DOMQuery("option[disabled]"), j, parent, parents = [];
		for(i = 0;(item=disabled.get(i));i++)
		{
			jscss('add', item, 'disabled', '');
			parent = getSiblingNode(item, 'up', 'select');

			if(parents.indexOf(parent) < 0)
			{
				addEvent(parent, 'change', disabledOption);

				if(jscss('check', parent.options[parent.selectedIndex], 'disabled'))
					parent.selectedIndex = -1;

				parents.push(parent);
			}
		}
		parents = null;
	}

	if(isIE && isNotIE7)
	{
		// MSIE can't handle first-child/last-child, so let's fix it ourselfs,
		// including some other selectors ander :after fixes
		addClassToTargets('div.action-header ol li:first-child, div#navigation li:first-child, div#welcome-text li:first-child, ul.calendar-navigation-up li:first-child', 'first-child');
		addClassToTargets('form .advanced-option + *, form dt.advanced-option + * + dd.dd-sequence, form dt.advanced-option + * + dd.dd-sequence + dd.dd-sequence', 'advanced-option-adjacent');
		addClassToTargets('div.rmltoolbar + textarea#rml_textarea', 'adjacent');

		items = new DOMQuery('input');
		for(i=0; (item=items.get(i));i++)
		{
			jscss('add', item, item.type);
		}

		addClassToTargets('dd.poll-result span > span', 'sub');
		addClassToTargets('dt:first-child + dd + dd.poll-result span', 'first');

		var _toggleAdvancedOptions = toggleAdvancedOptions;
		/* prevent repaint problems in IE6 */
		toggleAdvancedOptions = function()
		{
			document.body.style.display = 'none';
			 _toggleAdvancedOptions();
			document.body.style.display = 'block';
		}
	}
	else if(isWebKit)
	{
		// fancyfy the searchfields; make 'm pretty
		items = new DOMQuery('input.searchfield');
		var a = createDOMNode('a', {"href" : board_script_url}, []);
		for(i = 0; (item=items.get(i));i++)
		{
			item.setAttribute('type', 'search');

			// apple prefers a nl.react.www.search syntax
			item.setAttribute('autosave', a.host.split('.').reverse().join('.')+'.search');
			item.setAttribute('results', 5);
			item.setAttribute('placeholder', getText('normal', 'search_webkit') );
		}

		// Fix a flow-render problem
		items = new DOMQuery('div#content, div#footer');
		for(i = 0; (item=items.get(i));i++)
			item.style.overflow = 'visible';
	}
};

function attachRMLToolbar(targets)
{
	var rmltextareas = getTargets(targets, 'textarea#rml_textarea');

	if(rmltextareas.length == 0)
		return;

	for(var i = 0, item; (item=rmltextareas.get(i));i++)
	{
		item.parentNode.insertBefore(getToolbar(board_documentlibrary_allowed), item);
		if(isIE)
		{
			addEvent(item, 'click', storeCursor);
			addEvent(item, 'keyup', storeCursor);
			addEvent(item, 'select', storeCursor);
		}
	}

	/* dirty IE hack to force reflow */
	if(rmltextareas.length > 0 && isIE)
	{
		document.body.style.display = 'none';
		document.body.style.display = 'block';
	}
};

function logoutSessions(targets)
{
	if(board_action != 'logout')
		return;

	var sessions = getTargets(targets, 'input[type="checkbox"]');

	for(var i=0, item; (item=sessions.get(i)); i++)
	{
		addEvent(item, 'change', _logoutSessions);
		addEvent(item, 'click', _logoutSessions);
	}
};

function _logoutSessions()
{
	var logoutOptions = new DOMQuery('form#form-logout input[type="radio"]'), logoutBySession = new DOMQuery('input#logout_by_session');

	for(var i=0, item; (item=logoutOptions.get(i));i++)
	{
		item.checked = false;
	}

	logoutBySession.get(0).checked = true;
};

function setupToggleFolders()
{
	var menu = new DOMQuery('div.discussion-folders li');

	if(menu.length == 1)
	{
		addEvent(menu.get(0), 'click', toggleFolders);
	}
};

function toggleFolders(e)
{
	e.stopPropagation();

	var childs = new DOMQuery('ul', this);

	if(childs.length > 0)
	{
		jscss('toggle', this, 'active');
	}
};

function toggleTagcloudOverflow(e)
{
	var tagcloud = new DOMQuery('li.forum-tagcloud div').get(0);
	if(!tagcloud)
		return;

	if (new DOMQuery('a', tagcloud).length < 10)
		return;

	var more = createDOMNode('span', {'event' : ['click', function(e) { jscss('toggle', tagcloud, 'show-all'); e.stopPropagation(); }] }, [ ' ' + getText('normal', 'more') ]);

	tagcloud.appendChild(more);
};

/* used for quoteing messages to textarea */
var raw_messages = [];
var formRequiredFieldsDOMQuery = 'dt.required + dd input, dt.required + dd textarea, dt.required + dd select, dt[class^="requires-id-"] + dd input, dt[class^="requires-id-"] + dd textarea, dt[class^="requires-id-"] + dd select';
var formValidateFieldsDOMQuery = formRequiredFieldsDOMQuery + ', input[class^="validate-"], input#pwd2, input#keywords';
var focusableElements;

function focusFirstFormField(targets)
{
	focusableElements = getTargets(targets, 'input.focusable, textarea.focusable');

	if(focusableElements.length > 0)
	{
		setTimeout("focusableElements.get(0).focus();", 100);
	}
};

function validateForms(targets)
{
	var items = getTargets(targets, 'form');

	if(items.length == 0)
		return;

	for(var i = 0, item; (item=items.get(i));i++)
	{
		addEvent(item, 'submit', function(e) { if(!validateForm(this)) { e.preventDefault(); } } );
	}

	items = new DOMQuery(formRequiredFieldsDOMQuery);
	if(items.length > 0)
	{
		var text = new DOMQuery('div#action-header p'), p;

		if(text.length > 0)
		{
			p = text.get(0);
			p.appendChild(
				createDOMNode(null, {},
				[
					createDOMNode('br', {}, [ ]),
					createDOMNode('span', {}, [ getText('forms', 'marked_fields') ]),
					createDOMNode('span', {"class" :'required'}, ['*']),
					createDOMNode('span', {}, [ getText('forms', 'required') ])
				])
			);
		}
		else
		{
			p = createDOMNode('p', {},
				[
					createDOMNode('span', {}, [ getText('forms', 'marked_fields') ]),
					createDOMNode('span', {"class" :'required'}, ['*']),
					createDOMNode('span', {}, [ getText('forms', 'required') ])
				]
			);

			var h2 = new DOMQuery('div#action-header h2').get(0);
			if(h2)
				h2.parentNode.insertBefore(p, h2);
		}
	}

	items = new DOMQuery(formValidateFieldsDOMQuery);
	for(var j = 0; (item=items.get(j));j++)
	{
		addEvent(item, 'change', function() { validateField(this); }  );
	}
};

function hideAdvancedOptions(targets)
{
	var advancedOptions = getTargets(targets, 'dt.advanced-option');

	if(forms_show_advanced_options)
	{
		jscss('add', document.body, 'show-advanced-options', '');
	}
	else if(advancedOptions.length > 0)
	{
		if((new DOMQuery('span#toggle-advanced-options', document)).length == 0)
		{
			var p = new DOMQuery('div#action-header p', document).get(0);
			if(!p)
			{
				p = createDOMNode('p', {}, []);
				var h2 = new DOMQuery('div#action-header h2', document).get(0);
				if(!h2)
					return;

				h2.parentNode.insertBefore(p, h2);
			}

			p.appendChild(
				createDOMNode(null, {},
				[
					createDOMNode('br', {}, [ ]),
					createDOMNode('span',
							{
								'event' : ['click', toggleAdvancedOptions],
								'id' 	: 'toggle-advanced-options',
								'class' : 'clickable',
								'name'	: 'showAdvancedOptions'
							},
							[ getText('forms', 'show_advanced_options') ]
					)
				])
			);
		}

		if(document.location.hash == '#showAdvancedOptions')
		{
			toggleAdvancedOptions();
		}
	}
}

function toggleAdvancedOptions()
{
	var items = new DOMQuery('form');

	if(items.length == 0)
		return;

	var indicator = new DOMQuery('span#toggle-advanced-options').get(0);

	if (!indicator)
		return;

	for(var i=0, item; (item=items.get(i)); i++)
	{
		jscss('toggle', item, 'show-advanced-options');
		if(jscss('check', item, 'show-advanced-options'))
		{
			if(isIE)
			{
				item.attributes['action'].value = item.attributes['action'].value.replace(/#(.+)$/, '') + '#showAdvancedOptions';
			}
			else
			{
				item.setAttribute('action', item.getAttribute('action').replace(/#(.+)$/, '') + '#showAdvancedOptions');
			}

			if(i > 0)
				continue;

			if(!isIE)
				window.location.hash = '#showAdvancedOptions';

			indicator.firstChild.nodeValue = getText('forms', 'hide_advanced_options');
		}
		else
		{
			if(isIE)
			{
				item.attributes['action'].value = item.attributes['action'].value.replace(/#(.+)$/, '');
			}
			else
			{
				item.setAttribute('action', item.getAttribute('action').replace(/#(.+)$/, '') );
			}

			if(i > 0)
				continue;

			if(!isIE)
			{
				if (indicator.id == 'showAdvancedOptions')
					document.location.hash = indicator.id;
				else
					document.location.hash = 'hideAdvancedOptions'; //Does not exist, but setting to '' does funky things
			}
			indicator.firstChild.nodeValue = getText('forms', 'show_advanced_options');
		}
	}
};


function validateMaxLength()
{
	// Sjon: uitgeschakelt na overleg met Michiel; dit voldoet niet voldoende
	return false;

	if(this.tagName.toLowerCase() == 'input' && typeof this.maxLength != 'undefined' && this.maxLength > 0)
	{
		if(this.value.length == this.maxLength)
		{
			alertUser(this, getText('forms', 'max_chars', this.maxLength));
		}
		else
		{
			unAlertUser(this);
		}
	}
};

function validateForm(form)
{
	var items = new DOMQuery(formValidateFieldsDOMQuery, form);
	var errors = false;

	for (var i = 0, item; (item=items.get(i));i++)
	{
		errors = validateField(item, true) || errors;
	}

	if (errors)
	{
		var fields = new DOMQuery('dt.field-alert + dd input');

		if (fields.length > 0)
		{
			if (!jscss('check', fields.get(0).form, 'show-advanced-options'))
			{
				var hiddenFields = new DOMQuery('h3.advanced-option dt.field-alert + dd input, dt.field-alert.advanced-option + dd input');

				if (hiddenFields.length > 0)
					toggleAdvancedOptions();
			}

			fields.get(0).focus();
		}
	}

	return !errors;
};

/*
	return false is field is valid
	return true is field is not valid
*/
function validateField(ob, ret)
{
	var field = this.tagName ?  this : ob, empty = false;

	unAlertUser(field);

	if ( jscss('check', field, 'not-required') )
		return false;

	switch(field.type)
	{
		case 'select-one':
		case 'select-multiple':
			empty = (field.selectedIndex == -1) || (field.value == '') ;
			break;
		case 'checkbox':
			empty = !field.checked;
			break;
		default:
			empty = (field.value == '' ? true : false);
			break;
	}

	if(!empty)
	{
		switch(board_action)
		{
			case 'create_user':
			case 'edit_user':
				switch(field.id)
				{
					case 'pwd2':
						validatePassword(field);
					break;
					case 'nickname':
						if(field.value.length < 3)
						{
							alertUser(field, getText('forms', 'name_too_short'));
						}
						else if(!ret)
						{
							validateNickname(field);
						}
					break;
					case 'email':
						if(!ret)
						{
							validateEmail(field);
							validateEmailDomain(field);
						}
					break;
				}
			default :
				var reg, res, value = field.value;

				if(jscss('check', field, 'validate-email', ''))
				{
					reg = /^[\w-]+([\.\+][\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
					res = reg.test(value);
					if(!res)
					{
						alertUser(field, getText('forms', 'email_incorrect'));
						return true;
					}
				}
				if(jscss('check', field, 'validate-url', ''))
				{
					if (jscss('check', field, 'no-http', ''))
						reg = /^(([0-9]{1,3}\.){3}[0-9]{1,3}|\[([a-f0-9:]+)\]|([0-9a-z_!~*'\(\)-]+\.)*([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.[a-z]{2,6})(\/?|(\/[0-9a-z_!~*'\(\)\.;?:@&=+$,%#-]+)+\/?)$/i;
					else
						reg = /^(https?:\/\/)(([0-9]{1,3}\.){3}[0-9]{1,3}|\[([a-f0-9:]+)\]|([0-9a-z_!~*'\(\)-]+\.)*([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\.[a-z]{2,6})((\/?)|(\/[0-9a-z_!~*'\(\)\.;?:@&=+$,%#-]+)+\/?)$/i;

					res = reg.test(value);
					if(!res)
					{
						alertUser(field, getText('forms', 'url_incorrect'));
						return true;
					}
				}
				if(jscss('check', field, 'validate-integer', '') || jscss('check', field, 'validate-sofinummer', ''))
				{
					reg = /^[0-9]*$/;
					res = reg.test(value);
					if(!res)
					{
						alertUser(field, getText('forms', 'numeric_only'));
						return true;
					}
				}
				if(jscss('check', field, 'validate-sofinummer', ''))
				{
					if(value.length != 9)
					{
						alertUser(field, getText('forms', 'length_not_9'));
						return true;
					}
					/* source: http://cgi.dit.nl/sofi.cgi */
					var total = 0;
					for (i=1; i<=8; i++)
					{
						total += (10-i) * value[i-1];
					}
					total += (-1) * value[8];

					if ((total % 11) > 0)
					{
						alertUser(field, getText('forms', 'sofinummer_mismatch'));
						return true;
					}
				}

				switch(field.id)
				{
					case 'keywords':
						/*reg = /[^\w0-9_\-.]/;*/
						var values = value.split(' ');
						for(i=0;(value=values[i]);i++)
						{
							if(value.length > 50)
							{
								alertUser(field, getText('forms', 'keyword_too_long', value));
								return true;
							}

							/*res = reg.test(value);
							if(res)
							{
								alertUser(field, getText('forms', 'keywords_illegal_character', value));
								return true;
							}*/
						}
					break;
				}

				// If you want custom-field validation, create functions and add functionnames to array 'extraValidateFields'
				if(typeof extraValidateFields == 'object')
				{
					for(i=0; i<extraValidateFields.length; i++)
					{
						extraValidateFields[i](field);
					}
				}
			break;
		}
	}

	var dtFieldName = getSiblingNode(field.parentNode, 'previous', 'dt');
	if(dtFieldName)
	{
		var isRequired   = jscss('check', dtFieldName, 'required');

		/* Mark other fields as required when this field is not empty */
		var res = /requires\-id\-([a-z0-9_]+)/i.exec(dtFieldName.className);
		if(res && res[0])
		{
			var inputField = new DOMQuery('#' + res[1]).get(0);
			if(inputField)
			{
				if(!empty)
					jscss('add', getSiblingNode(inputField.parentNode, 'previous', 'dt'), 'required');
				else
					jscss('remove', getSiblingNode(inputField.parentNode, 'previous', 'dt'), 'required');

				return validateField(inputField, true);
			}
		}
	}

	if (empty && isRequired)
	{
		alertUser(field, getText('forms', 'required_field'));
	}
	else if (empty && !isRequired)
	{
		return false;
	}

	if (ret)
		return empty;
};

function alertUser(inputfield, str)
{
	var ddInputField = inputfield.parentNode;
	var ddErrorMsg   = getSiblingNode(inputfield.parentNode, 'next', 'dd');
	var dtFieldName  = getSiblingNode(inputfield.parentNode, 'previous', 'dt');

	if(!ddErrorMsg || !jscss('check',ddErrorMsg,'dd-sequence field-alert',''))
	{
		jscss( 'add', dtFieldName, 'field-alert', '');

		var x = createDOMNode('dd', {"class" :'dd-sequence field-alert'}, [str]);

		/* Add special class for IE6 if it is an advanced option */
		if(isIE && isNotIE7 && (jscss('check', dtFieldName, 'advanced-option') || jscss('checkParents', dtFieldName, 'advanced-option')))
			jscss( 'add', x, 'advanced-option-adjacent', '');

		ddInputField.parentNode.insertBefore(x, ddInputField.nextSibling);
	}
};


function unAlertUser(inputfield)
{
	var ddInputField = inputfield.parentNode;
	var ddErrorMsg   = getSiblingNode(inputfield.parentNode, 'next', 'dd');
	var dtFieldName  = getSiblingNode(inputfield.parentNode, 'previous', 'dt');

	if(ddErrorMsg && jscss('check',ddErrorMsg,'dd-sequence field-alert'))
	{
		ddInputField.parentNode.removeChild(ddErrorMsg);
		jscss('remove', dtFieldName, 'field-alert', '');
	}
};

function _validationResult(request)
{
	if (typeof request != 'undefined' && request != null && request.readyState == 4)
	{
		var response = getElementFromXHR(request, 'div#core');

		return response.firstChild.nodeValue;
	}

	return "0";
};

function _xmlrequestComplete(request)
{
	return typeof request != 'undefined' && request != null && request.readyState == 4;
};


function validatePassword(x)
{
	var pwd1 = new DOMQuery('input#pwd1').get(0);

	if(pwd1.value != x.value)
	{
		alertUser(x, getText('forms', 'password_no_match'));
		x.value = '';
	}
};


function validateNickname(field)
{
	nicknamereq = null;
	var request = 'action=custom&data%5Btemplate%5D=validate_nickname&data%5Bnickname%5D='+encodeURI(field.value);
	nicknamereq = httpreq_string(request, _validateNickname, null, true, "GET");

};

function _validateNickname()
{
	if (_xmlrequestComplete(nicknamereq) && _validationResult(nicknamereq) == '1')
	{
		alertUser(new DOMQuery('#nickname').get(0), getText('forms', 'username_taken'));
	}
};


function validateEmailDomain(field)
{
	emaildomainreq = null;
	var request = 'action=custom&data%5Btemplate%5D=validate_emaildomain&data%5Bemail%5D='+encodeURI(field.value);
	emaildomainreq = httpreq_string(request, _validateEmailDomain, false, true, "GET");
};


function _validateEmailDomain()
{
	if (_validationResult(emaildomainreq) == '1')
	{
		alertUser(new DOMQuery('#email').get(0), getText('forms', 'invalid_domain'));
	}
};


function validateEmail(field)
{
	emailreq = null;
	var request = 'action=custom&data%5Btemplate%5D=validate_email&data%5Bemail%5D='+encodeURI(field.value);
	emailreq = httpreq_string(request, _validateEmail, false, true, "GET");
};


function _validateEmail()
{
	if (emailreq && _validationResult(emailreq) == '1')
	{
		alertUser(new DOMQuery('#email').get(0), getText('forms', 'email_taken'));
	}
};

function attachCalendarSelector(targets)
{
	var calendarSelectors = getTargets(targets, 'input.date'), item;

	for(var i = 0, item; (item=calendarSelectors.get(i));i++)
	{
		if(item.id != '')
		{
			Calendar.setup({
				inputField			:		item.id,
				ifFormat			:		"%d-%m-%Y",
				showsTime			:		false,
				align				:		"Tl",
				step				:		1,
				electric			:		false,
				firstDay			:		1,
				onClose				:		function(cal)
											{
												cal.hide();
												if(document.createEvent)
												{
													var evt = document.createEvent("HTMLEvents");
													evt.initEvent("change", true, true);
													cal.params['inputField'].dispatchEvent(evt);
												}
												else if(document.createEventObject)
												{
													var evt = document.createEventObject();
													cal.params['inputField'].fireEvent("onchange", evt);
												}
											}
			});
		}
	}
};

function selectAllRows(targets)
{
	var checkboxes = getTargets(targets, 'div#content form table input[TYPE="checkbox"]');

	if(checkboxes.length == 0)
		return;

	var tablefooter = new DOMQuery("div#content form tfoot").get(0);

	var tr = createDOMNode('tr', {"class" :'footer-form'},
	[
		createDOMNode('td', {"class" :'select'},
		[
			createDOMNode('input', {"type" :'checkbox', "id" :'selectAllRows', "name" :'selectAllRows', "event" : (isIE ? ['click', _selectAllRows] : ['change', _selectAllRows]) }, [])
		]),
		createDOMNode('td', {"colSpan" :5},
		[
			createDOMNode('label', {'for' : 'selectAllRows'}, [getText('forms', 'select_all_rows')])
		])
	]);

	tablefooter.appendChild(tr);

	if(isGecko && !isWebKit)
	{
		jscss('add',document.body,'display-none','');
		jscss('remove',document.body,'display-none','');
	}
};

function _selectAllRows()
{
	var checked = this.checked;
	var items = new DOMQuery('tbody input[TYPE="checkbox"]', getSiblingNode(this, 'up', 'table'));
	for(var i = 0, item; (item=items.get(i));i++)
	{
		item.checked = checked;
	}
};

function rewriteQuoteLinks()
{
	if(raw_messages.length == 0)
		return;

	for(var i = 0, item; (item=raw_messages[i]); i++)
	{
		/* using a reference to message-? to slightly speed up lookup */
		var links = new DOMQuery("li.message-quote a", new DOMQuery("li#message-"+item[0]).get(0) );

		if(links.length > 0)
		{
			addEvent(links.get(0), 'click', function(e) { if(!copyQuoteToRML(this)) { e.preventDefault(); } } );
		}
	}
};

function copyQuoteToRML(x)
{
	var path = board_script_url + '/quote_message/';
	var temp = x.href.substring( path.length );
	var reg = /^([0-9]+)/;
	var res = temp.match(reg);
	var messageid = res[1];

	for(var i = 0, item; (item=raw_messages[i]);i++)
	{
		if(item[0] == messageid)
		{
			putStr(item[1]);
			return false;
		}
	}

	return true;
};

/* helper function for raw messages */
function q()
{
	return '"';
};

function privateMessagingCopyContact(targets)
{
	if(board_action == 'pm_new_message')
		addEventToTargets(targets, 'change', _privateMessagingCopyContact, 'input#recipients + select');
};

function _privateMessagingCopyContact()
{
	if(this.options[this.selectedIndex].value == '')
		return;

	var input = new DOMQuery("input#recipients").get(0);

	var username = this.options[this.selectedIndex].value;

	if ( username.match("'") )
		username = '"'+ username + '"';
	else if ( username.match(/^[0-9]+$/) || username.match('"') )
		username = "'"+ username + "'";

	input.value += (input.value != '' ? ', ' : '') + username;
};

function selectSelectedTopicAdmin()
{
	var topicAdmin = new DOMQuery("div#topic-admin").get(0);

	if(!topicAdmin)
		return;

	var selects = new DOMQuery('select[selected]', topicAdmin);

	for (var i = 0, select; (select=selects.get(i));i++)
	{
		for (var j = 0; j<select.options.length; j++)
		{
			if (select.options[j].value == select.getAttribute("selected"))
				select.options[j].selected = true;
		}
	}
};

function toggleChangeCheckboxTopicAdmin()
{
	var topicAdmin = new DOMQuery("div#topic-admin").get(0);

	if(!topicAdmin)
		return;

	var items = new DOMQuery('input[type="text"], textarea, select', topicAdmin);

	for(var i = 0, item; (item=items.get(i));i++)
	{
		addEvent(item, 'change', _toggleChangeCheckboxTopicAdmin);
	}

	var input = new DOMQuery("input#delmessages").get(0);
	if(input)
	{
		addEvent(input, 'change', selectMessagesForDeletion);
	}

	input = new DOMQuery("input#splitmessages").get(0);
	if(input)
	{
		addEvent(input, 'change', selectMessagesForSplit);
	}
};

function _toggleChangeCheckboxTopicAdmin()
{
	var search = jscss('check', this.parentNode, 'dd-sequence') ? this.parentNode.previousSibling :  this.parentNode;
	var items = new DOMQuery('input[type="checkbox"]', search);

	if(items.length > 0)
	{
		items.get(0).checked=true;
	}
};

var callbackOnMessageToggledSelected = null;
function _selectMessages(unsetCurrentMessages)
{
	var items = new DOMQuery('li.message');

	for(var i=0, item; (item=items.get(i));i++)
	{
		addEvent(item, 'click', _selectMessage);
		if(unsetCurrentMessages)
		{
			jscss('remove', item, 'selected', '');
		}
	}
};

function _selectMessage()
{
	if(!callbackOnMessageToggledSelected)
		return;

	jscss('toggle', this, 'selected', '');
	callbackOnMessageToggledSelected(this, jscss('check', this, 'selected', ''));
};

function _messageToggledForDeletion(listitem, selected)
{
	var del_messageids = new DOMQuery("input#del_messageids").get(0);
	if(!del_messageids)
		return;

	var reg = /^message\-([0-9]+)$/;
	var res = listitem.id.match(reg);
	var messageid = res[1];

	var ids = del_messageids.value.split(',');

	if(selected)
	{
		ids[ids.length] = messageid;
	}
	else
	{
		for(var i = 0; i < ids.length; i++)
		{
			if(ids[i] == messageid)
			{
				delete ids[i];
			}
		}
	}

	del_messageids.value = ids.join(',');
};

function selectMessagesForDeletion()
{
	var del_messageids = new DOMQuery("input#del_messageids").get(0);
	if(!del_messageids)
		return;

	del_messageids.value = '';

	_selectMessages(!this.checked);

	if(!this.checked)
		callbackOnMessageToggledSelected = null;
	else
		callbackOnMessageToggledSelected = _messageToggledForDeletion;

	if(this.checked)
		alert(getText('forms', 'select_messages'));
};

function _messageToggledForSplit(listitem, selected)
{
	var split_messageids = new DOMQuery("input#split_messageids").get(0);
	if(!split_messageids)
		return;

	var reg = /^message\-([0-9]+)$/;
	var res = listitem.id.match(reg);
	var messageid = res[1];

	var ids = split_messageids.value.split(',');

	if(selected)
	{
		ids[ids.length] = messageid;
	}
	else
	{
		for(var i=0, item; (item=ids[i]);i++)
		{
			if(item == messageid)
				delete item;
		}
	}

	split_messageids.value = ids.join(',');
};

function selectMessagesForSplit()
{
	var split_messageids = new DOMQuery("input#split_messageids").get(0);
	if(!split_messageids)
		return;

	split_messageids.value = '';

	_selectMessages(!this.checked);
	if(!this.checked)
		callbackOnMessageToggledSelected = null;
	else
		callbackOnMessageToggledSelected = _messageToggledForSplit;

	if(this.checked)
		alert(getText('forms', 'select_messages'));
};

var doclibsOpened = Array();
var currentTextarea;

var rml_buttons = Array('bold', 'italic', 'underline', 'strike','hline',
						/*'sup', 'sub','hline',*/
						'align_left', 'align_center', 'align_right','hline',
						'list_bullet', 'list_num','hline',
						/*'color_bg', */'color_fg','hline',
						'link', 'image','hline',
						'table', 'hr','hline',
						'maximize', 'documentlibrary', 'smileys');

function setCurrentTextarea(window)
{
	currentTextarea = doclibsOpened[window];
};

function getToolbar( showDocumentLibrary )
{
	var x = createDOMNode('div', {"class": "rmltoolbar"}, []);

	var image;
	for(var i = 0; i < rml_buttons.length;i++)
	{
		if(rml_buttons[i] == 'documentlibrary' && !showDocumentLibrary)
			continue;

		if(rml_buttons[i] == 'maximize' && events.indexOf(stretchTextareas) > -1)
			continue;

		if(rml_buttons[i] == 'smileys')
		{
			var smileys = (new DOMQuery('div#smileys')).get(0);
			if(!smileys)
				continue;

			var smileysClone = smileys.cloneNode(true);
			var smileysContainer = getSiblingNode(smileys, 'up', 'dd');
			var smileysContainerLabel = getSiblingNode(smileysContainer, 'previous', 'dt');

			smileysContainerLabel.parentNode.removeChild(smileysContainerLabel);
			smileysContainer.parentNode.removeChild(smileysContainer);

			x.appendChild(smileysClone);
		}

		image = document.createElement('img');

		if(rml_buttons[i] != 'hline')
			addEvent(image, 'click', handleRMLToolbarClick);
		else
			jscss('add',image,'hline','');

		image.id = 'rmltoolbar_'+rml_buttons[i];
		image.src = board_template_url+'img/icons/toolbar/'+rml_buttons[i]+'.gif';
		x.appendChild(image);
	}

	return x;
};

function handleRMLToolbarClick()
{
	if(this.parentNode && this.parentNode.nextSibling && this.parentNode.nextSibling.tagName == 'TEXTAREA')
	{
		currentTextarea = this.parentNode.nextSibling;
	}

	var listtype, my_link, my_title, sel, rows, type, out;

	switch(this.id)
	{
		case 'rmltoolbar_bold':
			wrapSelection('[b]','[/b]');
			return;
			break;
		case 'rmltoolbar_italic':
			wrapSelection('[i]','[/i]');
			return;
			break;
		case 'rmltoolbar_underline':
			wrapSelection('[u]','[/u]');
			return;
			break;
		case 'rmltoolbar_strike':
			wrapSelection('[s]','[/s]');
			return;
			break;
		case 'rmltoolbar_sup':
			wrapSelection('[sup]','[/sup]');
			return;
			break;
		case 'rmltoolbar_sub':
			wrapSelection('[sub]','[/sub]');
			return;
			break;
		case 'rmltoolbar_align_left':
			wrapSelection('[left]','[/left]');
			return;
			break;
		case 'rmltoolbar_align_center':
			wrapSelection('[center]','[/center]');
			return;
			break;
		case 'rmltoolbar_align_right':
			wrapSelection('[right]','[/right]');
			return;
			break;
		case 'rmltoolbar_list_bullet':
			listtype = '*';
		case 'rmltoolbar_list_num':
			if(typeof listtype == 'undefined')
				listtype = '1';
			var type = '*';
			var sel = getCurrentSelection();
			var rows = sel.split('\n');
			var out = '[list='+listtype+']';
			for(var i = 0, row;(row=rows[i]);i++)
			{
				if(row != '')
					out += '\n\t[li]'+row+'[/li]';
			}

			if(i==0)
			{
				out += '\n\t[li]'+row+'[/li]';
			}

			out += '\n[/list]';
			setSelection(out);
			return;
			break;
		case 'rmltoolbar_color_fg':
			attachColorSelector(this, function(hexColor) { wrapSelection("[fgcolor=" + hexColor + "]", "[/fgcolor]"); } );
			break;
		case 'rmltoolbar_color_bg':
			attachColorSelector(this, function(hexColor) { wrapSelection("[bgcolor=" + hexColor + "]", "[/bgcolor]"); } );
			break;
		case 'rmltoolbar_table':
			sel = getCurrentSelection();
			rows = sel.split('\n');
			out = '[table]';
			var j;
			for(var i = 0, row;(row=rows[i]);i++)
			{
				out += '\n[tr]';
				var cells = row.split('\t');
				for(j=0, cell;(cell=cells[j]);j++)
				{
					out += '\n\t[td]'+cell+'[/td]';
				}
				out += '\n[/tr]';
			}
			out += '\n[/table]';

			setSelection(out);
			return;
			break;
		case 'rmltoolbar_image':
			if(getCurrentSelection() != '')
			{
				wrapSelection('[img]', '[/img]');
				return;
			}
			my_link = prompt(getText('j_toolbar', 'enter_img_url'),"http://");

			if (my_link != null && my_link !='http://')
			{
				lft="[img]" + my_link;
				rgt="[/img]";
				wrapSelection(lft, rgt);
			}
			return;
			break;
		case 'rmltoolbar_link':
			my_link = prompt("Enter URL:","http://");
			if (my_link == null)
				return;

			var selection = getCurrentSelection();
			my_title = prompt(getText('j_toolbar', 'enter_title'),"");

			if ( selection == '' )
			{
				if(my_title != '' )
					lft="[url=" + my_link + "]"+my_title;
				else
					lft="[url=" + my_link + "]"+my_link;
			}
			else
			{
				if(my_title != '' )
					lft="[url=" + my_link + ","+my_title+"]";
				else
					lft="[url=" + my_link + "]";
			}

			rgt="[/url]";
			wrapSelection(lft, rgt);
			return;
			break;
		case 'rmltoolbar_documentlibrary':
			var ref = window.open(board_script_url+'/list_documents_small','DocumentLibrary','width=785,height=650,resizable=yes,scrollbars=yes');
			doclibsOpened[ref] = this.parentNode.nextSibling;
			break;
		case 'rmltoolbar_smileys':
			toggleSmileys();
			addEvent(get_rmltextarea(), 'focus', hideSmileys);
			addEvent(get_rmltextarea(), 'blur', hideSmileys);
			break;
		case 'rmltoolbar_maximize':
			var txtarea = get_rmltextarea();
			if(jscss('check',txtarea,'extra-large',''))
			{
				jscss('remove',txtarea,'extra-large','');
				jscss('remove',txtarea,'large','');
			}
			else if( jscss('check',txtarea,'large') )
			{
				jscss('add',txtarea,'extra-large','');
			}
			else
			{
				jscss('add',txtarea,'large','');
			}
			break;
		case 'rmltoolbar_hr':
			setSelection('[hr]');
			break;
	}
};

function toggleSmileys()
{
	jscss('toggle', new DOMQuery('div#smileys').get(0), 'show');
};
function hideSmileys()
{
	jscss('remove', new DOMQuery('div#smileys').get(0), 'show');
};

function get_rmltextarea()
{
	if(typeof currentTextarea == 'undefined')
		currentTextarea = new DOMQuery('textarea#rml_textarea').get(0);
	return currentTextarea;
};

function getContentFromOriginal()
{
	get_rmltextarea().value=window.opener.get_rmltextarea().value;
};

function setContentToOriginal()
{
	window.opener.get_rmltextarea().value=get_rmltextarea().value;window.close();
};

function rescaleTextarea(txtarea)
{
	if (typeof document.all != 'undefined')
	{
		txtarea.style.height=(document.body.clientHeight-80)+'px';
		txtarea.style.width=(document.body.clientWidth-15)+'px';
	}
	else
	{
		txtarea.style.height=(window.innerHeight-80)+'px';
		txtarea.style.width=(window.innerWidth-15)+'px';
	}
};

function wrapSelection(lft, rgt)
{
	var txtarea = get_rmltextarea();

	if (typeof txtarea.selectionStart == 'undefined')
	{
		IEWrap(txtarea, lft, rgt);
	}
	else if (document.getElementById)
	{
		mozWrap(txtarea, lft, rgt);
	}
};

function mozWrap(txtarea, lft, rgt)
{
	var selLength = txtarea.textLength;
	var selStart = txtarea.selectionStart;
	var selEnd = txtarea.selectionEnd;
	if (selEnd==1 || selEnd==2)
	{
		selEnd = selLength;
	}
	var s1 = txtarea.value.substring(0,selStart);
	var s2 = txtarea.value.substring(selStart, selEnd);
	var s3 = txtarea.value.substring(selEnd, selLength);
	txtarea.value = s1 + lft + s2 + rgt + s3;
};

function IEWrap(txtarea, lft, rgt)
{
	strSelection = document.selection.createRange().text;
	if (strSelection != "")
	{
		document.selection.createRange().text = lft + strSelection + rgt;
	}
	else
	{
		txtarea.value += lft + rgt;
	}
};

function getCurrentSelection()
{
	if (typeof document.selection != 'undefined' && document.selection.createRange)
	{
		return IEGet();
	}
	else if (document.getElementById)
	{
		var txtarea = get_rmltextarea();
		return mozGet(txtarea);
	}
	return '';
};

function mozGet(txtarea)
{
	var selLength = txtarea.textLength;
	var selStart = txtarea.selectionStart;
	var selEnd = txtarea.selectionEnd;
	if (selEnd==1 || selEnd==2)
		selEnd=selLength;
	return (txtarea.value).substring(selStart, selEnd);
};

function IEGet()
{
	return document.selection.createRange().text;
};

function setSelection(str)
{
	var txtarea = get_rmltextarea();
	if (typeof document.all != 'undefined')
	{
		IESet(txtarea, str);
	}
	else if (document.getElementById)
	{
		mozSet(txtarea, str);
	}
};

function mozSet(txtarea, str)
{
	var selLength = txtarea.textLength;
	var selStart = txtarea.selectionStart;
	var selEnd = txtarea.selectionEnd;
	if (selEnd==1 || selEnd==2)
		selEnd=selLength;
	var s1 = txtarea.value.substring(0,selStart);
	var s2 = txtarea.value.substring(selStart, selEnd);
	var s3 = txtarea.value.substring(selEnd, selLength);
	txtarea.value = s1 + str + s3;
};

function IESet(txtarea, str)
{
	strSelection = document.selection.createRange().text;

	if (strSelection!="")
	{
		document.selection.createRange().text = str;
	}
	else
	{
		txtarea.value += str;
	}
};

function storeCursor()
{
	this.cursorPos = document.selection.createRange().duplicate();
};

function putStr( text )
{
	var target = get_rmltextarea();

	if ( target )
	{
		if (typeof document.all != 'undefined' && target.cursorPos)
		{
			var cursorPos = target.cursorPos;
			cursorPos.text = cursorPos.text.charAt(cursorPos.text.length - 1) == ' ' ? text + ' ' : text;
		}
		else
		{
			try
			{
				wrapSelection('', text);
			}
			catch(e)
			{
				target.value += text;
			}
		}

		target.focus();
	}
};
var element_m = false;
var delta_y = 0;
var delta_x = 0;

function findMoveableElement(e)
{
	if(!e)
	{
		e = window.event;
	}

	element_m = this;

	if(!element_m)
		return;

	delta_y = (y(e) - currentStyle(element_m, 'top'));
	delta_x = (x(e) - currentStyle(element_m, 'left'));
};

function moveElement(e)
{
	if(!e)
	{
		e = window.event;
	}

	if(element_m)
	{
		var maxLeft = parseInt(window.XMLHttpRequest ? document.body.offsetWidth:document.body.scrollWidth) - currentStyle(element_m, 'width');

		element_m.style.left = Math.min(maxLeft, Math.max(x(e) - delta_x, 0)) + 'px';
		element_m.style.top = Math.max(y(e) - delta_y, 0) + 'px';
	}
};

function moveEnd()
{
	if(element_m)
		element_m = false;
};

function x(e)
{
	return (e.clientX) ? e.clientX : e.pageX;
};

function y(e)
{
	return (e.clientY) ? e.clientY : e.pageY;
};

function createOverlay()
{
	var w = document.createElement('div');

	w.style.width = window.XMLHttpRequest ? document.body.offsetWidth : document.body.scrollWidth;
	w.style.height = document.body.scrollHeight + 50;
	w.id = 'overlay';

	document.body.appendChild(w);
};

function destroyOverlay()
{
	document.body.removeChild(document.getElementById('overlay'));
};
function getDocumentSelector(documentid)
{
	var data = raw_documents[documentid];
	var format_list = [ createDOMNode('option', {"value" : ''}, [getText('doclib', 'original')]) ];

	if(typeof formats != "undefined")
	{
		for(var i=0; i < formats.length;i++)
		{
			format_list[i+1] = createDOMNode('option', {"value" : formats[i][0]}, [formats[i][0]+ ' (' + formats[i][1][0] + 'x' + formats[i][1][1] + ')']);
		}
	}

	var insert_as = [
		createDOMNode('dt', {}, [getText('doclib', 'insert_as')]),
		createDOMNode('dd', {}, [
			createDOMNode('input', {"value" : 'image', "name" : 'as', "type" : 'radio', "id" : 'as_image_'+documentid+'_image', 'checked' : 'checked'}, []),
			createDOMNode('label', {'for' : 'as_image_'+documentid+'_image'}, [getText('doclib', 'insert_as_image')]),
			createDOMNode('input', {"value" : 'text', "name" : 'as', "type" : 'radio', "id" : 'as_text_'+documentid+'_image'}, []),
			createDOMNode('label', {'for' : 'as_text_'+documentid+'_text'}, [getText('doclib', 'insert_as_text')])
		] )
	];

	var insert_as_link = [
		createDOMNode('dt', {}, [getText('doclib', 'insert_as_link')]),
		createDOMNode('dd', {},
			[
				createDOMNode('input', {"value" : 'link', "name" : 'link', "type" : 'checkbox', "id" : 'link_'+documentid}, []),
				createDOMNode('label', {'for' : 'link_'+documentid}, [getText('doclib', 'insert_as_thumb')])
			]
		)
	];

	var format = [
		createDOMNode('dt', {}, [getText('doclib', 'format')]),
		createDOMNode('dd', {},
			[
				createDOMNode('select', {"name" : 'format', "id" : 'format_'+documentid}, format_list)
			])
	];

	var align = [
		createDOMNode('dt', {}, [getText('doclib', 'outline')]),
		createDOMNode('dd', {},
		[
			createDOMNode('select', {"name" : 'float', "id" : 'float_'+documentid},
			[
				createDOMNode('option', {"value" : ''}, [getText('doclib', 'none')]),
				createDOMNode('option', {"value" : 'left'}, [getText('doclib', 'left')]),
				createDOMNode('option', {"value" : 'right'}, [getText('doclib', 'right')])
			]),
		])
	];

	var insert = [
		createDOMNode('dt', {}, [getText('doclib', 'insert')]),
		createDOMNode('dd', {},
		[
			createDOMNode('input', {"value" : getText('doclib', 'insert_image'), "type" : 'submit'}, []),
		])
	];

	var preview_img = createDOMNode('img', {"id" : 'image_preview', "src" : data[0] + 'square'}, []);

	if (data[5] == '1')
	{
		/* If the document is remote and doesn't have an alternative icon. Don't show the image
	 	 * related form elements */
		if (data[6] != '1')
		{
			format = [];
			align = [];
			preview_img = document.createTextNode('');
		}
		else
		{
			insert_as_link[1].childNodes[0].disabled = true;
			insert_as_link[1].childNodes[0].checked = true;
			insert_as_link[1].childNodes[0].defaultChecked = true;
		}
	}

	var form_combined = insert_as.concat(insert_as_link, format, align, insert);

	form_combined = form_combined.concat(insert_as_link);
	form_combined = form_combined.concat(format);
	form_combined = form_combined.concat(align);
	form_combined = form_combined.concat(insert);

	var form =
		createDOMNode('div', {"id" : "document-selector"},
		[
			createDOMNode('h3', {"id" : 'insert_image'}, [getText('doclib', 'insert_image')]),
			preview_img,
			createDOMNode('form', {"method" : 'POST', "action" : board_script_url, "event" : ['submit', copy2rml]},
			[
				createDOMNode('fieldset', {},
				[
					createDOMNode('input', {"value" : documentid, "name" : 'documentid', "type" : 'hidden'}, []),
					createDOMNode('input', {"value" : data[0], "name" : 'url', "type" : 'hidden'}, []),
					createDOMNode('input', {"value" : data[1], "name" : 'key', "type" : 'hidden'}, []),
					createDOMNode('input', {"value" : data[2], "name" : 'libraryid', "type" : 'hidden'}, []),
					createDOMNode('input', {"value" : '', "name" : 'alt', "type" : 'hidden'}, []),
					createDOMNode('input', {"value" : data[4], "name" : 'filename', "type" : 'hidden'}, []),

					createDOMNode('dl', {}, form_combined)
				])
			])
		]);

	return form;
};

function doclibInteraction()
{
	switch(board_action)
	{
		case 'edit_document':
			addEventToTargets(null, 'click', modifyThumbnail, 'img[longdesc]');
		break;

		case 'list_documents_small':
			var links = new DOMQuery('a[href*="list_documents"]');

			for(var i = 0, link;(link = links.get(i));i++)
			{
				if(isIE)
				{
					/*
						IE checks if the link's firstChild.nodeValue equals a "valid" url,
						if so it will swap it's value with the newly set href.

						IE considers http://, https://, ftp:// and ^www. as "valid"

						IE should really die.
					*/
					if( link.firstChild.nodeValue.match(/^(((ftp|https?):\/\/)|(www\.))/) )
					{
						link.appendChild(createDOMNode('span', {'class' : 'dummy'}, []));
					}
				}

				link.href = link.href.toString().replace(/list_documents/, 'list_documents_small');
			}

			addEventToTargets(null, 'click', doclibImageClick, 'div.document');

		//FALLTHROUGH
		case 'list_documents':
			addEventToTargets(null, 'click', selectAllDocuments, 'input#select_all_documents');
			if(board_action == 'list_documents')
				addEventToTargets(null, 'click', selectDocument, 'div.document img, body.list_documents div.document li.select input');
		break;
	}

	/* yes, it's doubtfull wether this is the best place... */
	var items = new DOMQuery('ol.messages a.doclib');
	for(var i = 0, item; (item = items.get(i)); i++)
	{
		addEvent(item, 'click', function(e) { window.open(this.href, 'popupdoclib'); e.preventDefault(); } );
	}
};


/*
	this function can be called in 3 ways:
	- by the checkbox itself
	- by a click on the image
	- by selectAllDocuments()
*/
function selectDocument(obj)
{
	var callingElement = this.tagName ?  this : obj, checkbox;
	var container = getSiblingNode(callingElement, 'up', 'div');

	/* if it's not the checkbox itself who's calling us, toggle it */
	if ( callingElement.tagName.toLowerCase() != 'input' )
	{
		checkbox = new DOMQuery('input[type=checkbox]', container).get(0);
		checkbox.checked = !checkbox.checked;
	}
	else
	{
		checkbox = callingElement;
	}

	if ( checkbox.checked )
	{
		jscss('add', container, 'selected', '');

		if( (new DOMQuery('div.document input')).length == (new DOMQuery('div.document.selected input')).length)
			(new DOMQuery('input#select_all_documents').get(0)).checked = true;
	}
	else
	{
		jscss('remove', container, 'selected', '');

		(new DOMQuery('input#select_all_documents').get(0)).checked = false;
	}
};

function selectAllDocuments()
{
	/* uncheck selected images */
	if(board_action == 'list_documents')
	{
		var img = new DOMQuery('div.document.selected img');
		for(var i = 0; i < img.length;i++)
		{
			selectDocument(img.get(i));
		}
	}

	if(!this.checked)
		return;

	if(board_action == 'list_documents')
	{
		img = new DOMQuery('div.document img');

		for(i=0; i < img.length;i++)
		{
			selectDocument(img.get(i));
		}
	}
};

function deselectAllDocuments()
{
	var selectedDocuments = new DOMQuery('div.document.selected');
	for(var i = 0, selectedDocument; (selectedDocument=selectedDocuments.get(i)); i++)
	{
		jscss('remove', selectedDocument, 'selected', '');
	}
}

function doclibImageClick(e)
{
	var x = this;
	if(x.tagName.toLowerCase() != 'img')
		x = new DOMQuery('img', this ).get(0);

	if (typeof x == 'undefined')
		return;

	var container = getSiblingNode(x, 'up', 'div');
	var documentid = container.id.replace(/^document_/, '');

	/* store for later use */
	var currentlySelected = jscss('check', container, 'selected');
	deselectAllDocuments();

	/* destroy existing */
	var currentForm = new DOMQuery("div.discussion-content div#document-selector").get(0);
	if(currentForm)
		currentForm.parentNode.removeChild(currentForm);

	/* show just one form at a time */
	var searchForm = new DOMQuery('div#search-documents').get(0);
	if(currentlySelected)
	{
		jscss('remove', searchForm, 'display-none');
		deselectAllDocuments();
		/* we're de-selecting, so no info to parent window */
		return;
	}
	else
	{
		jscss('add', container, 'selected', '');
		jscss('add', searchForm, 'display-none');
	}

	var form = getDocumentSelector( documentid );
	if(!form)
		return;

	var p = new DOMQuery("div.discussion-content").get(0);
	if(!p)
		return;

	p.insertBefore(form, p.childNodes[0]);

	// do we have to notify the document selector opener?
	if(window.opener != null && typeof window.opener.selectedDocument != 'undefined')
	{
		try
		{
			var data = raw_documents[documentid];
			window.opener.selectedDocument(documentid, window);
													/* key    ,doclibid */
			/* window.close();*/
			return;
		}
		catch(e)
		{
			;
		}
	}
};

function copy2rml(e)
{
	e.preventDefault();

	if (typeof window.opener == 'undefined' || !window.opener.document)
		return false;

	// Are we called from a FCKEditor image-selector?
	if(typeof window.opener.SetUrl != 'undefined')	
	{
		window.opener.SetUrl(board_script_url +
				'/../download.php/download_document/' +
				new DOMQuery('input[name="documentid"]', this).get(0).value +
				'/' + new DOMQuery('input[name="key"]', this).get(0).value +
				'/' +
				new DOMQuery('select[name="format"]', this).get(0).value
		);
		window.close();
		return false;
	}

	/* find out which radio button was selected */
	var items = new DOMQuery('input[name="as"]', this), data_as;
	for(var i = 0, item; (item = items.get(i)); i++)
	{
		if(item.type == 'hidden' || item.checked)
		{
			data_as = item;
			break;
		}
	}

	if(!data_as)
		return false;

	var rml = '';
	switch( data_as.value )
	{
		case 'image':
			var float_select = new DOMQuery('select[name="float"]', this);
			var format_select = new DOMQuery('select[name="format"]', this);
			var link_input = new DOMQuery('input[name="link"]', this);

			var link = '0';

			var float = '', format='';

			if (float_select.length > 0)
				float = float_select.get(0).options[ float_select.get(0).selectedIndex ].value;

			if (format_select.length > 0)
				format = format_select.get(0).options[ format_select.get(0).selectedIndex ].value;

			if ( link_input.length > 0)
			{
				link = link_input.get(0).checked ? '1' : '0';
			}

			rml = '[doclib=' +
					new DOMQuery('input[name="documentid"]', this).get(0).value +
					',' +
					new DOMQuery('input[name="key"]', this).get(0).value +
					',' +
					new DOMQuery('input[name="libraryid"]', this).get(0).value +
					',' +
					format +
					',' +
					link +
					(float != "" ? ("," + float) : "" ) +
					']\n';
		break;
		case 'text':
			rml = '[doclib=' +
					new DOMQuery('input[name="documentid"]', this).get(0).value +
					',' +
					new DOMQuery('input[name="key"]', this).get(0).value +
					',' +
					new DOMQuery('input[name="libraryid"]', this).get(0).value +
					',,0]' +
					new DOMQuery('input[name="filename"]', this).get(0).value +
					'[/]\n';
		break;
		default:
			return;
	}
	window.opener.setCurrentTextarea(window);
	window.opener.putStr(rml);
	window.opener.focus();
	window.close();

	return false;
};

/*
	cssQuery, version 2.0 (2005/05/23)
	Copyright: 2004-2005, Dean Edwards (http://dean.edwards.name/)
	License: http://creativecommons.org/licenses/LGPL/2.1/
*/
if(!DOMQuery.hasXPath)
{
	eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1;};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p;}('8 C=6(){8 1H="2.0 (2S)";8 $2B=/\\s*,\\s*/;8 C=6($d,$$b){2T{8 $m=[];8 $1S=c.2Q.2A&&!$$b;8 $1K=($$b)?($$b.2R==2E)?$$b:[$$b]:[X];8 $$E=1o($d).22($2B),i;x(i=0;i<$$E.y;i++){$d=1C($$E[i]);9(16&&$d.S(0,3).2w("")==" *#"){$d=$d.S(2);$$b=26([],$1K,$d[1])}1I $$b=$1K;8 j=0,$U,$F,$c,$1a="";I(j<$d.y){$U=$d[j++];$F=$d[j++];$1a+=$U+$F;$c="";9($d[j]=="("){I($d[j++]!=")")$c+=$d[j];$c=$c.S(0,-1);$1a+="("+$c+")"}$$b=($1S&&19[$1a])?19[$1a]:2u($$b,$U,$F,$c);9($1S)19[$1a]=$$b}$m=$m.2N($$b)}1Y C.1m;7 $m}2P($1m){C.1m=$1m;7[]}};C.2i=6(){7"6 C() {\\n  [1H "+1H+"]\\n}"};8 19={};C.2A=P;C.33=6($d){9($d){$d=1C($d).2w("");1Y 19[$d]}1I 19={}};8 1P={};8 1X=P;C.1s=6($1b,$1q){9(1X)1n("$1q="+1i($1q));1P[$1b]=12 $1q()};C.30=6($Y){7 $Y?1n($Y):z};8 E={};8 v={};8 Z=[];E[" "]=6($l,$b,$q,$p){8 $5,i,j;x(i=0;i<$b.y;i++){8 $1r=1f($b[i],$q,$p);x(j=0;($5=$1r[j]);j++){9(O($5)&&1p($5,$p))$l.D($5)}}};E["#"]=6($l,$b,$H){8 $5,j;x(j=0;($5=$b[j]);j++)9($5.H==$H)$l.D($5)};E["."]=6($l,$b,$17){$17=12 1R("(^|\\\\s)"+$17+"(\\\\s|$)");8 $5,i;x(i=0;($5=$b[i]);i++)9($17.h($5.17))$l.D($5)};E[":"]=6($l,$b,$2y,$c){8 $h=v[$2y],$5,i;9($h)x(i=0;($5=$b[i]);i++)9($h($5,$c))$l.D($5)};v["2X"]=6($5){8 $X=V($5);9($X.1G)x(8 i=0;i<$X.1G.y;i++){9($X.1G[i]==$5)7 R}};v["35"]=6($5){};8 O=6($5){7($5&&$5.1Z==1&&$5.q!="!")?$5:2q};8 1l=6($5){I($5&&($5=$5.32)&&!O($5))2G;7 $5};8 K=6($5){I($5&&($5=$5.2U)&&!O($5))2G;7 $5};8 1L=6($5){7 O($5.2b)||K($5.2b)};8 2L=6($5){7 O($5.29)||1l($5.29)};8 15=6($5){8 $15=[];$5=1L($5);I($5){$15.D($5);$5=K($5)}7 $15};8 16=R;8 2z=6($5){7 V($5).31=="2V 2Y"};8 V=6($5){7 $5.2Z||$5.X};8 1f=6($5,$q){7($q=="*"&&$5.1J)?$5.1J:$5.1f($q)};8 1t=6($5,$q,$p){9($q=="*")7 O($5);9(!1p($5,$p))7 P;7 $5.q.28()==$q.28()};8 1p=6($5,$p){7!$p||($p=="*")||($5.2W==$p)};8 1V=6($5){7 $5.2K};6 26($l,$b,H){8 $m,i,j;x(i=0;i<$b.y;i++){9($m=$b[i].1J.34(H)){9($m.y==2q)$l.D($m);1I x(j=0;j<$m.y;j++)$l.D($m[j])}}7 $l};8 $1F=/\\|/;6 2u($$b,$U,$F,$c){9($1F.h($F)){$F=$F.22($1F);$c=$F[0];$F=$F[1]}8 $l=[];9(E[$U]){E[$U]($l,$$b,$F,$c)}7 $l};8 $2m=/^[^\\s>+~]/;8 $$2h=/[\\s#.:>+~()@]|[^\\s#.:>+~()@]+/g;6 1C($d){9($2m.h($d))$d=" "+$d;7 $d.m($$2h)||[]};8 $2g=/\\s*([\\s>+~(),]|^|$)\\s*/g;8 $2f=/([\\s>+~,]|[^(]\\+|^)([#.:@])/g;8 1o=6($d){7 $d.G($2g,"$1").G($2f,"$1*$2")};8 1Q={2i:6(){7"\'"},m:/^(\'[^\']*\')|("[^"]*")$/,h:6($u){7 z.m.h($u)},25:6($u){7 z.h($u)?$u:z+$u+z},2k:6($u){7 z.h($u)?$u.S(1,-1):$u}};8 1O=6($14){7 1Q.2k($14)};8 $2j=/([\\/()[\\]?{}|*+-])/g;6 10($u){7 $u.G($2j,"\\\\$1")};C.1s("1x-2a",6(){E[">"]=6($l,$b,$q,$p){8 $5,i,j;x(i=0;i<$b.y;i++){8 $1r=15($b[i]);x(j=0;($5=$1r[j]);j++)9(1t($5,$q,$p))$l.D($5)}};E["+"]=6($l,$b,$q,$p){x(8 i=0;i<$b.y;i++){8 $5=K($b[i]);9($5&&1t($5,$q,$p))$l.D($5)}};E["@"]=6($l,$b,$2l){8 $h=Z[$2l].h;8 $5,i;x(i=0;($5=$b[i]);i++)9($h($5))$l.D($5)};v["3s-1e"]=6($5){7!1l($5)};v["1B"]=6($5,$Y){$Y=12 1R("^"+$Y,"i");I($5&&!$5.1j("1B"))$5=$5.24;7 $5&&$Y.h($5.1j("1B"))};8 k={};k.1E="@";k.N={};k.m=/\\[([\\w-]+)\\s*(\\W?=)?\\s*([^\\]]*)\\]/g;k.G=6($m,$t,$2s,$A){8 $1y=k.1E+$m;9(!Z[$1y]){$t=k.2t($t,$2s||"",$A||"");Z[$1y]=$t;Z.D($t)}7 Z[$1y].H};k.2e=6($d){7 $d.G(z.m,z.G)};k.2t=6($1D,$h,$A){8 $1g={};$1g.H=k.1E+Z.y;$1g.1b=$1D;$h=z.N[$h];$h=$h?$h(k.1j($1D),1O($A)):P;$1g.h=12 2r("e","7 "+$h);7 $1g};k.1j=6($1b){1w($1b.3y()){B"H":7"e.H";B"3v":7"e.17";B"x":7"e.3x";B"27":9(16){7"1i((e.3n.m(/27=\\"?([^\\\\s\\"]*)\\"?/)||[])[1]||\'\')"}}7"e.1j(\'"+$1b+"\')"};z.k=k;k.N[""]=6($t){7 $t};k.N["="]=6($t,$A){7 $t+"=="+1Q.25($A)};k.N["~="]=6($t,$A){7"/(^|\\\\s)"+10($A)+"(\\\\s|$)/.h("+$t+")"};k.N["|="]=6($t,$A){7"/^"+10($A)+"(-|$)/.h("+$t+")"};8 2d=1o;1o=6($d){7 2d(k.2e($d))}});C.1s("1x-37",6(){8 1A=1P["1x-2a"];9(!1A)7;E["~"]=6($l,$b,$q,$p){8 $5,i;x(i=0;($5=$b[i]);i++){I($5=K($5)){9(1t($5,$q,$p))$l.D($5)}}};v["38"]=6($5,$14){$14=12 1R(10(1O($14)));7 $14.h(1V($5))};v["3k"]=6($5){7 $5==V($5).2J};v["3j"]=6($5){8 $M,i;x(i=0;($M=$5.2H[i]);i++){9(O($M)||$M.1Z==3)7 P}7 R};v["2v-1e"]=6($5){7!K($5)};v["3m-1e"]=6($5){$5=$5.24;7 1L($5)==2L($5)};v["3l"]=6($5,$d){8 $1N=C($d,V($5));x(8 i=0;i<$1N.y;i++){9($1N[i]==$5)7 P}7 R};v["2x-1e"]=6($5,$c){7 1z($5,$c,1l)};v["2x-2v-1e"]=6($5,$c){7 1z($5,$c,K)};v["3i"]=6($5){7 $5.H==3c.3b.S(1)};v["2F"]=6($5){7 $5.2F};v["3A"]=6($5){7 $5.1M===P};v["1M"]=6($5){7 $5.1M};v["2D"]=6($5){7 $5.2D};8 k=1A.k;k.N["^="]=6($t,$A){7"/^"+10($A)+"/.h("+$t+")"};k.N["$="]=6($t,$A){7"/"+10($A)+"$/.h("+$t+")"};k.N["*="]=6($t,$A){7"/"+10($A)+"/.h("+$t+")"};6 1z($5,$c,$1u){1w($c){B"n":7 R;B"3r":$c="2n";Q;B"3p":$c="2n+1"}8 $$23=15($5.24);6 1T($13){8 $13=($1u==K)?$$23.y-$13:$13-1;7 $$23[$13]==$5};9(!1d($c))7 1T($c);$c=$c.22("n");8 $T=2C($c[0]);8 $L=2C($c[1]);9((1d($T)||$T==1)&&$L==0)7 R;9($T==0&&!1d($L))7 1T($L);9(1d($L))$L=0;8 $1h=1;I($5=$1u($5))$1h++;9(1d($T)||$T==1)7($1u==K)?($1h<=$L):($L>=$1h);7($1h%$T)==$L}});C.1s("1x-3t",6(){16=1n("P;/*@3o@9(@\\3q)16=R@39@*/");9(!16){1f=6($5,$q,$p){7 $p?$5.3h("*",$q):$5.1f($q)};1p=6($5,$p){7!$p||($p=="*")||($5.3f==$p)};2z=X.2I?6($5){7/3g/i.h(V($5).2I)}:6($5){7 V($5).2J.q!="3e"};1V=6($5){7 $5.1k||$5.2K||20($5)};6 20($5){8 $1k="",$M,i;x(i=0;($M=$5.2H[i]);i++){1w($M.1Z){B 11:B 1:$1k+=20($M);Q;B 3:$1k+=$M.36;Q}}7 $1k}}});12 6(){8 $$18=6($6,$2c,$c){$6.18($2c,$c)};9(\'\'.G(/^/,1i)){8 2o=1i.1U.G;8 2p=6($1v,$1c){8 $m,$1W="",$u=z;I($u&&($m=$1v.3d($u))){$1W+=$u.S(0,$m.13)+$$18($1c,z,$m);$u=$u.S($m.3a)}7 $1W+$u};1i.1U.G=6($1v,$1c){z.G=(3w $1c=="6")?2p:2o;7 z.G($1v,$1c)}}9(!2r.18){8 J="18-"+3z(12 3u);$$18=6(f,o,a){8 r;o[J]=f;1w(a.y){B 0:r=o[J]();Q;B 1:r=o[J](a[0]);Q;B 2:r=o[J](a[0],a[1]);Q;B 3:r=o[J](a[0],a[1],a[2]);Q;B 4:r=o[J](a[0],a[1],a[2],a[3]);Q;2M:8 21=[],i=a.y-1;2O 21[i]="a["+i+"]";I(i--);1n("r=o[J]("+21+")")}1Y o[J];7 r}}9(![].D)2E.1U.D=6(){x(8 i=0;i<c.y;i++){z[z.y]=c[i]}7 z.y}};1X=R;7 C}();',62,223,'|||||element|function|return|var|if||from|arguments|selector||||test|||AttributeSelector|results|match|||namespace|tagName|||attribute|string|pseudoClasses||for|length|this|value|case|cssQuery|push|selectors|filter|replace|id|while|APPLY|nextElementSibling|step|node|tests|thisElement|false|break|true|slice|multiplier|token|getDocument||document|code|attributeSelectors|regEscape||new|index|text|childElements|isMSIE|className|apply|cache|cacheSelector|name|replacement|isNaN|child|getElementsByTagName|attributeSelector|count|String|getAttribute|textContent|previousElementSibling|error|eval|parseSelector|compareNamespace|script|subset|addModule|compareTagName|traverse|expression|switch|css|key|nthChild|css2|lang|_toStream|propertyName|PREFIX|NAMESPACE|links|version|else|all|base|firstElementChild|disabled|negated|getText|modules|Quote|RegExp|useCache|_checkIndex|prototype|getTextContent|newString|loaded|delete|nodeType|_getTextContent|aa|split|children|parentNode|add|_msie_selectById|href|toUpperCase|lastChild|level2|firstChild|object|_parseSelector|parse|IMPLIED_ALL|WHITESPACE|STREAM|toString|ESCAPE|remove|attributeSelectorID|STANDARD_SELECT||_stringReplace|_functionReplace|null|Function|compare|create|select|last|join|nth|pseudoClass|isXML|caching|COMMA|parseInt|indeterminate|Array|checked|continue|childNodes|contentType|documentElement|innerText|lastElementChild|default|concat|do|catch|callee|constructor|beta|try|nextSibling|XML|scopeName|link|Document|ownerDocument|valueOf|mimeType|previousSibling|clearCache|item|visited|nodeValue|level3|contains|end|lastIndex|hash|location|exec|HTML|prefix|xml|getElementsByTagNameNS|target|empty|root|not|only|outerHTML|cc_on|odd|x5fwin32|even|first|standard|Date|class|typeof|htmlFor|toLowerCase|Number|enabled'.split('|'),0,{}));
}
var calendar_event_types = Array("calendarevent","calendareventallday","topicstart","topicevent","birthday");
var calendar_eventlist_close_event, calendar_eventlist_show_event, calendar_eventlist_show_ob;

/* Create an iframe with the minicalendar in it */
function minicalendarCreate()
{
	if(!show_mini_calendar)
		return;

	if(arguments.callee.initialRun)
		return;

	/* don't show the calendar on result pages; by the time it's loaded, the page refreshes */
	var metaRefresh = new DOMQuery('meta[http-equiv="refresh"]');
	if(metaRefresh.length > 0)
		return false;

	var iframe = createDOMNode('iframe', {"id" : 'top-calendar', "frameBorder" : 0, scrolling: 'no', "hideFocus" : true, "src" : board_script_url + '/list_calendar/mini/0/0/5', "allowTransparency" : true }, []);

	document.body.appendChild(iframe);
	arguments.callee.initialRun = true;
};

function WksInYr(Y)
{
    return 52 + ((new Date(Y, 0, 1)).getDay() == 4 ||
        (new Date(Y, 11, 31)).getDay() == 4);
};

/* Setup the minicalendar */
function minicalendarSetup()
{
	/* Make sure we are not in the full calendar */
	if (document.location.pathname.indexOf('list_calendar/mini') == -1)
		return false;

	if(arguments.callee.initialRun)
		return;

	var calendar_table = new DOMQuery('table#calendar').get(0);
	if(!calendar_table)
		return;

	/* Jump to today, or the first day on the calendar */
	var cell_today = new DOMQuery('td.today', calendar_table), items, tbodyCells;
	if (cell_today.length > 0)
	{
		minicalendarShowEventlist(cell_today.get(0));
	}
	else
	{
		tbodyCells = new DOMQuery('tbody td', calendar_table);
		minicalendarShowEventlist(tbodyCells.get(0));
	}

	/* add (double)click event to all minicalendar TDs */
	/* recycle previous lookup */
	if(typeof tbodyCells != 'undefined')
		items = tbodyCells;
	else
		items = new DOMQuery('tbody td', calendar_table);

	for (var i = 0, item; (item=items.get(i)); i++)
	{
		addEvent(item, 'focus', function(e){ this.blur(); } );
		addEvent(item, 'click', function(e){ minicalendarShowEventlist(this); e.preventDefault(); } );
		addEvent(item, 'dblclick', function(e){ parent.location.href = this.firstChild.href ? this.firstChild.href : this.childNodes[1].href; e.preventDefault(); } );
	}

	/* When mousing over the eventlist; enlarge it */
	if(parent != self)
	{
		var calendar_eventlist = document.getElementById('mini-calendar-eventlist');
		addEvent(calendar_eventlist, 'mouseover', function() { calendarEventlistEnlarge('over'); });
		addEvent(calendar_eventlist, 'mouseout', function() { calendarEventlistEnlarge('out'); });
	}

	/* Add links to next and previous month */
	var targetcell = calendar_table.tHead.rows[0].cells[0];
	targetcell.removeChild(targetcell.firstChild);

	var currentWeekLink = new DOMQuery('table#calendar tbody tr:first-child th a').get(0);

	if(currentWeekLink)
	{
		var matches = currentWeekLink.href.match(/(.*)week\/([0-9]+)\/([0-9]+)/, 'mini/$1/$2/5');

		var currentWeekNumber = parseInt(matches[3]);
		var currentWeekNumberYear = parseInt(matches[2]);

		previousSequenceStartWeek = currentWeekNumber - 5;
		previousSequenceYear = currentWeekNumberYear;

		if(previousSequenceStartWeek <= 0)
		{
			previousSequenceYear -= 1;
			previousSequenceStartWeek += WksInYr(previousSequenceYear);
		}

		targetcell.appendChild( createDOMNode('a', {"href" : matches[1] + 'mini/' + previousSequenceYear + '/' + previousSequenceStartWeek + '/5' }, ['<']) );

		nextSequenceStartWeek = currentWeekNumber + 5;
		nextSequenceYear = currentWeekNumberYear;

		if(nextSequenceStartWeek > WksInYr(nextSequenceYear))
		{
			nextSequenceStartWeek -= WksInYr(nextSequenceYear);
			nextSequenceYear += 1;
		}

		targetcell.appendChild( createDOMNode('a', {"href" : matches[1] + 'mini/' + nextSequenceYear + '/' + nextSequenceStartWeek + '/5' }, ['>']) );
	}

	/* Reroute weeknumber-column clicks to the parent frame */
	var weeknumber_columns = new DOMQuery('tbody th', calendar_table);
	for (i = 0; (item=weeknumber_columns.get(i)); i++)
	{
		addEvent(item, 'click', function(e) { parent.location.href = this.firstChild.href; e.preventDefault(); } );
	}

	miniCalendarResizeToFullHeight();

	arguments.callee.initialRun = true;
};

function miniCalendarResizeToFullHeight()
{
	var iframe = parent.document.getElementById('top-calendar');

	if(!iframe)
		return;

	var iframeHeight = window.getComputedStyle ? window.getComputedStyle(iframe,'').getPropertyValue('height') : iframe.currentStyle.getAttribute('height');

	if(!arguments.callee.initialRun && (iframeHeight == 'auto' || iframeHeight == '100%'))
	{
		iframe.resizeToFullHeight = true;
	}

	if (iframe.resizeToFullHeight)
	{
		if(!isNaN(parseInt(iframeHeight)))
			var newHeight = Math.max(document.body.scrollHeight, parseInt(iframeHeight));
		else
			var newHeight = document.body.scrollHeight;

		iframe.style.height = newHeight + 'px';
	}

	arguments.callee.initialRun = true;
};

/* When a calender-day-td is clicked; this function will show the events for that day */
function minicalendarShowEventlist(ob)
{
	var calendar_eventlist = document.getElementById('mini-calendar-eventlist');
	var calendar_table = document.getElementById('calendar');
	var child, header, events, list, insertlink, j, item, eventList = [];

	if (!calendar_eventlist)
		return false;

	/* Kill children */
	while (child = calendar_eventlist.firstChild)
		calendar_eventlist.removeChild(child);

	var items = new DOMQuery('td.selected', getSiblingNode(ob, 'up', 'tbody'));
	for(i=0;(item=items.get(i)); i++)
	{
		jscss('remove', item, 'selected', '');
	}

	jscss('add', ob, 'selected', '');

	if(typeof miniCalendarEventlistLength == 'undefined')
	{
		miniCalendarEventlistLength = 1;
	}

	for (var numberOfDaysShown = 0; numberOfDaysShown < miniCalendarEventlistLength; numberOfDaysShown++)
	{
		/* Display addevent link */

		insertlink = createDOMNode('span', {},
		[
			createDOMNode('a', {"href" : board_script_url + '/insert_calendarevent/' + ob.id.replace(/day-(\d+)-(\d+)-(\d+)$/, '$3-$2-$1'), "event" : ['click', function(){ parent.location.href = this.href; return false;}]}, ['+'])
		]);

		calendar_eventlist.appendChild(insertlink);

		/* Display current date */
		header = createDOMNode('h2', {}, [
			createDOMNode('a', {"href" : board_script_url + '/list_calendar/day/' + ob.id.replace(/day-(\d+)-(\d+)-(\d+)$/, '$2/$3/$1'), "event" : ['click', function(){ parent.location.href = this.href; return false;}]}, [ob.firstChild.title])
		]);
		calendar_eventlist.appendChild(header);

		/* Display events by type */
		for (var i = 0; (item = calendar_event_types[i]); i++)
		{
			event_type = item;
			eventList = [];

			events = new DOMQuery('ol.event-type-' + event_type + ' > li', ob);

			if (events.length > 0)
			{
				header = createDOMNode('h3', {}, [getText('calendar', event_type)]);
				calendar_eventlist.appendChild(header);

				for (j = 0; j<events.length; j++)
				{
					item = events.get(j).cloneNode(true);
					addEvent(item, 'click', function(e) { var link = new DOMQuery('a.primary', this); if(link.length > 0) { parent.location.href = link.get(0).href; e.preventDefault(); } } );

					eventList[eventList.length] = item;
				}

				list = createDOMNode('ul', {"id" : 'mini-events-' + event_type}, eventList);

				calendar_eventlist.appendChild(list);
			}
		}

		// search next working day
		do
		{
			if(ob.nextSibling)
				ob = ob.nextSibling;
			else if (ob.parentNode.nextSibling)
				ob = ob.parentNode.nextSibling.childNodes[1];
			else
				break;
		}
		while(ob.cellIndex > 5);
	}

	miniCalendarResizeToFullHeight();

	return false;
};


function calendarEventlistEnlarge(type)
{
	if (isIE)
		return false;

	var calendar_eventlist = document.getElementById('mini-calendar-eventlist');
	var calendar_iframe = parent.document.getElementById('top-calendar');
	var events = new DOMQuery('li', calendar_eventlist);

	if (type == 'over')
	{
		if (typeof calendar_close_event != 'undefined')
			clearTimeout(calendar_close_event);

		jscss('add', calendar_eventlist, 'hover', '');

		for(var	i=0, item; (item=events.get(i)); i++)
		{
			jscss('add', item, 'hover', '');
		}

		var has_scrollbar = (calendar_eventlist.scrollHeight > calendar_eventlist.clientHeight);

		if(has_scrollbar)
		{
			jscss('add', calendar_iframe, 'hover', '');
			jscss('add', calendar_eventlist, 'expand', '');
		}
	}
	else if (type == 'out')
	{
		calendar_close_event = setTimeout(
			function ()
			{
				jscss('remove',calendar_iframe,'hover','');
				jscss('remove',calendar_eventlist,'hover','');
				jscss('remove',calendar_eventlist,'expand','');
				for(var	i=0, item; (item=events.get(i)); i++)
				{
					jscss('remove', item, 'hover', '');
				}
			}
			, 100);
	}
};
var calenderRepeatDetails = Array();
var calendarRepeat;

function toggleRepeatDetails()
{
	calendarRepeat = new DOMQuery('input#calendar_repeatcheck');

	if(calendarRepeat.length == 0)
	{
		calendarRepeat = null;
		return;
	}

	calendarRepeat = calendarRepeat.get(0);

	addEventToTargets(null, 'change', _toggleRepeatDetails, 'input#calendar_repeatcheck, select#calendar_repeatselect');
	addClassToTargets('dt.calendar-repeat-details, dd.calendar-repeat-details', 'display-none');

	if(calendarRepeat.checked)
	{
		_toggleRepeatDetails();

		if(!isIE && window.location.hash != '#showAdvancedOptions')
			toggleAdvancedOptions();
	}
};

function _toggleRepeatDetails()
{
	var calendarRepeatDetails = new DOMQuery('dt.calendar-repeat-details, dd.calendar-repeat-details');

	for (var i = 0; i < calendarRepeatDetails.length; i++)
	{
		var item = calendarRepeatDetails.get(i);

		if(calendarRepeat.checked)
			jscss('remove',item,'display-none', '');
		else
			jscss('add',item,'display-none', '');
	}

	var frequency = new DOMQuery('select#calendar_repeatselect');

	if(frequency.length > 0)
	{
		frequency = frequency.get(0).options[frequency.get(0).selectedIndex].value;
		var items = new DOMQuery('dt.calendar-repeat-weekly, dd.calendar-repeat-weekly');
		for(i=0, item; (item=items.get(i)); i++)
		{
			jscss('add',item,'display-none', '');

			switch(frequency)
			{
				case 'week':
					if(calendarRepeat.checked)
						jscss('remove',item,'display-none', '');
				break;
			}
		}
	}
};

function easyTimeInputConverter()
{
	addEventToTargets('input#calendar_startdate_time, input#calendar_enddate_time',	'change', _easyTimeInputConverter);

	addEventToTargets('input#calendar_startdate, input#calendar_enddate, input#calendar_startdate_time, input#calendar_enddate_time', 'blur', _ensureCorrectDateRange);
};

function _easyTimeInputConverter()
{
	if(this.value.indexOf(':') > 0)
		return;

	var newValue = this.value;

	switch(newValue.length)
	{
		case 1:				/* '9' => 9h => 09:00		*/
			newValue = '0' + this.value + ':00';
		break;
		case 2:				/* '21' => 21h => 21:00		*/
			newValue = this.value + ':00';
		break;
		case 3:				/* '914' => 914h => 09:14	*/
			newValue = '0'+ this.value.substr(0,1) + ':' + this.value.substr(1,2);
		break;
		case 4:				/* '2125' => 2125h => 21:25	*/
			newValue = this.value.substr(0,2) + ':' + this.value.substr(2,3);
		break;
	}
	this.value = newValue;
};

function _ensureCorrectDateRange()
{
	var startDate = new DOMQuery('input#calendar_startdate').get(0);
	var startTime = new DOMQuery('input#calendar_startdate_time').get(0);
	var endDate = new DOMQuery('input#calendar_enddate').get(0);
	var endTime = new DOMQuery('input#calendar_enddate_time').get(0);

	var datePattern = /0?(\d{1,2})\D0?(\d{1,2})\D(\d{4})/, m;
	var timePattern = /0?([0-9]{1,2}):0?([0-9]{1,2})/, m;

	var startDateMatches = startDate.value.match( datePattern );
	var startTimeMatches = startTime.value.match( timePattern );
	var startDateObject = new Date(
		parseInt(startDateMatches[3]),  // year
		parseInt(startDateMatches[2]) - 1, // month
		parseInt(startDateMatches[1]), // day
		parseInt(startTimeMatches[1]), // hour
		parseInt(startTimeMatches[2]), // minute
		0, // seconds
		0 // milliseconds
	);

	var endDateMatches = endDate.value.match( datePattern );
	var endTimeMatches = endTime.value.match( timePattern );
	var endDateObject = new Date(
		parseInt(endDateMatches[3]),  // year
		parseInt(endDateMatches[2]) - 1, // month
		parseInt(endDateMatches[1]), // day
		parseInt(endTimeMatches[1]), // hour
		parseInt(endTimeMatches[2]), // minute
		0, // seconds
		0 // milliseconds
	);

	if(endDateObject >= startDateObject)
		return;

	switch(this.id)
	{
		case 'calendar_startdate':
		case 'calendar_startdate_time':
			endDate.value = startDate.value;
			endTime.value = startTime.value;
		break;
		case 'calendar_enddate':
		case 'calendar_enddate_time':
			startDate.value = endDate.value;
			startTime.value = endTime.value;
		break;
	}
};

var texts = new Array()

texts['doclib'] = new Array();
texts['doclib']['insert_as'] = 'Invoegen als'
texts['doclib']['insert_as_image'] = 'afbeelding'
texts['doclib']['insert_as_text'] = 'tekst'
texts['doclib']['insert_as_link'] = 'Link'
texts['doclib']['insert_as_thumb'] = 'Link thumbnail naar origineel'
texts['doclib']['format'] = 'Format'
texts['doclib']['original'] = 'Origineel'
texts['doclib']['outline'] = 'Positie'
texts['doclib']['none'] = 'Geen'
texts['doclib']['left'] = 'Links'
texts['doclib']['right'] = 'Rechts'
texts['doclib']['insert'] = 'Invoegen'
texts['doclib']['insert_image'] = 'Afbeeldingen invoegen'
texts['doclib']['not_implemented'] = 'Nog niet toegepast'

texts['forms'] = new Array();
texts['forms']['marked_fields'] = 'Velden gemarkeerd met een '
texts['forms']['required'] = ' zijn verplicht'
texts['forms']['hide_advanced'] = 'Verberg extra opties'
texts['forms']['show_advanced'] = 'Toon extra opties'
texts['forms']['max_chars'] = 'U kunt hier tot %1$s tekens gebruiken'
texts['forms']['name_too_short'] = 'De gebruikersnaam is te kort'
texts['forms']['email_incorrect'] = 'Het emailadres is onjuist'
texts['forms']['url_incorrect'] = 'De URL is onjuist'
texts['forms']['numeric_only'] = 'Dit veld kan alleen nummers bevatten'
texts['forms']['required_field'] = 'Dit veld is verplicht'
texts['forms']['password_no_match'] = 'De wachtwoorden komen niet overeen'
texts['forms']['username_taken'] = 'Deze gebruikersnaam is al in gebruik'
texts['forms']['invalid_domain'] = 'Email adressen van deze domein zijn niet toegestaan.'
texts['forms']['email_taken'] = 'Dit email adres is al in gebruik.'
texts['forms']['select_all_rows'] = 'selecteer alle rijen'
texts['forms']['select_messages'] = 'Click op een of meer berichten om deze te selecteren'
texts['forms']['username'] = 'Gebruikersnaam'
texts['forms']['password'] = 'Wachtwoord'
texts['forms']['sofinummer_mismatch'] = 'Dit getal komt nite door de 11-cijfer test, ongeldig sofinummer'
texts['forms']['length_not_9'] = 'Dit veld moet precies 9 cijfers bevatten'

texts['imagewizard'] = new Array();
texts['imagewizard']['sizes_error'] = 'Fout :: originele afmetingen van bronbestand niet gevonden'

texts['normal'] = new Array();
texts['normal']['disabled_option'] = 'Deze optie is niet toegestaan'

texts['xmlhttp'] = new Array();
texts['xmlhttp']['close'] = 'Sluit'

texts['extra'] = new Array();
texts['extra']['searchPopup'] = 'Zoek...'
texts['extra']['close_and_submit'] = 'Sluit en bevestig'
texts['extra']['accesskey_indicator'] = '(%1$s)'

texts['j_toolbar'] = new Array();
texts['j_toolbar']['enter_color'] = 'Voer Hex kleur in'
texts['j_toolbar']['enter_img_url'] = 'Voer afbeelding URL in'
texts['j_toolbar']['enter_url'] = 'Voer URL: in'
texts['j_toolbar']['enter_title'] = 'Voer titel optie in'

texts['calendar'] = new Array();
texts['calendar']['calendarevent'] = 'Afspraken'
texts['calendar']['calendareventallday'] = 'Events voor een hele dag'
texts['calendar']['topicstart'] = 'Topicbegint'
texts['calendar']['topicevent'] = 'Topics'
texts['calendar']['birthday'] = 'Verjaardagen'

