/* code by jonne unless noted otherwise*/

function getroot()	{
	/* seriously, why is this so hard to get right?
	 * This still needs fixing, but it works more or less...
	 */
	var address=''+this.location;
	if(address.indexOf('/xml/')>0){
		return address.substring(0,address.indexOf('/xml/'))+'/';
		}else{
		return address.substring(0,address.lastIndexOf('/'))+'/';
		}
	}
/* initialisation */
/* this is the 'bootloader', functions that need to run on page load need to be added here */
function upstart(){
	window.makeMailLinks?makeMailLinks():null;
	window.makeCalendar?makeCalendar():null;
	window.askConfirmation?askConfirmation():null;	//ask for confirmation before submiting 'dangerous' forms
	window.xmlRequests?xmlRequests():null; 			//this one refreshes the <div> in question according to an url  and a defined timeout (class="xmlget")
	window.popups?popups():null; 
	window.keepSession?keepSession():null;			//keep the session alive when idling
	window.setMaxLength?setMaxLength():null;		//checks for textarea's with maxlength
	window.autoSubmit?autoSubmit():null;	 		//submit form fields if the selectbox value is altered
	window.xmlActions?xmlActions():null;	 			// xmldo -> send a get request to the server without having to leave the page
	window.lightBox?lightBox():null;					//lightbox variant
	window.initLiveSearch?initLiveSearch():null; 		//livesearch: like google suggest
	}
function refresh()	{
	window.popups?popups():null;
	window.xmlActions?xmlActions():null;	 			// xmldo -> send a get request to the server without having to leave the page
	window.lightBox?lightBox():null;					//lightbox variant
	}	
		
function makeMailLinks()
	{
	if (!document.getElementsByTagName && !document.createElement && !document.createTextNode)
		return;
	var spans = document.getElementsByTagName("span");
	for(var i=0;i<spans.length;i++)
		{
		if (spans[i].className=="email")
			{
			var theNode = spans[i];
			var theAddress = theNode.firstChild.nodeValue;
			
			theAddress = theAddress.replace(/ \(at\) /, "@");
			theAddressNode = document.createElement('A');
			theAddressNode.setAttribute("href", "mailto:" + theAddress);
			theAddressNode.appendChild(document.createTextNode(theAddress));
			theNode.parentNode.replaceChild(theAddressNode, theNode);
			i--; /*because we implicitly removed a <span> from the spans array by making it an <a>; Otherwise it'll skip the next span*/
			}
		}
	}
	
/* calendar */
var calendarIcon=getroot()+'js/cal.gif';
var calendarClose=getroot()+'js/close.png';
/* **************************************
start datepicker
************************************** */
//adds a datepicker next to inputfields with the 'date' class.
function makeCalendar()	{
	dateFields = getElementsByClassName('input','date');
	for(i=0;i<dateFields.length;i++)
		{
		img = document.createElement("img");
		img.setAttribute("src",calendarIcon);
		img.setAttribute("alt","[+]");
		img.setAttribute("class","cal");
		img.onclick = function(){setDate(this);};
		img.style.cursor = "pointer";
		img.style.marginLeft = "5px";
		dateFields[i].parentNode.insertBefore(img,dateFields[i].nextSibling);
		}
	}
function setDate(e)	{
	var today = new Date();
	var month = today.getMonth() + 1;
	var day = today.getDate();
	var year = today.getFullYear();
	if(parseDate(e.previousSibling.value)){
		var existingdate = parseDate(e.previousSibling.value);
		month = existingdate[1];
		year = existingdate[0];
		}
	createDatePicker(e,month,year);
	//e.previousSibling.value=year+"-"+month+"-"+day;
	}
function createDatePicker(e,month,year)	{
	if(document.getElementById('datepicker'))
		{
		var fucker=document.getElementById('datepicker');
		fucker.parentNode.removeChild(fucker);
		}
	var calendar=document.createElement("div");
	/*calendar.style.position='absolute';*/
	/*calendar.style.display='inline';*/
	/*calendar.style.border='1px solid #999';*/
	calendar.setAttribute('id','datepicker');
	/*calendar.style.background='#fff';*/
	calendar.innerHTML=calendarString(month,year);
	
	
	var fucker=document.getElementById('datepicker');
	e.parentNode.insertBefore(calendar,e.nextSibling);
}
function parseDate(datestring){
	if(datestring.indexOf('-')>0 && datestring.split('-')[0]>0){
		return datestring.split('-');
		}else{
		return false;
		}
	}
function calendarString(month,year)	{
	string='<table id="calendartable">';
	string+='<tr id="header"><td colspan="7" class="close"><img src="'+calendarClose+'" alt="click to close" onclick="closeCalendar();" /></td></tr>';
	string+='<tr>';
	string+='<td class="pickerday" onclick="changeMonth('+year+','+month+',\'prev\');return false;"><a href="#">&lt;&lt;</a></td>';
	string+='<td colspan="5" style="text-align: center;">';
	string+='<select name="month" style="width:auto;clear: none;float: none;font-size:10px;" onchange="changeMonth('+year+',this.value);">';
	for(var i=1;i<=12;i++)
		{
		string+='<option value="'+i+'"'+(month==i?' selected="selected"':null)+'>'+monthName(i)+'</option>';
		}
	string+='</select>';
	string+='<select name="year" style="width:auto;clear: none;float: none;font-size:10px;" onchange="changeMonth(this.value,'+month+');">';
	for(var i=2000;i<=2020;i++)
		{
		string+='<option value="'+i+'"'+(year==i?' selected="selected"':null)+'>'+i+'</option>';
		}
	string+='</select>';
	//string+=monthName(month);
	//string+=' '+year;
	string+='</td>';
	string+='<td class="pickerday" onclick="changeMonth('+year+','+month+',\'next\');return false;"><a href="#">&gt;&gt;</a></td>';
	string+='</tr>';
	string+='<tr>';
	string+='<td class="pickerweekday">M</td>';
	string+='<td class="pickerweekday">T</td>';
	string+='<td class="pickerweekday">W</td>';
	string+='<td class="pickerweekday">T</td>';
	string+='<td class="pickerweekday">F</td>';
	string+='<td class="pickerweekday">S</td>';
	string+='<td class="pickerweekday">S</td>';
	string+='</tr>';
	string+='<tr>';
	//calculate first weekday of the month
	var firstDayOfMonth = new Date(year,month-1,1);
	var LastDayOfMonth=daysInMonth(month,year);
	offset=(((firstDayOfMonth.getDay()+7)-1)%7);
	//draw table
	for(i=0;i<offset;i++)
		{
		string+='<td></td>';
		}
	for(i=0;i<LastDayOfMonth;i++)
		{
		if((i+offset)%7==0)	{
		string+='</tr>';	
		string+='<tr>';	
			} 
		string+='<td class="pickerday" onclick="writeDate('+year+','+month+','+(i+1)+');return false;"><a href="#">'+(i+1)+'</a></td>';
		}
	string+='</tr>';
	string+='</table>';
	return string;
	}
function monthName(monthNum)	{
	var months = new Array('january','february','march','april','may','june','july','august','september','october','november','december');
	return months[monthNum-1];
	}
// http://javascript.about.com/library/bllday.htm 
//gives the number of days in a given month. don't ask me how it works, but it does
function daysInMonth(month,year) {
	var dd = new Date(year, month, 0);
	return dd.getDate();
}
function writeDate(year,month,day)	{
	var calendar=document.getElementById('datepicker');
	if(month<10)
		{
		month='0'+month;
		}
	if(day<10)
		{
		day='0'+day;
		}
	calendar.previousSibling.previousSibling.value=year+'-'+month+'-'+day;
	closeCalendar();
	}
function changeMonth(year,month,direction)	{
	if(direction=='next')
		{
		if(month==12)	{
			month=1;
			year++;
			} else {
			month++;
			}
		} else if(direction=='prev')	{
		if(month==1)	{
			month=12;
			year--;
			} else {
			month--;
			}
		}
	var calendar=document.getElementById('datepicker');
	calendar.innerHTML=calendarString(month,year);
	}
//closecalendar
function closeCalendar()	{
var calendar=document.getElementById('datepicker');
calendar.parentNode.removeChild(calendar);
}	
/*stop calendar*/

/* ************************************************************************************************
ask confirmation before submitting a form (<form class="confirm" title="are you sure you want to drop this database?">)
************************************************************************************************ */
function askConfirmation()
	{
	confirmations = getElementsByClassName('form','confirm');
	for(i=0;i<confirmations.length;i++)
		{
		//inventing new attributes
		confirmations[i].setAttribute('confirm',confirmations[i].title);
		confirmations[i].title="";
		confirmations[i].onsubmit = function(){return window.confirm(this.getAttribute('confirm'));};
		
		}
	}
	
/* *******************************************
add popup events when there's a class="popup{}" on a link
******************************************** */
function popups()	{
	var popuplinks = new Array;
	popuplinks = getElementsByClassName('a','popup');
	for(i=0;i<popuplinks.length;i++)
		{
		arr=getClassVariables(popuplinks[i],'popup');
		if(!isNaN(arr[0]*1)){width=arr[0]*1;}else{width=550;}
		if(!isNaN(arr[1]*1)){height=arr[1]*1;}else{height=450;}
		popuplinks[i].onclick=function(){ popup(this.href,width,height);return false;};
		}
	}
function popup(url,windowwidth,windowheight)	{
	window.open(url,'upload','width='+windowwidth+',height='+windowheight+',scrollbars=1');
	}
/* when you're a popup window, refresh stuff on parent window when loading */	
if(self.opener)
	{
	self.opener.flushXMLData?self.opener.flushXMLData():null;
	}
/* *************************************
xmlHTTPrequest section
************************************** */
//this one refreshes the <div> in question according to an url and a defined timeout
var timer = new Array;
function xmlRequests()	{
	xmldivs = getElementsByClassName('div','xmlget');
	for(i=0;i<xmldivs.length;i++){
		timer[i]=new Array;
		timer[i]['params']=getClassVariables(xmldivs[i],'xmlget');
		timer[i]['element']=xmldivs[i];
		//timer[i]['interval']=window.setInterval('getXMLText(timer['+i+'][\'params\'][0],timer['+i+'][\'element\']);',timer[i]['params'][1]*1000);
		window.setInterval('getXMLText(timer['+i+'][\'params\'][0],timer['+i+'][\'element\']);',timer[i]['params'][1]*1000);
		}
	}

//xmlHTTPRequest (because that's handy sometimes)
var xmlhttp=false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
// JScript gives us Conditional compilation, we can cope with old IE versions.
// and security blocked creation of the objects.
 try {
  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
 } catch (e) {
  try {
   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (E) {
   xmlhttp = false;
  }
 }
@end @*/
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
	try {
		xmlhttp = new XMLHttpRequest();
	} catch (e) {
		xmlhttp=false;
	}
}
function createNewRequestObject()
	{
	var requestObj=false;
	/*@cc_on @*/
	/*@if (@_jscript_version >= 5)
	// JScript gives us Conditional compilation, we can cope with old IE versions.
	// and security blocked creation of the objects.
	 try {
	  requestObj = new ActiveXObject("Msxml2.XMLHTTP");
	 } catch (e) {
	  try {
	  requestObj = new ActiveXObject("Microsoft.XMLHTTP");
	  } catch (E) {
	   requestObj = false;
	  }
	 }
	@end @*/
	if (!requestObj && typeof XMLHttpRequest!='undefined') {
		try {
			requestObj = new XMLHttpRequest();
		} catch (e) {
			requestObj=false;
		}
	}
	return requestObj;
	}
//this one just loads a page (without immediate feedback)
function xmlActions()	{
	var xmlactions = new Array;
	xmlactions = getElementsByClassName('a','xmldo');
	for(i=0;i<xmlactions.length;i++)
		{
		//var action=xmlactions[i].href;
		if(xmlactions[i].getAttribute('rel')=='confirm')
		{
		xmlactions[i].onclick=function(){
										this.blur();
										if(confirmIt(this))
											{
											XMLdo(this.href);
											}
										return false;};
		}else{
		xmlactions[i].onclick=function(){this.blur();XMLdo(this.href);return false;};
		}
		}
	}
	
function XMLdo(url)	{
	xmlhttp.open("HEAD", url,true);	
		xmlhttp.onreadystatechange=function() {
		if (xmlhttp.readyState==4) {
			//do nothing
			
				for(i=0;i<xmldivs.length;i++)
					{
					params=getClassVariables(xmldivs[i],'xmlget');
					param=params[0];
					xmldiv=xmldivs[i];
					getXMLText(param,xmldiv);
					}
			}
		}
	xmlhttp.send(null);
	}
/* ****************************************************************************************
keepSession: keeps session alive so you're not logged out when idling on the website (if you've enabled js)
***************************************************************************************** */
function keepSession()	{
	var session = setInterval(function (){
				XMLdo(getroot()+'xml/ping.lasso');
				},720000);
	}


/* **************************
PPK's awesome form maxlength script
*************************** */
function setMaxLength() {
	var x = document.getElementsByTagName('textarea');
	var counter = document.createElement('div');
	counter.className = 'counter';
	for (var i=0;i<x.length;i++) {
		if (x[i].className=='maxlength') {
			var counterClone = counter.cloneNode(true);
			counterClone.relatedElement = x[i];
			var maxLength = x[i].previousSibling.value;
			counterClone.innerHTML = '<span>0</span>/'+maxLength;
			x[i].parentNode.insertBefore(counterClone,x[i].nextSibling);
			x[i].relatedElement = counterClone.getElementsByTagName('span')[0];
			x[i].onkeyup = x[i].onchange = checkMaxLength;
			x[i].onkeyup();
		}
	
	}
}

function checkMaxLength() {
	var maxLength = this.previousSibling.value;
	var currentLength = this.value.length;
	if (currentLength > maxLength)
	{
		this.className = 'toomuch';
		this.value = this.value.substring(0,maxLength); 
		this.focus();
	}else{
		this.className = 'maxlength';
	this.relatedElement.firstChild.nodeValue = currentLength;
	}
	// not innerHTML
}

/* stop maxlength script */

/* ******************************
submits forms when the selectbox has a class of 'submitonchange'
also hides submit buttons with class of 'jshide'
****************************** */
function autoSubmit()	{
	var listboxes = new Array;
	var uselesssubmitbuttons = new Array;
	listboxes = getElementsByClassName('select','submitonchange');
	uselesssubmitbuttons = getElementsByClassName('input','jshide').concat(getElementsByClassName('button','jshide'));
	for(i=0;i<listboxes.length;i++)
		{
		listboxes[i].onchange=function(){ submitForm(this);};
		}
	for(i=0;i<uselesssubmitbuttons.length;i++)
		{
		//uselesssubmitbuttons[i].style.display='none';
		uselesssubmitbuttons[i].style.padding='0';
		uselesssubmitbuttons[i].style.border='none';
		uselesssubmitbuttons[i].style.width='0px';
		uselesssubmitbuttons[i].value='';
		}	
	}
function submitForm(e){
	e.parentNode.parentNode.submit();
	}


/* *******************************************
add live search on specific form elements (  like in http://www.google.com/webhp?complete=1 )
******************************************** */
function initLiveSearch()	{
	var searching;
	var livesearchinputs = new Array;
	livesearchinputs = getElementsByClassName('input','live');
	for(i=0;i<livesearchinputs.length;i++)
		{
		arr=getClassVariables(livesearchinputs[i],'livesearch');
		livesearchinputs[i].setAttribute('live',livesearchinputs[i].title);
		livesearchinputs[i].title="";
		livesearchinputs[i].onkeyup=function(){ liveSearch(this,this.value,this.getAttribute('live'),10);return false;};
		}
	}
var searching;
function liveSearch(e,query,url,height)	{
	if(searching)
		{
		clearTimeout(searching);
		}
	if(query=='')
		{
		removeElement('livesearch');
		} else	{
		if(!document.getElementById('livesearch'))
			{
				div = document.createElement("div");
				div.setAttribute("id","livesearch");
				div.style.left=findPos(e)[0]-findPos($('txtcontainer'))[0]+'px';
				/*calculate new top */
				var newtop = findPos(e)[1]-findPos($('txtcontainer'))[1]; /* exact position of the input field */
				newtop += e.offsetHeight; /* add the height of the input field */
				div.style.top=newtop+'px';
				e.parentNode.insertBefore(div,e);
				//document.body.onclick(function(){this.style.background='#fff'});
				addEvent(document.body, 'click', function(event) {
					//console.log('clicked');
					removeElement('livesearch');
					});

			} else	{
				div=e.previousSibling;
			}
		//div.innerHTML="livesearch: "+query;
		var xmlquery = url+'?query='+query;
		searching = setTimeout('getXMLText(\''+xmlquery+'\',div)',500);
		}
	}




addLoadEvent(upstart);
/* stuff used by various functions */
/* getting sick of typing "document.getElementById' all the time (I also keep screwing up the caps).*/
function $(id)	{
	return document.getElementById(id);
	}
//inArray function, always useful...
Array.prototype.inArray = function (value) {
	var i;
	for (i=0; i < this.length; i++) {
		if (this[i] == value) {
			return true;
		//this checks if an array in an array	is the same as the array passed
		}
	}
	return false;
};
// addLoadEvent()
// Adds event to window.onload without overwriting currently assigned onload functions.
// Function found at Simon Willison's weblog - http://simon.incutio.com/
function addLoadEvent(func)
{	
	var oldonload = window.onload;
	if (typeof window.onload != 'function'){
    	window.onload = func;
	} else {
		window.onload = function(){
		oldonload();
		func();
		}
	}

}
function addEvent(obj, evType, fn){ 
 if (obj.addEventListener){ 
   obj.addEventListener(evType, fn, false); 
   return true; 
 } else if (obj.attachEvent){ 
   var r = obj.attachEvent("on"+evType, fn); 
   return r; 
 } else { 
   return false; 
 } 
}


/* ppk's findpos script */
function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
	return [curleft,curtop];
}


//function removeElement: removes the element with the id passed, if it exists (saves me from typing)
function removeElement(id)	{
	if(document.getElementById(id))	{
			document.getElementById(id).parentNode.removeChild(document.getElementById(id));
			}
	}

//as long as browsers don't support getElementsByClassName, let's just write our own!
//extra functionality browsers won't support ever: 
//-values can be added by appending them in brackets. example: required(*@*.*),, popup(500,400), ...
function getElementsByClassName(tag, classname)	{
	var xyzzy=document.getElementsByTagName(tag);
	var elements = new Array;
	var regulexp= new RegExp("(^|\\s)"+classname+"(\\s|$|\\(.*\\))");
	for(i=0;i<xyzzy.length;i++)
		{
		if(regulexp.test(xyzzy[i].className))
			{
			elements[elements.length]=xyzzy[i];
			}
		}
	return elements;
	}
function getClassVariables(e,classname)	{
	vars = new Array;
	varstring = e.className;
	//var regulexp= new RegExp("(^|\\s)"+classname+"(\\s|$|{.*})");
	var regulexp= new RegExp(classname+"\\((.*)\\)");
	varr=varstring.match(regulexp);
	if(varr!=null){
		varstring = varr[1];
		vars=varstring.split(',');
	}else{
		vars= new Array(NaN,NaN);
	}
	return vars;
	}
//gets the text from an url, and drops it into the innerHTML of the given element
function getXMLText(path,e)	{
		var request=createNewRequestObject();
		request.open("GET", getroot()+"xml/"+path+"&rnd="+Math.round(Math.random()*10000),true);
		request.onreadystatechange=function() {
		if (request.readyState==4) {
			var text = request.responseText;
			e.innerHTML=text;
			refresh();
			}
		}
		request.send(null);
	}

function flushXMLData()	{
	for(i=0;i<xmldivs.length;i++)
		{
		params=getClassVariables(xmldivs[i],'xmlget');
		param=params[0];
		xmldiv=xmldivs[i];
		getXMLText(param,xmldiv);
		}
	}

