var xmlreqs = new Array();
var xmlreqsTime = new Array();
var httpStatus = new Array();
var debugProcTime = false;
var dbproctime = false;
var dbtime = false;
var dbaction = false;
var dbpl = false;
var dbsms = false;

//creates and returns a cross browser xmlhttp object
function CXMLReq(freed) {
	this.freed = freed;
	this.xmlhttp = false;
	if (window.XMLHttpRequest) {
		this.xmlhttp = new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
}

function ajaxProcTime(mssinceepoch) {
		
	////////////
	//
	//debug info
	//
	//debugProcTime = mssinceepoch;
	//spandebugNum = document.getElementById("debugNum");
	//alert(mssinceepoch);
	//if (spandebugNum !== null) {
	//	removeChildren(spandebugNum);
	//	spandebugNum.appendChild(document.createTextNode(mssinceepoch));
	//}

	var l = xmlreqsTime.length;
	if (l>4) {
		xmlreqsTime.reverse();
		xmlreqsTime.pop();
		xmlreqsTime.reverse();
		var l = xmlreqsTime.length;
	}
	xmlreqsTime[l] = mssinceepoch;
}

function ajaxCalcAverage() {
	var xmreqsAverage = 100;
	var currentTime = new Date();
	var tst = 0;
	var l = xmlreqsTime.length;
	var ti = l;
	if (l>0) {
		for (i=0; i!=l; i++) {
			tst += xmlreqsTime[i];
		}
	}
	var l = xmlreqs.length;
	if (l>0) {
		for (var i=0; i<l; i++) {
			if (xmlreqs[i].freed == 0) {
				msbusy = currentTime.getTime() - xmlreqs[i].ts;
				if (msbusy>2000) {
					ti++;
					tst += msbusy;
				}
			}
		}
	}
	if (ti>0) {
		xmreqsAverage = Math.round(tst/ti);
	}
	if (xmreqsAverage>10000) {
		server_slow();
	} else {
		server_ok();
	}
}

function ajaxCall(url, params, method, forcecall) {
	ajaxCalcAverage();
	var pos = -1;
	var busy = 0;
	var currentTime = new Date();
	var l = xmlreqs.length;
	//alert('kiekeboe ' + l);
	for (var i=0; i<l; i++) {
		var x = xmlreqs[i].timeout-currentTime.getTime(); //this is to check whether the connection has served it's timeout
		if (xmlreqs[i].freed == 1 && x<0) {
			pos = i;
			//alert(i + " = pos");
		} else {
			busy++;
			//alert(i + " = busy");
		}
	}
	if (busy > 0 && forcecall != true) { //cancels call if a query currently waiting, unless force == true
		return false;
		//alert('no can do');
	} else if (pos == -1) { 
		pos = xmlreqs.length;
		//alert("pos wordt " + pos);
	}
	xmlreqs[pos] = new CXMLReq(1);
	
	//if (xmlreqs[pos].xmlhttp) {
	//	alert('gelukt');	
	//}
	
	//alert(xmlreqs.length);
	//if (xmlreqs[pos].xmlhttp) {
		
		currentTime = new Date();
		xmlreqs[pos].ts = currentTime.getTime();
		xmlreqs[pos].timeout = currentTime.getTime();
		xmlreqs[pos].freed = 0;
		
		
		
		
			////////////
			//
			//debug info
			//
			/*
			if (debugProcTime !== false) {
				params += "&debugProcTime=" + debugProcTime;
			}
			if (dbtime !== false) {
				params += "&dbtime=" + dbtime;
			}
			if (dbproctime !== false) {
				params += "&dbproctime=" + dbproctime;
			}
			if (dbaction !== false) {
				params += "&dbaction=" + dbaction;
			}
			if (dbpl !== false) {
				params += "&dbpl=" + dbpl;
			}
			if (dbsms !== false) {
				params += "&dbsms=" + dbsms;
			}
			*/
		
		
		
		
		if (method == 'post') {
			xmlreqs[pos].xmlhttp.open("POST",url,true);
			xmlreqs[pos].xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			xmlreqs[pos].xmlhttp.setRequestHeader("Content-length", params.length);
			//xmlreqs[pos].xmlhttp.setRequestHeader("Connection", "close");	
			//xmlreqs[pos].xmlhttp.setRequestHeader("Proxy-Connection", "close");
		} else {
			

			
			//var tempd = new Date();
			//var tempdms = tempd.getTime();
			//params += "&currentMs" + tempdms;
			
			xmlreqs[pos].xmlhttp.open("GET",url+"?"+params,true);
			//xmlreqs[pos].xmlhttp.setRequestHeader("Connection", "close");
			//xmlreqs[pos].xmlhttp.setRequestHeader("Pragma", "no-cache");
			//xmlreqs[pos].xmlhttp.setRequestHeader("Cache-Control", "no-cache");
			//xmlreqs[pos].xmlhttp.setRequestHeader("Proxy-Connection", "close");
		}
		xmlreqs[pos].xmlhttp.onreadystatechange = function() {
			if (typeof(xmlhttpChange) != 'undefined') { xmlhttpChange(pos); }
		}
		if (method == 'post') {
			xmlreqs[pos].xmlhttp.send(params);
		} else if (window.XMLHttpRequest) { //Mozilla/Safari/IE7+
			xmlreqs[pos].xmlhttp.send(null);
		} else if (window.ActiveXObject) { //IE6-
			xmlreqs[pos].xmlhttp.send();
		}
		return true;
		//aaMsg = new Array();
		//aaMsg['ID'] = '';
		//aaMsg['ts'] = currentTimestamp();
		//aaMsg['sender'] = member;
		//aaMsg['msg'] = params + " [" + xmreqsAverage + "]";
		//aaMsg['alert'] = 'n';
		//appendMsg(aaMsg);
		//scrollDown();
	//}
}

function xmlhttpChange(pos) {
	var currentTime = new Date();
	if (typeof(xmlreqs[pos]) != 'undefined' && xmlreqs[pos].freed == 0 && xmlreqs[pos].xmlhttp.readyState == 4) {
		try {
			if (xmlreqs[pos].xmlhttp.status !== undefined && xmlreqs[pos].xmlhttp.status != 0){
				httpStatus[pos] = xmlreqs[pos].xmlhttp.status;
			} else {
				httpStatus[pos] = 13030;
			}
		}
		catch(e){
			// 13030 is the custom code to indicate the condition -- in Mozilla/FF --
			// when the object's status and statusText properties are
			// unavailable, and a query attempt throws an exception.
			httpStatus[pos] = 13030;
		}
		if (httpStatus[pos] == 13030) {
			handle_error();
		} else if (xmlreqs[pos].xmlhttp.status == 200 || xmlreqs[pos].xmlhttp.status == 304) {
			handle_response(xmlreqs[pos].xmlhttp.responseXML);
		} else {
			handle_error();
		}
		xmlreqs[pos].freed = 1;
		xmlreqs[pos].xmlhttp = null;
		xmlreqs[pos].timeout = currentTime.getTime() + 700; //we wait a few miliseconds before making this connection available for a new call 
		ajaxProcTime(currentTime.getTime() - xmlreqs[pos].ts); //for calculating average
		httpStatus[pos] = false;	
	}
}

function handle_response(xml) {
	for(j = 0; j < xml.firstChild.childNodes.length; j++)	{
		pXml = xml.firstChild.childNodes[j];
		switch (pXml.nodeName) {
			case "friendList": //friend list update
				callbackFriendlist(pXml.getElementsByTagName("f"));
			break
			case "im": //instant message
				processIMessages(pXml.getElementsByTagName("m"));
			break
			case "getChat": //getChat response
				getChatCallback(pXml);
			break
			case "s": //system message
				aMsg = pXml.getElementsByTagName("m");
				IMsystemMsg(aMsg[0].childNodes[0].firstChild.data, aMsg[0].childNodes[1].firstChild.data, aMsg[0].childNodes[2].firstChild.data);
			break
			case "nm": //new mail
				callbackNewMail(pXml);	
			break
			case "nim": //new instant message
				callbackNewIM(pXml.getElementsByTagName("nims"));
			break
			//case "cr": //change of chat room
			//	changeRoom(pXml.firstChild.data);
			//break
			//case "pt": //new instant message
			//	dbproctime = pXml.firstChild.data;
			//break
			//case "dbaction": //debug: type ajaxcall dat was gedaan
			//	dbaction = pXml.firstChild.data;
			//break
			//case "currentTime": //debug: servertijd start php parse
			//	dbtime = pXml.firstChild.data;
			//break
			//case "pl": //debug: aantal processen bij begin php parse
			//	dbpl = pXml.firstChild.data;
			//break
			//case "sms": //debug: proctime per query
			//	dbsms = pXml.firstChild.data;
			//break
			
			case "dp":
				deletePhotoComplete(pXml.getElementsByTagName("photo"));
			break
			
			case "hp":
				hoofdPhotoComplete(pXml.getElementsByTagName("photo"));
			break
			
			case "ct":
				editBoxChangeComplete(pXml.getElementsByTagName("inputbox"));
			break
		}
	}
}

function hoofdPhotoComplete(hoofdObject){
	if(hoofdObject[0].childNodes[0].firstChild.data == "success"){
		makeWhite(hoofdObject[0].childNodes[1].firstChild.data + ".jpg");
	}
}

function deletePhotoComplete(deleteObject){
	if(deleteObject[0].childNodes[0].firstChild.data == "success"){
		fadeOut(deleteObject[0].childNodes[1].firstChild.data + ".jpg", 100);
	}
}

function editBoxChangeComplete(content){
	if(content[0].childNodes[0].firstChild.data == "success"){
		changeEditBoxNow(content[0].childNodes[1].firstChild.data);
	}
}
