var JSNULL = 'javascript:;';
var timerObj;

function getDiv(id,sClass,cont,close)
{
	var s = '<div' + (id ? ' id="' + id + '"' : '') + (sClass ? ' class="' + sClass + '"' : '') + '>';
	s += cont;
	if(close)
	{
		s += '</div>';
	}
	return s;
}

function getSelect(options,id,sClass,chFunc,selected)
{
	var s = '<select' + (id ? ' id="' + id + '"' : '') + (sClass ? ' class="' + sClass + '"' : '') + (chFunc ? ' onchange="' + chFunc + '"' : '') + '>';
	for(var i = 0; i < options.length; i++)
	{
		s += '<option value="' + options[i][1] +  '"' + (selected == i ? ' selected="1"' : '') + '>' + options[i][0] + '</option>';
	}
	s += '</select>';
	return s;
}

function retryFlashText(flid,name)
{
	var fl = getFlashMovie(flid);
	if(fl.setText)
	{
		fl.setText(name);
	}
	else
	{
		setTimeout("retryFlashText('" + flid + "','" + name + "');",500);
	}
}

var listsOnPage = {};
function addList(id,fillOnLoad)
{
	if(listsOnPage[id])
	{
		alert('list already exists');
	}
	listsOnPage[id] = {onload: fillOnLoad};
}

var tabsOnPage = {};
function addTab(id,groupId)
{
	if(!tabsOnPage[groupId])
	{
		tabsOnPage[groupId] = [];
	}
	tabsOnPage[groupId].push(id);
}

function getCookie(n)
{
	if (document.cookie.length > 0)
	{
		var pos = document.cookie.indexOf(n + "=");
		if (pos != -1)
		{
			pos = pos + n.length + 1;
			var endpos = document.cookie.indexOf(";",pos);
			if (endpos == -1) { endpos = document.cookie.length; }
			return unescape(document.cookie.substring(pos,endpos));
		}
	}
	return "";
}

function setCookie(n,v)
{
	var exdate = new Date();
	exdate.setTime(exdate.getTime() + (1000 * 60 * 60 * 2));
	document.cookie = n + "=" + escape(v) + "; expires=" + exdate.toUTCString() + '; path=/';
}

function doOnLoad()
{
	for(var k in listsOnPage)
	{
		if(listsOnPage[k].onload)
		{
			showPreviousListEntries(k);
		}
	}
	
	flashGetInstalledVersion();
	
	if(flashInstalledVersion < 10 && getCookie('nc2_flashcheck') == '')
	{
		setCookie('nc2_flashcheck','1');
	    var d = createTag('div','overlay');
	    var el = document.getElementById('container');
	    el.parentNode.appendChild(d);
	    
	    d = createTag('div','flashPopup');
	    d.innerHTML = '<b>Flash versie mogelijk verouderd</b><br/><br/>Mogelijk is de versie van uw geinstalleerde Flash-player verouderd. Neurocampus werkt optimaal met Flash-player versie 10.<br/><br/>Download de nieuwste versie via <a href="http://www.adobe.com/go/getflash">www.adobe.com/go/getflash</a>.<br/><br/>Wanneer u geen hogere flash versie installeert, is het mogelijk dat niet alle oefeningen optimaal werken.<br/><a href="javascript:;" onclick="closeFlashPopup();" id="closeFlashPopup">Sluiten</a>';
	    
	    el.parentNode.appendChild(d);
	    
	    d.style.left = el.offsetLeft + Math.floor((el.offsetWidth - d.offsetWidth) / 2) + 'px';
		d.style.top = el.offsetTop + 150 + 'px';
	}
}

function closeFlashPopup()
{
	var el = document.getElementById('overlay');
	el.parentNode.removeChild(el);
	el = document.getElementById('flashPopup');
	el.parentNode.removeChild(el);
}

function multiReplace(replaceVars,replaceWith,subject)
{
	var onevalue = replaceWith.length == 1;
	for(var i = 0; i < replaceVars.length; i++)
	{
		subject = subject.split(replaceVars[i]).join(replaceWith[onevalue ? 0 : i]);
	}
	return subject;
}

var flashInstalledCheck = false;
var flashInstalledVersion = 0;
function flashGetInstalledVersion()
{
	if(flashInstalledCheck)
	{
		return;
	}
	
	var maxversion = 0;
	var flash = null;
	if(window.ActiveXObject)
	{
		for(var i = 6; i <= 10; i++)
		{
			try
			{
				flash = new ActiveXObject(("ShockwaveFlash.ShockwaveFlash." + i));
				maxversion = i;
			}
			catch(e)
			{
				
			}
		}
	}
	else if(navigator.plugins && navigator.mimeTypes.length > 0)
	{
		flash = navigator.plugins["Shockwave Flash"];
		if(flash)
		{
			maxversion = navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/, "$1");
		}
	}
	
	flashInstalledCheck = true;
	flashInstalledVersion = Number(maxversion);
}


function flashReplace(id,swf,w,h,params,flashvars,version)
{
	flashGetInstalledVersion();
	var el = document.getElementById(id);
	if(version = null)
	{
		version = 9;
	}
	
	if(el && flashInstalledVersion >= version)
	{
		var fvstr = "";
		for(var i in flashvars)
		{
			fvstr += (fvstr == '' ? '?' : '') + i + '=' + flashvars[i] + '&';
		}
		if(fvstr != '')
		{
			fvstr = fvstr.substr(0,fvstr.length - 1);
		}
		
		var obj = '<object' + (window.ActiveXObject ? ' id="' + id + '_flash" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" data="' + swf + fvstr + '"' : '');
			obj += ' width="' + w + '"';
			obj += ' height="' + h + '"';
			obj += '>';
			var param = '<param';
			param += ' name="movie"';
			param += ' value="' + swf + fvstr + '"';
			param += '>';

			var extraParams = '';
			var extraAttributes = '';
			for(var i in params)
			{
				extraParams += '<param name="' + i + '" value="' + params[i] + '">';
				extraAttributes += ' ' + i + '="' + params[i] + '"';
			}
			var embed = '<embed id="' + id + '_flash" src="' + swf + fvstr + '" type="application/x-shockwave-flash" width="' + w + '" height="' + h + '"';
			var embedEnd = extraAttributes + '></embed>';
			var objEnd = '</object>';
			el.innerHTML = obj + param + extraParams + embed + embedEnd + objEnd;
	}
}

function getClassDiv(el,name)
{
	for(var i = 0; i < el.childNodes.length; i++)
	{
		if(el.childNodes[i].className == name)
		{
			return el.childNodes[i];
		}
	}
	
	return null;
}

function getFlashMovie(movieName)
{
	if (window.document[movieName])
	{
		return window.document[movieName];
	}
	if (navigator.appName.indexOf("Microsoft Internet") == -1)
	{
		if (document.embeds && document.embeds[movieName])
		{
			return document.embeds[movieName];
		}
	}
	else
	{
		return document.getElementById(movieName);
	}
}

function createTag(tag,id,className)
{
	var el = document.createElement(tag);
	if(id && id != "")
	{
		el.setAttribute('id',id);
	}
	if(className && className != "")
	{
		el.setAttribute('class',className);
	}
	return el;
}

function getAttribute(xml,name)
{
	for(var i = 0; i < xml.attributes.length; i++)
	{
		if(xml.attributes[i].nodeName == name)
		{
			return xml.attributes[i];
		}
	}
	return null;
}

function getAttributeValue(xml,name)
{
	var node = getAttribute(xml,name);
	return (node == null || node.firstChild == null) ? "" : node.firstChild.nodeValue;
}

function getXmlNode(xml,name)
{
	for(var i = 0; i < xml.childNodes.length; i++)
	{
		if(xml.childNodes[i].nodeName == name)
		{
			return xml.childNodes[i];
		}
	}
	return null;
}

function getXmlNodeValue(xml,name)
{
	var node = getXmlNode(xml,name);
	return (node == null || node.firstChild == null) ? "" : node.firstChild.nodeValue;
}

function receiveXml()
{
	if (this.readyState == 4)
	{
		if (this.status == 200)
		{
			var root = null;
			for(var i = 0; i < this.responseXML.childNodes.length; i++)
			{
				if(this.responseXML.childNodes[i].nodeName == "root")
				{
					root = this.responseXML.childNodes[i];
					break;
				}
			}
			
			var func = null;
			for (var i = 0; i < xmlhttps.length; i++)
			{
				if(xmlhttps[i].xmlhttp == this)
				{
					func = xmlhttps[i].func;
					xmlhttps.splice(i,1);
					break;
				}
			}
			if(root && func)
			{
				func(root);
			}
		}
	}
}

function RequestObject(func)
{
	this.xmlhttp = getXmlHttp2();
	this.doneFunc = func;
	
	var _this = this;
	
	this.xmlhttp.onreadystatechange = function() { _this.receiveXml(); }
	
}

RequestObject.prototype.receiveXml = function()
{

	if (this.xmlhttp.readyState == 4)
	{
		if (this.xmlhttp.status == 200)
		{
			var root = null;
			for(var i = 0; i < this.xmlhttp.responseXML.childNodes.length; i++)
			{
				if(this.xmlhttp.responseXML.childNodes[i].nodeName == "root")
				{
					root = this.xmlhttp.responseXML.childNodes[i];
					break;
				}
			}

			if(root && this.doneFunc)
			{
				this.doneFunc(root);
			}
		}
	}
}

var xmlhttps = [];

function getXmlHttp()
{
	var xmlhttp;
	if (window.XMLHttpRequest)
	{
		xmlhttp = new XMLHttpRequest();
	}
	else if (window.ActiveXObject)
	{
		try
		{
			xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e)
		{
			try
			{
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch (e) {}
		}
	}
	xmlhttp.onreadystatechange = receiveXml;
	return xmlhttp;
}

function getXmlHttp2()
{
	var xmlhttp;
	if (window.XMLHttpRequest)
	{
		xmlhttp = new XMLHttpRequest();
	}
	else if (window.ActiveXObject)
	{
		try
		{
			xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e)
		{
			try
			{
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch (e) {}
		}
	}

	return xmlhttp;
}

function submitData(data,url,f)
{
	var req = new RequestObject(f);
	
	var params = "";
	for(var k in data)
	{
		params += k + '=' + encodeURIComponent(data[k]) + '&';
	}
	if(params.length > 0)
	{
		params = params.substr(0,params.length - 1);
	}
	
	req.xmlhttp.open("POST",url,true);
	req.xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	
	req.xmlhttp.send(params);
}

function submitData2(data,url,f)
{
	var req = new RequestObject(f);
	
	var params = "";
	for(var k in data)
	{
		params += k + '=' + encodeURIComponent(data[k]) + '&';
	}
	if(params.length > 0)
	{
		params = params.substr(0,params.length - 1);
	}
	
	req.xmlhttp.open("POST",url,true);
	req.xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	//obj.xmlhttp.setRequestHeader("Content-length", params.length);
	//obj.xmlhttp.setRequestHeader("Connection", "close");
	
	req.xmlhttp.send(params);
}

function getLink(href,name,sId,sClass,target,onclick)
{
	var s = '<a href="' + href + '"';
	var ar = {id:sId, target: target, onclick:onclick};
	ar["class"] = sClass;
	for(var k in ar)
	{
		s += (ar[k] != null ? ' ' + k + '="' + ar[k] + '"' : "");
	}
	s += '>' + name + '</a>';
	return s;
}

function getImage(src,sId,sClass,width,height,nopath)
{
	if(!nopath) { src = 'img/' + src; }
	var s = '<img src="' + src + '"';
	var ar = {id:sId, width: width, height:height};
	ar["class"] = sClass;
	for(var k in ar)
	{
		if(ar[k] != 0 && ar[k] != '')
		{
			s += (ar[k] != null ? ' ' + k + '="' + ar[k] + '"' : "");
		}
	}
	s += '/>';
	return s; 
}

function showDialog(content,sId,sClass,okAction, cancelAction)
{
	var d = createTag('div','overlay');
	var el = document.getElementById('container');
	el.parentNode.appendChild(d);
	
	d = createTag('div',sId,sClass ? sClass : 'dialogWindow');
	d.innerHTML = content + getLink(JSNULL,getImage('okbut.png'),'','dialogOk','',okAction) + getLink(JSNULL,getImage('cancelbut.png'),'','dialogCancel','',cancelAction ? cancelAction : 'closeDialog();');
	
	el.parentNode.appendChild(d);
	
	d.style.left = el.offsetLeft + Math.floor((el.offsetWidth - d.offsetWidth) / 2) + 'px';
	d.style.top = el.offsetTop + 30 + 'px';
	
	var ar = d.getElementsByTagName('input');
	if(ar.length > 0)
	{
		ar[0].focus();
	}
}

function closeDialog()
{
	var el = document.getElementById('container');
	el = getClassDiv(el.parentNode,'dialogWindow');
	el.parentNode.removeChild(el);
	
	el = document.getElementById('overlay');
	el.parentNode.removeChild(el);
}

function newDatasetDialog()
{
	var cont = '<div class="cmsListHeading">Nieuwe dataset koppelen</div>';
	cont += getLink(JSNULL,'Nieuw','newDatasetNewTabBut','tabLinkSelected','','activateTab(\'newDatasetNewTab\');');
	cont += getLink(JSNULL,'Bestaande','newDatasetExistingTabBut','tabLink','','activateTab(\'newDatasetExistingTab\');');
	cont += '<div style="clear: both;"></div>';
	cont += '<div id="newDatasetNewTab" class="navTab" style="display: block;">Naam: <input type="text" class="textBox" id="newDatasetName"/></div>';
	cont += '<div id="newDatasetExistingTab" class="navTab" style="display: none;"></div>';
	
	addTab("newDatasetNewTab","dialogTabs");
	addTab("newDatasetExistingTab","dialogTabs");
	
	showDialog(cont,'',null,'addNewDataset();');
}

function addNewDataset()
{
	var n = document.getElementById('newDatasetName').value;
	var obj = {cmd:'newdataset',name:n};
	obj.pid = listSelections['exercises'];
	submitData(obj,'process.php',dataProcessed);
	
	closeDialog();
}

function newDialog(title,okFunc)
{
	var cont = '<div class="cmsListHeading">' + title + '</div>';
	cont += '<input type="text" id="newItemName"/><br/>';
	showDialog(cont,'',null,okFunc);
}

function getBoxTypes()
{
	var ar = [];
	ar.push(['Tekst/plaatje',1]);
	ar.push(['Media',2]);
	ar.push(['Flash',3]);
	ar.push(['HTML',4]);
	ar.push(['PHP',5]);
	return ar;
}

function newBoxDialog()
{
	var cont = getDiv('','cmsListHeading','Nieuwe box toevoegen',true);
	
	cont += '<table border="0" cellspacing="1" cellpadding="1">';
	cont += '<tr><td>Naam:</td><td><input class="textBox" type="text" id="newBoxName"/></td></tr>';
	cont += '<tr><td>Wide:</td><td><input class="checkBox" type="checkbox" id="newBoxWide"/></td></tr>';
	//cont += '<tr><td>Type:</td><td>' + getSelect(getBoxTypes(),'newBoxType') + '</td></tr>';
	cont += '</table>';
	
	showDialog(cont,'',null,"addNew('newbox');");
}

function addNew(id)
{
	var n = document.getElementById('newItemName').value;
	var obj = {cmd:id,name:n};
	switch(id)
	{
		case 'newbox':
			obj.wide = document.getElementById('newBoxWide').checked ? '1' : '0';
			obj.pid = listSelections['pages'];
		break;
		case 'newex':
			obj.pid = listSelections['categories'];
		break;
	}
	submitData(obj,'process.php',dataProcessed);
	
	closeDialog();
}

var currentBoxType = 0;
var propertiesData = {};
function dataProcessed(xml)
{
	var t = getXmlNodeValue(xml,'cmd');
	switch(t)
	{
		case 'viewimg':
			var cnt = "";
			cnt += '<div class="cmsListHeading">' + getXmlNodeValue(xml,'name') + '</div>';
			cnt += getImage('../uploads/' + getXmlNodeValue(xml,'filename'),'','',0,0,true);
			cnt += '<br/>';
			showDialog(cnt,'','','closeDialog();');		
		break;
		case 'newpage':
			refreshList('pages');
		break;
		case 'newcat':
			refreshList('categories');
		break;
		case 'newex':
			refreshList('exercises',listSelections['categories']);
		break;
		case 'newbox':
			if(getXmlNodeValue(xml,'wide') == '1')
			{
				refreshList('wideBoxes',listSelections['pages']);
			}
			else
			{
				refreshList('smallBoxes',listSelections['pages'])
			}
		break;
		case 'newdataset':
			refreshList('datasets',listSelections['exercises']);
		break;
		case 'getdataset':
			var rows = getXmlNode(xml,'rows').childNodes;
			if(rows.length == 0)
			{
				document.getElementById('exData').innerHTML = '<i>Geen data aanwezig</i>';
				return;
			}
			var s = '<table border="0" cellspacing="1" cellpadding="1">';
			for(var i = 0; i < rows.length; i++)
			{
				s += '<tr><td>' + (i + 1) + '</td>';
				for(var j = 0; j < rows[i].childNodes.length; j++)
				{
					if(getAttributeValue(rows[i].childNodes[j],'type') == "media")
					{
						s += '<td>Media: ' + rows[i].childNodes[j].firstChild.nodeValue + '</td>';
					}
					else
					{
						s += '<td>' + rows[i].childNodes[j].firstChild.nodeValue + '</td>';
					}
				}
				s += '</tr>';
			}
			s += '</table>';
			document.getElementById('exData').innerHTML = s;
		break;
		case 'getbox':
			var id = getXmlNodeValue(xml,'id');
			var props = getXmlNode(xml,'props');
			handleProperties('boxProperties',props.childNodes);
			
			var boxtype = getXmlNode(props,'boxtype');
			boxtype = getXmlNodeValue(boxtype,'value');
			currentBoxType = boxtype;
			setupBoxContent(boxtype,xml);
		break;
		case 'logout':
			window.location.reload();
		break;
		case 'getpage':
			var id = getXmlNodeValue(xml,'id');
			var props = getXmlNode(xml,'props').childNodes;
			handleProperties('pageProperties',props);
			
			refreshList('wideBoxes',id);
			refreshList('smallBoxes',id);
		break;
		case 'getcat':
			var id = getXmlNodeValue(xml,'id');
			var props = getXmlNode(xml,'props').childNodes;
			handleProperties('categoryProperties',props);
			
			refreshList('exercises',id);
		break;
		case 'getex':
			var id = getXmlNodeValue(xml,'id');
			var props = getXmlNode(xml,'props').childNodes;
			handleProperties('exerciseProperties',props);
			
			refreshList('datasets',id);
		break;
		case 'newlang':
			if(listData['languages'])
			{
				listData['languages'].offset += listData['languages'].numperpage;
			}
			showPreviousListEntries('languages');
		break;
		case 'getlist':
			var id = getXmlNodeValue(xml,'id');
			var total = getXmlNodeValue(xml,'total');
			var err = getXmlNode(xml,'error');
			if(err != null)
			{
				if(err.firstChild.nodeValue == 'OFFSET_TOLARGE')
				{
					listData[getXmlNodeValue(xml,'id')].offset -= listData[getXmlNodeValue(xml,'id')].numperpage;
					if(listData[getXmlNodeValue(xml,'id')].offset < 0)
					{
						listData[getXmlNodeValue(xml,'id')].offset = 0;
					}
					
					if(total == 0)
					{
						fillList([],total,id,'');
					}
				}
				return;
			}
			
			var list = getXmlNode(xml,'list').childNodes;
			var ar = [];
			for(var i = 0; i < list.length; i++)
			{
				var obj = {id: getXmlNodeValue(list[i],'id'),name: getXmlNodeValue(list[i],'name')};
				var vis = getXmlNode(list[i],'visible');
				if(vis != null)
				{
					obj.checked = vis.firstChild.nodeValue == '1' ? true : false;
				}
				ar.push(obj);
			}
			
			var act = 'showItem(\'' + id + '\',{id});';
			fillList(ar,total,id,act);
		break;
		case 'setlang':
			for(var k in listsOnPage)
			{
				refreshList(k);
			}
		break;
		case 'saveprop':
			var id = getXmlNodeValue(xml,'id');
			switch(id)
			{
				case 'boxProperties':
					refreshList('wideBoxes',listSelections['pages']);
					refreshList('smallBoxes',listSelections['pages']);
				break;
				case 'exerciseProperties':
					refreshList('exercises',listSelections['categories']);
				break;
				default:
					id = getListFromProperties(id);
					refreshList(id);
				break;
			}
		break;
		case 'delpage':
			refreshList(id);
		break;
		default:
			//do nothing, accept silently
		break;
	}
}

function showItem(listId,id)
{
	switch(listId)
	{
		case 'languages':
			showLanguage(id);
		break;
		case 'pages':
			showPage(id);
		break;
		case 'smallBoxes': case 'wideBoxes':
			showBox(id);
		break;
		case 'categories':
			showCategory(id);
		break;
		case 'exercises':
			showExercise(id);
		break;
		case 'datasets':
			showDataset(id);
		break;
	}
}

function editorToggleBold(id)
{	
	var win = document.getElementById(id).contentWindow;
	var doc = win.document;
	var sel = win.getSelection ? win.getSelection() : doc.selection;
	var range;
	
	if (sel)
	{
		if (sel.createRange)
		{
			range = sel.createRange();
		} 
		else if (sel.getRangeAt)
		{
			range = sel.getRangeAt(0);
		}
		else if (sel.anchorNode && sel.focusNode && doc.createRange)
		{
			range = doc.createRange();
			range.setStart(sel.anchorNode, sel.anchorOffset);
			range.setEnd(sel.focusNode, sel.focusOffset);
		
			if (range.collapsed !== sel.isCollapsed)
			{
				range.setStart(sel.focusNode, sel.focusOffset);
				range.setEnd(sel.anchorNode, sel.anchorOffset);
			}
		}
		
		var txt = sel + "";
		
		if(range.cloneContents)
		{
			var cnt = docFragmentToString(range.cloneContents());
			var changenode = doc.createElement('span');
			changenode.setAttribute('id','alter');
			changenode.innerHTML = cnt;
			range.deleteContents();
			range.insertNode(changenode);
		}
		else
		{
			range.pasteHTML('<span id="alter">' + range.htmlText + '</span>');
		}
		
		editContent(id,'bold');
	}
}

function docFragmentToString(obj)
{
	var s = "";
	for(var i = 0; i < obj.childNodes.length; i++)
	{
		s += dumpNode(obj.childNodes[i]);
	}
	return s;
}

function dumpNode(node)
{
	if(node.nodeValue != null)
	{
		return node.nodeValue;
	}
	
	var s = '<' + node.nodeName.toLowerCase();
	if(node.attributes)
	{
		for(var i = 0; i < node.attributes.length; i++)
		{
			s += ' ' + node.attributes[i].nodeName + '="' + (node.attributes[i].firstChild ? node.attributes[i].firstChild.nodeValue : '') + '"';s
		}
	}
	s += '>';
	for(i = 0; i < node.childNodes.length; i++)
	{
		s += dumpNode(node.childNodes[i]);
	}
	s += '</' + node.nodeName.toLowerCase() + '>';
	
	if(s.indexOf('<br') == 0)
	{
		s = '<br/>';
			
	}			
	
	return s;
}

function lowerTag(str)
{
	var res = "";
	var started = false;
	var attribute = false;
	var c = 0;
	while(c < str.length)
	{
		if(!started && str.substr(c,1) != "<" && str.substr(c,1) != "/")
		{
			started = true;
		}
		
		if(started && (str.substr(c,1) == " " || str.substr(c,1) == ">"))
		{
			started = false;
		}
		
		if(!attribute && str.substr(c,1) == "=")
		{
			attribute = true;
			if(str.substr(c + 1,1) != '"')
			{
				res += '="';
			}
			else
			{
				res += '=';
			}
		}
		else if(attribute && (str.substr(c,1) == " " || str.substr(c,1) == "/" || str.substr(c,1) == ">"))
		{
			attribute = false;
			if(str.substr(c - 1,1) != '"')
			{
				res += '"' + str.substr(c,1);
			}
			else
			{
				res += str.substr(c,1);
			}
		}
		else
		{
			res += started ? str.substr(c,1).toLowerCase() : str.substr(c,1);
		} 
		
		c++;
	}
	
	res += str.substr(c);
	return res;
}

function tagsToLower(str)
{
	var res = "";
	var stpos = str.indexOf('<');
	var epos = -1;
	while(stpos > -1)
	{
		epos += 1;
		res += str.substr(epos,stpos - epos);
		epos = str.indexOf('>',stpos);
		res += lowerTag(str.substr(stpos,(epos - stpos) + 1));
		
		stpos = str.indexOf('<',epos);
	}
	epos += 1;
	res += str.substr(epos);
	return res;
}

function arRemove(ar,it)
{
	if(ar)
	{
		for(var i = 0; i < ar.length; i++)
		{
			if(ar[i] == it)
			{
				ar.splice(i,1);
				break;
			}
		}
	}
}

function editContent(id,cmd)
{
	var idstring = '<span id="alter">';
	
	var win = document.getElementById(id).contentWindow;
	var doc = win.document;
	var html = tagsToLower(doc.body.innerHTML);
	html = removeEmptyTags(html);
	var pos = html.indexOf(idstring);
	
	var status = "text";
	var directContain = true;
	var containedIn = [];
	var opennodes = [];
	var cnode = "";
	var epos = 0;
	while(pos > 0)
	{
		pos--;
		if(html.substr(pos,1) == ">")
		{
			status = "intag";
		}
		else if(html.substr(pos,1) == "<")
		{
			status = "text";
			epos = html.indexOf('>',pos);
			
			if(html.substr(pos + 1,1) == "/")
			{
				cnode = html.substr(pos + 2, epos - (pos + 2));
				opennodes.push(cnode);//<b>asdf<u>sadf</u> <alter>asdfasd</alter> jaap</b>
			}
			else if(html.substr(epos - 1,1) != "/")//start node, find matching end node
			{
				cnode = html.substr(pos + 1, epos - (pos + 1));
				var p = cnode.indexOf(" ");
				cnode = p == -1 ? cnode : cnode.substr(0,p);
				
				var found = false;
				if(opennodes.length > 0)
				{
					
					for(var i = 0; i < opennodes.length; i++)
					{
						if(opennodes[i] == cnode)
						{
							opennodes.splice(i,1);
							found = true;
							break;
						}
					}
				}
				if(!found && cnode != 'br')
				{
					var obj = {node:cnode,direct:directContain};
					
					var endNodesToFind = 1;
					epos = pos;
					p = pos;
					while(endNodesToFind > 0  && epos > -1)
					{
						epos = getTagIndex(html,cnode,epos + 1,true);
						while(p > -1 && p < epos)
						{
							p = getTagIndex(html,cnode,p + 1);
							if(p >-1 && p < epos)
							{
								endNodesToFind++;
							}
						}
						endNodesToFind--;
					}
					
					obj.spos = pos;
					obj.epos = epos;
					if(directContain)//only spaces and tags allowed between </alter> and endtag
					{
						var dc = true;
						var st = "text";
						p = selend + 8;
						while(dc && p < epos)
						{
							if(html.substr(p,1) == "<")
							{
								st = "node";
							}
							else if(html.substr(p,1) == ">" && st == "node")
							{
								st = "text";
							}
							else if(st == "text" && html.substr(p,1) != " ")
							{
								dc = false;
							}
							p++;
						}
					}
					obj.direct = dc;
					
					containedIn.push(obj);
				}
			}
		}
		else if(status == "text" && html.substr(pos,1) != " ")
		{
			directContain = false;
		}
	}
	
	var tobereplaced = [];
	var replacements = [];
	
	var selstart = html.indexOf(idstring);
	var selend = getEndTagPos(html,'span',selstart);
	var contained = false;
	for(var i = 0; i < containedIn.length; i++)
	{
		//- selection can be directly contained in b tags: remove outside b tags
		if(containedIn[i].node == "b" && containedIn[i].direct)//<b><alter>hi</alter></b>
		{
			html = setupReplacement(html,tobereplaced,replacements,containedIn[i].spos,'');
			html = setupReplacement(html,tobereplaced,replacements,containedIn[i].epos,'');
			html = setupReplacement(html,tobereplaced,replacements,selstart,'');
			html = setupReplacement(html,tobereplaced,replacements,selend,'');
			contained = true;
			
			var p = getTagIndex(html,'b',selstart);
			while(p > -1 && p < selend)
			{
				html = setupReplacement(html,tobereplaced,replacements,p,'');
				p = getTagIndex('b',p);
			}
			var p = getTagIndex(html,'b',selstart,true);
			while(p > -1 && p < selend)
			{
				html = setupReplacement(html,tobereplaced,replacements,p,'');
				p = getTagIndex(html,'b',p,true);
			}
			
			break;
			
		}
		//- selection can be indirectly contained in b tags: add end b tag before selection, add start b tag after selection
		if(containedIn[i].node == "b" && !containedIn[i].direct)//<b>Bla<u>blue</u><alter>hi</alter></b>
		{
			html = setupReplacement(html,tobereplaced,replacements,selstart,'</b>');
			html = setupReplacement(html,tobereplaced,replacements,selend,'<b>');
			contained = true;
			
			var p = getTagIndex(html,'b',selstart);
			while(p > -1 && p < selend)
			{
				html = setupReplacement(html,tobereplaced,replacements,p,'');
				p = getTagIndex('b',p);
			}
			var p = getTagIndex(html,'b',selstart,true);
			while(p > -1 && p < selend)
			{
				html = setupReplacement(html,tobereplaced,replacements,p,'');
				p = getTagIndex(html,'b',p,true);
			}
			
			break;
		}
	}
	
	if(!contained)
	{
		var pos = getTagIndex(html,'b',selstart); 
		if(pos > -1 && pos < selend)
		{
			var sttags = 0;
			var endtags = 0;
			//determine if there are any open tags in selection not closed within selection
			
			//count starttags within sel and count endtags within sel
			//if starttags > endtags => outside
			var positions = [];
			while(pos > -1 && pos < selend)
			{
				positions.push(pos);
				sttags++;
				pos = getTagIndex(html,'b',pos + 1);
			}
			
			pos = getTagIndex(html,'b',selstart,true);
			while(pos > -1 && pos < selend)
			{
				positions.push(pos);
				endtags++;
				pos = getTagIndex(html,'b',pos + 1,true);
			}
			
			if(sttags > endtags)//tag ends outside selection, place starttag in front of selection and remove all tags
			{
				html = setupReplacement(html,tobereplaced,replacements,selstart,'<b>');
				html = setupReplacement(html,tobereplaced,replacements,selend,'');
			}
			else//tag(s) all end within selection, remove them and contain selection in tags
			{
				if(checkAllEncased(html,'b',selstart,selend))
				{
					//all will be removed by positions
					contained = true;
				}
				else
				{
					pos = getTagIndex(html,'b',selstart);
					var contentStart = getContentPos(html,selstart);
					if(pos > -1 && pos < contentStart)//check if selection starts and ends with tag
					{
						var epos = getEndTagPos(html,'b',pos);
						contentStart = getContentPos(html,epos);
						if(epos > -1 && (contentStart > selend || contentStart == -1) && (epos < contentStart || contentStart == -1))//string starts and ends with <b>
						{
							contained = true;
							html = setupReplacement(html,tobereplaced,replacements,pos,'');
							html = setupReplacement(html,tobereplaced,replacements,epos,'');
							
							arRemove(positions,pos);
							arRemove(positions,epos); 
						}
					}
				}
				
				html = setupReplacement(html,tobereplaced,replacements,selstart,contained ? '' : '<b>');
				html = setupReplacement(html,tobereplaced,replacements,selend,contained ? '' : '</b>');
			}
			for(var i in positions)
			{
				html = setupReplacement(html,tobereplaced,replacements,positions[i],'');
			}
		}
		else//no bold tags present whatsoever
		{
			html = setupReplacement(html,tobereplaced,replacements,selstart,'<b>');
			html = setupReplacement(html,tobereplaced,replacements,selend,'</b>');
		}
	}
	
	//if all content is encased in multiple tags, remove them in stead of containing entire selection in one tag (because entire span is effective affected)
	
	//alert(html);
	html = multiReplace(tobereplaced,replacements,html);
	html = removeEmptyTags(html);
	doc.body.innerHTML = html;
	
	//find any nodes in selection
	//check if selection is contained in a tag
	//if contained in a tag do nothing
	//if directly contained in a tag, remove tag
	//else add tag
}

function checkAllEncased(str,tag,st,end)
{
	var p = getTagIndex(str,tag,st);
	var contentStart = getContentPos(str,st);
	
	
	while(p > -1)
	{
		var endpos = getTagIndex(str,tag,p,true);
		//check if any content is present before the first tag
		if(contentStart > -1 && contentStart < end && (contentStart < p || p == -1))
		{
			return false;
		}
		p = getTagIndex(str,tag,endpos);
		contentStart = getContentPos(str,endpos);
	}
	
	return true;
}

function getContentPos(str,pos)
{
	var st = "text";

	while(pos > -1 && pos < str.length)
	{
		if(str.substr(pos,1) == "<")
		{
			st = "node";
		}
		else if(str.substr(pos,1) == ">" && st == "node")
		{
			st = "text";
		}
		else if(st == "text" && str.substr(pos,1) != " ")
		{
			break;
		}
		pos++;
	}
	return pos < str.length ? pos : -1;
}

function getEndTagPos(str,tag,start)
{
	var endNodesToFind = 1;
	var epos = start;
	var p = start;
	while(endNodesToFind > 0  && epos > -1)
	{
		epos = getTagIndex(str,tag,epos + 1,true);
		while(p > -1 && p < epos)
		{
			p = getTagIndex(str,tag,p + 1);
			if(p >-1 && p < epos)
			{
				endNodesToFind++;
			}
		}
		endNodesToFind--;
	}
	return epos;
}

function getTagIndex(str,tag,pos,ending)
{
	var tag = '<' + (ending ? '/' : '') + tag;
	pos = str.indexOf(tag,pos);
	
	while(pos > -1 && pos < str.length)
	{
		if(str.substr(pos + tag.length,1) == " " || str.substr(pos + tag.length,1) == ">")
		{
			return pos;
		}
		else
		{
			pos++;
		}
		
		pos = str.indexOf(tag,pos);
	}
	return -1;
}

function removeEmptyTags(html)
{
	var replacements = [];
	var res = "";
	var pos = html.indexOf('<');
	while(pos > -1 && pos < html.length)
	{
		if(html.substr(pos + 1,1) != "/")//start tag
		{
			var start = pos;
			var end = html.indexOf(">",pos);
			var spacepos = html.indexOf(" ",pos);
			end = spacepos > -1 && spacepos < end ? html.indexOf(" ",pos) : end;
			var name = html.substr(pos + 1,end - (pos + 1));
			
			var closing = getEndTagPos(html,name,pos);
			var contentStart = getContentPos(html,pos);
			pos += 1;
			if(closing > -1 && (contentStart == -1 || contentStart > closing))
			{
				closing = html.indexOf('>',closing);
				var brcheck = html.indexOf('<br',start);
				if(!(brcheck > -1 && brcheck < closing))
				{
					var uid = getUniqueIdentifier(html,(closing - start) + 1);
					html = replaceTextSpan(html,start,closing,uid);
					replacements.push(uid);
				}
				
				pos = closing;
			}
			
			
			/*pos = html.indexOf(">",pos) + 1;
			
			var next = html.indexOf("<",pos);
			while(pos < next && html.substr(pos,1) == " ")
			{
				pos++;
			}
			
			var endchar = html.substr(pos + 1 + name.length + 1,1);
			if(pos == next && html.indexOf('</' + name,pos) == pos && (endchar == " " || endchar == ">"))//tag is empty
			{
				next = html.indexOf('>',next);
				var uid = getUniqueIdentifier(html,(next - start) + 1);
				html = replaceTextSpan(html,start,next,uid);
				replacements.push(uid);
			}*/
		}
		else
		{
			pos += 1;
		}
		pos = html.indexOf('<',pos);
	}
	return multiReplace(replacements,[''],html);
}

function setupReplacement(html,tobereplaced,replacements,spos,replacement)
{
	var end = html.indexOf('>',spos);
	var uid = getUniqueIdentifier(html,(end - spos) + 1);
	html = replaceTextSpan(html,spos,end,uid);
	tobereplaced.push(uid);
	replacements.push(replacement);
	
	return html;
}

function replaceTextSpan(str,spos,epos,replacement)
{
	return str.substr(0,spos) + replacement + str.substr(epos + 1);
}

function rand(imin,imax)
{
	return Math.floor(Math.random() * (imax - imin)) + imin;
}

function getUniqueIdentifier(str,len)
{
	var res = "";
	var rndChars = "abcdefghijklmnopqrstuvwxyz012456789";
	
	var done = false;
	var tries = 0;
	while(!done && tries < 500)
	{
		tries++;
		if(len >= 3) { res = "{"; }
		while (res.length < len - 1)
		{
			res += rndChars.substr(rand(0,rndChars.length),1);
		}
		if(len >= 3) { res += "}"; }
		
		if(len < 3)
		{
			res = "";
			while(res.length < len)
			{
				res += rndChars.substr(rand(0,rndChars.length),1);
			}
		}
		
		done = str.indexOf(res) == -1;
	}
	return res;
}

function setupBoxContent(boxtype,xml)
{
	var contentholders = ['standard','media','flash','html','php'];
	for(var i in contentholders)
	{
		document.getElementById('boxContents_' + contentholders[i]).style.display = 'none';
	}
	document.getElementById('boxContents_' + contentholders[Number(boxtype) - 1]).style.display = 'block';
	
	switch(boxtype)
	{
		case '1':
			document.getElementById('boxProperties_standard_editor').contentDocument.body.innerHTML = getXmlNodeValue(xml,'contents');
		break;
		case '4':
			document.getElementById('boxProperties_html_contents').value = getXmlNodeValue(xml,'contents');
		break;
	}
}

function handleProperties(id,props)
{
	propertiesData[id] = {};
	for(var i = 0; i < props.length; i++)
	{
		var el = document.getElementById(id + '_' + props[i].nodeName.toLowerCase());
		propertiesData[id][props[i].nodeName.toLowerCase()] = {type: getAttributeValue(props[i],'type')};
		switch(getAttributeValue(props[i],'type'))
		{
			case 'str': case 'hidden':
				el.value = getXmlNodeValue(props[i],'value');
			break;
			case 'img':
				var curimg = document.getElementById(id + '_' + props[i].nodeName.toLowerCase() + '_current');
				curimg.value = getXmlNodeValue(props[i],'value');
				document.getElementById(id + '_' + props[i].nodeName.toLowerCase() + '_temp').value = '0';
				var fl = getFlashMovie(id + '_' + props[i].nodeName.toLowerCase() + "_flash");
				if(fl.setText)
				{
					fl.setText(getXmlNodeValue(props[i],'name'));
				}
				else
				{
					setTimeout("retryFlashText('" + id + '_' + props[i].nodeName.toLowerCase() + "_flash" + "','" + getXmlNodeValue(props[i],'name') + "');",500);
				}
			break;
			case 'bool':
				el.checked = getXmlNodeValue(props[i],'value') == "1";
			break;
			case 'list':
				var ar = el.getElementsByTagName('option');
				for(var j = 0; j < ar.length; j++)
				{
					if(ar[j].value == getXmlNodeValue(props[i],'value'))
					{
						el.selectedIndex = j;
						break;
					}
				}
			break;
		}
	}
}

function refreshList(id,pid)
{
	if(!listData[id])
	{
		var npp = getClassDiv(document.getElementById(id),'cmsListNumPerPage');
		listData[id] = {offset: 0,numperpage: Number(npp.innerHTML)};
	}
	
	var obj = {cmd:'getlist',id:id,offset:listData[id].offset,num:listData[id].numperpage};
	if(pid)
	{
		obj.pid = pid;
	}
	submitData(obj,'process.php',dataProcessed);
}

function deleteListItem(id)
{
	if(!listSelections[id])
	{
		alert('Er is geen item geselecteerd!');
		return;
	}
	
	if(confirm('De geselecteerde pagina wordt verwijderd uit alle talen. Zeker weten?'))
	{
		submitData({cmd:'delpage',id:listSelections[id]},'process.php',dataProcessed);
	}
}

function removeImage(id)
{
	document.getElementById(id + "_temp").value = 0;
	var flmv = getFlashMovie(id + "_flash");
	flmv.setText('<Geen>');
}

function viewImage(id)
{
	var tempid = document.getElementById(id + "_temp").value;
	if(tempid == 0)
	{
		tempid = document.getElementById(id + "_current").value;
	}
	
	if(tempid != 0)
	{
		submitData({cmd:'viewimg',id:tempid},'process.php',dataProcessed);
	}
}

function getListFromProperties(id)
{
	var listmap = {pageProperties:'pages',categoryProperties:'categories',exerciseProperties:'exercises'};
	return listmap[id];
}

function cancelProperties(id)
{
	if(id == 'boxProperties')
	{
		refreshList('wideBoxes',listSelections['pages']);
		refreshList('smallBoxes',listSelections['pages']);
	}
	else
	{
		id = getListFromProperties(id);
		refreshList(id);
	}
}

function saveProperties(id)
{
	if(!propertiesData[id])
	{
		alert('Er is een fout opgetreden. Probeer het nogmaals. (propertiesData is leeg)');
		return;
	}
	
	var data = {};
	for(var k in propertiesData[id])
	{
		switch(propertiesData[id][k].type)
		{
			case 'str': case 'hidden': case 'list':
				data[k] = document.getElementById(id + "_" + k).value;
			break;
			case 'bool':
				data[k] = document.getElementById(id + "_" + k).checked ? '1' : '0';
			break;
			case 'img':
				var el = document.getElementById(id + "_" + k + "_temp");
				if(el.value != '0')
				{
					data[k] = el.value;
				}
			break;
		}
	}
	data.cmd = 'saveprop';
	data.propid = id;
	submitData(data,'process.php',dataProcessed);
}

var listData = {};
var listSelections = {};

function listSelect(id,entryId)
{
	var entries = document.getElementById(id);
	entries = getClassDiv(entries,'cmsListContent');
	entries = entries.getElementsByTagName('a');
	for(var i = 0; i < entries.length; i++)
	{
		if(entries[i].nodeName.toLowerCase() == 'a')
		{
			entries[i].className = 'listEntry';
		}
	}
	
	if(!listSelections[id])
	{
		listSelections[id] = {};
	}
	listSelections[id] = entryId;
	
	var entry = document.getElementById(id + entryId);
	if(entry != null)
	{
		entry.className = 'listEntrySelected';
	}
	else
	{
		listSelections[id] = 0;
	}
}

function setVisibility(listId,id)
{
	var cb = document.getElementById(listId + id);
	cb = cb.parentNode.parentNode.getElementsByTagName('input');
	cb = cb[0];
	
	submitData({cmd:'setvis',id:id,listid:listId,vis:cb.checked ? 1 : 0},'process.php',dataProcessed);
}

function activateTab(id)
{
	var curTabBut = document.getElementById(id + 'But');
	var curTab = document.getElementById(id);
	var oldstate = "";
	if(curTabBut.className == 'tabLinkSelected')
	{
		oldstate = curTab.style.display;
	}
	
	var actgrp = "";
	for(var grp in tabsOnPage)
	{
		for(var i = 0; i < tabsOnPage[grp].length; i++)
		{
			if(tabsOnPage[grp][i] == id)
			{
				actgrp = grp;
				break;
			}
		}
	}
	
	for(var tab in tabsOnPage[actgrp])
	{
		var el = document.getElementById(tabsOnPage[actgrp][tab] + 'But');
		el.className = 'tabLink';
		el = document.getElementById(tabsOnPage[actgrp][tab]);
		el.style.display = "none";
	}
	
	
	 
	if(oldstate != "")//expand or collapse
	{
		
		curTab.style.display = oldstate == "block" ? 'none' : 'block';
	}
	else
	{ 
		curTabBut.className = 'tabLinkSelected';
		curTab.style.display = "block";
	}
}

function fillList(ar,total,id,clickAction)
{
	var lcnt = document.getElementById(id);
	lcnt = getClassDiv(lcnt,'cmsListContent');
	var s = '<table border="0" cellspacing="0" cellpadding="0">';
	for(var i = 0; i < ar.length; i++)
	{
		s += '<tr>';
		s += '<td width="125">' + getLink(JSNULL,ar[i].name,id + ar[i].id,'listEntry','',multiReplace(['{id}'],[ar[i].id],clickAction)) + '</td>';
		if(ar[i].checked != null)
		{
			s += '<td><input type="checkbox" class="checkBox" onclick="setVisibility(\'' + id + '\',' + ar[i].id + ');" ' + (ar[i].checked ? 'checked="1"' : '') + '/></td>';
		}
		s += '</tr>';
	}
	s += '</table>';
	lcnt.innerHTML = s;
	
	if(ar.length == 0)
	{
		lcnt.innerHTML = '<i>Deze lijst is leeg</i>';
	}
	
	var lnav = document.getElementById(id);
	lnav = getClassDiv(lnav,'cmsListNav');
	lnav = getClassDiv(lnav,'cmsListNavInner');
	lnav.innerHTML = '[ ' + (Math.floor(listData[id].offset / listData[id].numperpage) + 1) + '/' + Math.max(1,Math.ceil(total / listData[id].numperpage)) + ' ]';
	
	if(ar.length == 0)
	{
		return;
	}
	
	//check if currently something selected and if it is present in list
	var cursel = -1;
	if(listSelections[id])
	{
		cursel = listSelections[id];
		for(var i = 0; i < ar.length; i++)
		{
			if(ar[i].id == cursel)
			{
				break;
			}
		}
		if(i == ar.length) { cursel = -1; }
	}
	
	//if other box has valid selection, get out
	if(id == 'smallBoxes' && listSelections['wideBoxes'] && document.getElementById('wideBoxes' + listSelections['wideBoxes'])) { return; }
	if(id == 'wideBoxes' && listSelections['smallBoxes'] && document.getElementById('smallBoxes' + listSelections['smallBoxes'])) { return; }	
	
	if(cursel == -1) { cursel = ar[0].id; }
	
	eval(multiReplace(['{id}'],[cursel],clickAction));
}

function showPreviousListEntries(id)
{
	var lcnt = document.getElementById(id);
	
	if(!listData[id])
	{
		var npp = getClassDiv(lcnt,'cmsListNumPerPage');
		listData[id] = {offset: 0,numperpage: Number(npp.innerHTML)};
	}
	
	if(listData[id].offset == 0)
	{
		//return;
	}
	
	listData[id].offset = Math.max(0,listData[id].offset - listData[id].numperpage);
	refreshList(id);
}

function showNextListEntries(id)
{
	var lcnt = document.getElementById(id);
	
	if(!listData[id])
	{
		var npp = getClassDiv(lcnt,'cmsListNumPerPage');
		listData[id] = {offset: 0,numperpage: Number(npp.innerHTML)};
	}
	
	listData[id].offset = listData[id].offset + listData[id].numperpage;
	refreshList(id);
}

function showLanguage(id)
{
	listSelect('languages',id);
}

function changeLanguage()
{
	var el = document.getElementById('languageSelect');
	submitData({cmd:'setlang',id:el.value},'process.php',dataProcessed);
}

function showBox(id)
{
	listSelect('smallBoxes',id);
	listSelect('wideBoxes',id);
	submitData({cmd:'getbox',id:id},'process.php',dataProcessed);
}

function showPage(id)
{
	listSelect('pages',id);
	submitData({cmd:'getpage',id:id},'process.php',dataProcessed);
}

function showCategory(id)
{
	listSelect('categories',id);
	submitData({cmd:'getcat',id:id},'process.php',dataProcessed);
}

function showExercise(id)
{
	listSelect('exercises',id);
	submitData({cmd:'getex',id:id},'process.php',dataProcessed);
}

function showDataset(id)
{
	listSelect('datasets',id);
	submitData({cmd:'getdataset',id:id},'process.php',dataProcessed);
}

function uploadDone(name,id)
{
	var el = document.getElementById(name + "_temp");
	el.value = id;
	return 1;
}

function getHtmlEditorContent(id)
{
	return document.getElementById(id).contentDocument.body.innerHTML;
}

function saveBoxContents()
{
	var data = {cmd:'savebox',id:document.getElementById('boxProperties_id').value,boxtype:currentBoxType};
	switch(currentBoxType)
	{
		case '1':
			data.media_id = document.getElementById("boxProperties_standard_media_id_current").value;
			data.contents = getHtmlEditorContent('boxProperties_standard_editor');
		break;
		case '4':
	 		data.contents = document.getElementById('boxProperties_html_contents').value;
		break;
		
	}
	submitData(data,'process.php',dataProcessed);
}

function getPosition(el)
{
    var obj = {x: 0,y: 0};
    while(el)
	{
		obj.x += el.offsetLeft;
		obj.y += el.offsetTop;
		el = el.offsetParent;
    }
    
    return obj;
}

function getMousePosition(evt)
{
	var obj = {x: 0,y: 0};
	if (evt.pageX) 
	{ 
		obj.x = evt.pageX;
		obj.y = evt.pageY;
	}
	else if (evt.clientX)
	{
	   obj.x = evt.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
	   obj.y = evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
 	}
 	return obj;
}

function startDrag(e,el)
{
	if (!e) var e = window.event;
	
	curDrag = el.parentNode;
	
	var mpos = getMousePosition(e);
	var pos = getPosition(el);
	dragOffset.x = pos.x - mpos.x;
	dragOffset.y = pos.y - mpos.y;
	
	curDrag.style.position = 'absolute';
	curDrag.style.left = pos.x + 'px';
	curDrag.style.top = pos.y + 'px';
	curDrag.style.zIndex = '1';
	
	if (e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; }
	if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; }
}

function getOrder(wide)
{
	var container = document.getElementById(wide ? 'boxesLeft' : 'boxesRight');
	var order = "";
	for(var i = 0; i < container.childNodes.length; i++)
	{
		if(container.childNodes[i].className.indexOf('NoMove') == -1)
		{ 
			var box = container.childNodes[i];
			var id = box.childNodes[box.childNodes.length - 2].id.split('_')[1];
			order += ';' + id;
		}
	}
	return order.substr(1);
}

function stopDrag(e)
{
	if(curDrag)
	{
		if (!e) var e = window.event;
		var mpos = getPosition(curDrag);
		
		var wide = curDrag.className == 'wideBox';
		var container = document.getElementById(wide ? 'boxesLeft' : 'boxesRight');
		container.removeChild(curDrag);
		for(var i = curDrag.className == 'wideBox' ? 1 : 0; i < container.childNodes.length; i++)
		{
			if(container.childNodes[i] != curDrag)
			{
				var pos = getPosition(container.childNodes[i]);
				if(mpos.y < pos.y)
				{
					break;
				}
			}
		}
		//i is now equal to the element below mouse pos, so insert item after
		if(i < container.childNodes.length)
		{
			var droptarget = container.childNodes[i];
			while(droptarget && droptarget.className.indexOf('NoMove') > -1) { droptarget = droptarget.nextSibling; }
		}
		if(droptarget)
		{
			container.insertBefore(curDrag,droptarget);
		}
		else
		{
			container.appendChild(curDrag);
		}
		
		submitData({cmd:'stororder',id:pageid,order:getOrder(wide),wide:wide ? 1 : 0},'process.php',dataProcessed);
		
		curDrag.style.zIndex = '0';
		curDrag.style.position = "relative";
		curDrag.style.left = "0px";
		curDrag.style.top = "0px";
		curDrag = null;
	}
}

var dragOffset = {x: 0,y: 0};
var curDrag = null;
function doMouseMove(e)
{
	if(curDrag)
	{
		if (!e) var e = window.event;
		var mpos = getMousePosition(e);
		
		if (e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; }
		if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; }
		
		curDrag.style.left = mpos.x + dragOffset.x + 'px';
		curDrag.style.top = mpos.y + dragOffset.y + 'px';
	}
	
	if(!curToolTipHover) { return; }
	
	var p = getMousePosition(e);
	var ori = getPosition(curToolTipHover);
	if(p.x >= ori.x && p.x <= ori.x + curToolTipHover.offsetWidth && p.y >= ori.y && p.y <= ori.y + curToolTipHover.offsetHeight)
	{
		var p = getMousePosition(e);
		var tt = document.getElementById('toolTipId');
		if(tt)
		{
			tt.style.top = (p.y - tt.offsetHeight - 2) + 'px';
			tt.style.left = (p.x + 2) + 'px';
		}
	}
	else
	{
		hideToolTip();
	}
}

var checkBoxGroups = {};
function toggleCheckBox(id,checked)
{
	document.getElementById(id + '_value').value = checked;
	document.getElementById(id + '_checked').style.display = 'none';
	document.getElementById(id + '_notchecked').style.display = 'none';
	document.getElementById(id + '_' + (checked ? '' : 'not') + 'checked').style.display = 'inline';
	
	var grp = null;
	for(var g in checkBoxGroups)
	{
		for(var i in checkBoxGroups[g])
		{
			if(checkBoxGroups[g][i] == id) 
			{ 
				grp = g;
				break;
			}
		}
		if(grp) { break; }
	}
	
	if(grp)
	{
		if(checked)
		{
			for(var i in checkBoxGroups[grp])
			{
				if(checkBoxGroups[grp][i] != id)
				{
					document.getElementById(checkBoxGroups[grp][i] + '_value').value = 0;
					document.getElementById(checkBoxGroups[grp][i] + '_checked').style.display = 'none';
					document.getElementById(checkBoxGroups[grp][i] + '_notchecked').style.display = 'inline';
				}
			}
		}
		else
		{
			var i = 0;
			while(i < checkBoxGroups[grp].length && checkBoxGroups[grp][i] == id)
			{
				i++;
			}
			if(i < checkBoxGroups[grp].length)
			{
				document.getElementById(checkBoxGroups[grp][i] + '_value').value = 1;
				document.getElementById(checkBoxGroups[grp][i] + '_checked').style.display = 'inline';
				document.getElementById(checkBoxGroups[grp][i] + '_notchecked').style.display = 'none';
			}
		}
	}
}

function elementVal(id)
{
	return document.getElementById(id) ? document.getElementById(id).value : null;
}

function isEmail(str)
{
	var apos = str.indexOf('@');
	var dpos = str.lastIndexOf('.');
	
	if(apos < 1 || dpos == -1 || dpos < apos || dpos - apos == 1 || dpos > str.length - 3) { return false; }
	return true;
}

function isNumeric(str)
{
	var nums = '0123456789';
	for(var i = 0; i < str.length; i++)
	{
		if(nums.indexOf(str.charAt(i)) == -1) { return false; }
	}
	return str.length > 0 ? true : false;
}

function topNavSetSelection(id)
{
	var links = document.getElementById('topNavCategories').childNodes;
	for(var i = 0; i < links.length; i++)
	{
		if(links[i].id != 'loginButton') { links[i].className = 'topNavCategory'; }
	}
	
	if(document.getElementById('topNavCategory' + id))
	{
		document.getElementById('topNavCategory' + id).className = 'topNavCategoryHighlight';
	}
	
	links = document.getElementById('topNavLinks').childNodes;
	for(var i = 0; i < links.length; i++)
	{
		if(links[i].nodeName.toLowerCase() == 'div')
		{
			links[i].style.display = 'none';
		}
	}
	
	document.getElementById('topNavLinks' + id).style.display = 'block';
}

function wbCh_setSelected(level,sel,override)
{
	if(!override && level == wbCh_selectedLevel) { return; }
	document.getElementById('wbCh_level' + level).setAttribute('src','img/levelicon' + level + (sel ? '_sel' : '') + '.gif');
}

function wbCh_setLevel(level)
{
	wbCh_setSelected(wbCh_selectedLevel,0,true);
	wbCh_selectedLevel = level;
	wbCh_setSelected(wbCh_selectedLevel,1,true);
	
	var links = document.getElementById('wbCh_startExercise').getElementsByTagName('a');
	for(var i = 0; i < links.length; i++)
	{
		var url = links[i].getAttribute('href').split('/');
		if(!isNumeric(url[url.length - 1])) { url.push(wbCh_selectedLevel); }
		url[url.length - 1] = wbCh_selectedLevel;
		links[i].setAttribute('href',url.join('/'));
	}
	
	if(eval('typeof sbI_showLevel') == 'function')
	{
		eval('sbI_showLevel(' + level + ')');
	}
}

function expandLogin()
{
	var el = document.getElementById('sbLog_login_identifier');
	var box = el.parentNode.parentNode.parentNode;
	box.style.display = 'none';
	toggleCollapse(box.previousSibling);
}

function wbEr_setSelected(level,sel,override)
{
	if(!override && level == wbEr_selectedLevel) { return; }
	document.getElementById('wbCh_level' + level).setAttribute('src','img/levelicon' + level + (sel ? '_sel_er.png' : '.gif'));
}

function wbEr_setLevel(level)
{
	wbEr_setSelected(wbEr_selectedLevel,0,true);
	wbEr_selectedLevel = level;
	wbEr_setSelected(wbEr_selectedLevel,1,true);
	
	var links = document.getElementById('wbCh_startExercise').getElementsByTagName('a');
	for(var i = 0; i < links.length; i++)
	{
		var url = links[i].getAttribute('href').split('/');
		if(!isNumeric(url[url.length - 1])) { url.push(wbEr_selectedLevel); }
		url[url.length - 1] = wbEr_selectedLevel;
		links[i].setAttribute('href',url.join('/'));
	}
}


function logout()
{
	submitData({cmd:'logout'},'process.php',dataProcessed);
}

function wbCh_showExercise(sellink,id)
{
	var el = document.getElementById('wbCh_rside_cat');
	
	while(el)
	{
		el.style.display = 'none';
		el = el.nextSibling;
	}
	
	document.getElementById('wbCh_rside_exercise' + id).style.display = 'block';
	
	var links = document.getElementById('wbCh_leftSide').childNodes;
	for(var i = 0; i < links.length; i++)
	{
		links[i].className = 'wbCh_exercise';
	}
	sellink.className = 'wbCh_exerciseSelected';
	
	document.getElementById('wbCh_startExercise').style.display = 'block';
	
	links = document.getElementById('wbCh_startExercise').getElementsByTagName('a');
	for(var i = 0; i < links.length; i++)
	{
		links[i].style.display = 'none';
	}
	var link = document.getElementById('wbCh_startExercise_link' + id);
	link.style.display = 'block';
	
	if(eval('typeof wbExp_showExplanation') == 'function')
	{
		if(id == 0) { id = "'tent'"; }
		eval('wbExp_showExplanation(' + id + ')');
	}
}

function toggleCollapse(el)
{
	var cnt = el.nextSibling;
	var id = cnt.id.split("_")[1];
	cnt.style.display = cnt.style.display == 'none' ? 'block' : 'none';
	el.setAttribute('src','img/collapse_' + (cnt.style.display == 'none' ? 'up' : 'down') + '.png');
	
	submitData({cmd:'storcol',id:id,pid:pageid,col:cnt.style.display == 'none' ? 1 : 0},'process.php',dataProcessed);
}

var curToolTipHover = null;
function showToolTip(title,txt,hoverel,e)
{
	curToolTipHover = hoverel;
	if (!e) var e = window.event;
	
	var el = document.getElementById('toolTipId');
	if(el) { el.parentNode.removeChild(el); }
	
	el = createTag('div','toolTipId','ToolTip');
	var html = getImage('tooltip_top.png','','',0,0);
	html += '<div class="ToolTipMid">';
	html += getDiv('','TooltipHeader',title,true);
	html += txt;
	html += '</div>';
	html += getImage('tooltip_bot.png','','',0,0);
	el.innerHTML = html;
	
	var p = getMousePosition(e);
	el.setAttribute('style','top: ' + (p.y - 50) + 'px; left: ' + (p.x + 2) + 'px;');
	
	document.body.appendChild(el);
	
	el.style.top = (p.y - el.offsetHeight - 2) + 'px';
}

function hideToolTip()
{
	var el = document.getElementById('toolTipId');
	if(el) { el.parentNode.removeChild(el); }
}
