/**
* functions for processing of ajax-requests
* this functions can either do a get or post request with or without submission of a form oder do a post request with wddx-packet as payload
*
* if a form is submittet, every variable will have the same name as the corresponding form field
* if there are multiple fields with the same name, the will be sent seperately
* the submitted variable of a wddx request will be named "wddxPacket"
*
* the response can either be processed by built in default functions or by customized callback functions
*
* the default function for processing a response expects the response to be valid XML with a root-node named "root" and only one level of childs.
* each childs content will replace the HTML in a element with the same id as the nodes name
* the response node <js></js> will be evaluated as JavaScript after replacing the elements
*
* a customized callback function will get the complete requester object with the attributes responseXML and responseText
*/




/**
* send GET request
* param url: url to get, must be on the same domain
* param options.form (optional): document.forms object to send
* param options.callbackResponse (optional): callback funktion for response processing
* param options.callbackError (optional): callback function for error processing
* return void
*/
getPage = function (url, options) {
	cons.push (new AjaxCon (url, options));
	cons[cons.length - 1].get ();
}


/**
* send POST request
* param url: url to post, must be on the same domain
* param options.form: document.forms object to send
* param options.callbackResponse (optional): callback funktion for response processing
* param options.callbackError (optional): callback function for error processing
* return boolean false
*/
postPage = function (url, options) {
	cons.push (new AjaxCon (url, options));
	cons[cons.length - 1].post ();
	return false;
}

postForm = function (url, options) {
	options.element = "formoverlaycontent";
	return postPage (url, options);
}


/**
* send POST request with a WDDX payload
* param url: url to get, must be on the same domain
* param options.form: document.forms object to send
* param options.payload: array to send. each level of the array might be either a numerical array or an object with attributes
* param options.callbackResponse (optional): callback funktion for response processing
* param options.callbackError (optional): callback function for error processing
* return boolean false
*/
postWddx = function (url, options) {
	cons.push (new AjaxCon (url, options));
	cons[cons.length - 1].wddx ();
	return false;
}


processLinks = function () {
	var links = document.getElementsByTagName ("a");
	var regex = new RegExp ("^" + baseurl);
	for (var i = 0; i < links.length; i++) {
		if (regex.exec (links[i].href) != null && links[i].href.search (/\.rss$/) == -1 && !$(links[i]).hasClassName ("file") && !$(links[i]).href.match (/&meta=true/)) {
			if (navigator.isIE ()) links[i].href = "javascript:getPage ('" + decodeURIComponent (links[i].href) + "');";
			else {
				//links[i].onclick = function () { getPage (decodeURIComponent (this.href)); return false; }
				//links[i].onclick = function () { document.location.href = this.href + "&meta=true"; return false; }
				links[i].href+= "&meta=true";
				links[i].target = "historyframe";
			}
		}
	}
}


/**
* connection object - don't use directly
*/
AjaxCon = Class.create ();
AjaxCon.prototype = {
	/**
	* initialize httprequest object
	* return void
	*/
	initialize: function (url, options) {
		this.url = url + "&xml=true&cachedate=" + new Date ().getTime ();
		if (options != undefined) this.options = options;
		else this.options = {};

		if (this.options.callbackResponse != undefined) this.processResponse = this.options.callbackResponse;
		else this.processResponse = this.stdProcessResponse;
		if (this.options.callbackError != undefined) this.processError = this.options.callbackError;
		else this.processError = this.stdProcessError;

		try {
			this.requester = new XMLHttpRequest ();
		} catch (error) {
			this.requester = new ActiveXObject('Msxml2.XMLHTTP');
		}
		this.requester.onreadystatechange = this.onReadyStateChange;
	},


	/**
	* send get request
	* return void
	*/
	get: function () {
		if (this.options.form != undefined) {
			var elements = this.getElements (this.options.form);
			for (var i = 0; i < elements.length; i++) {
				this.url+= "&" + elements[i].name + "=" + elements[i].value;
			}
		}
		if (this.url.indexOf ("&") > -1) {
			this.url = this.url.substring (0, this.url.indexOf ("&")) + "?" + this.url.substring (this.url.indexOf ("&") + 1);
		}
		this.requester.open ("GET", this.url, true);
		this.requester.send (null);
		this.displayLoading ();
	},


	/**
	* send post request
	* return void
	*/
	post: function () {
		var strData = "";
		if (this.options.form != undefined) {
			var elements = this.getElements (this.options.form);
			for (var i = 0; i < elements.length; i++) {
				if (!i) strData+= elements[i].name + "=" + elements[i].value;
				else strData+= "&" + elements[i].name + "=" + elements[i].value;
			}
		}
		//alert (url+"\n"+ decodeURIComponent (strData));
		if (this.url.indexOf ("&") > -1) {
			this.url = this.url.substring (0, this.url.indexOf ("&")) + "?" + this.url.substring (this.url.indexOf ("&") + 1);
		}
		this.requester.open ("POST", this.url, true);
		this.requester.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
		this.requester.setRequestHeader ("Content-length", strData.length);
		this.requester.send (strData);
		this.displayLoading ();
	},


	/**
	* get element of a document.forms object as array
	* multiple elements with same name are allowed
	* param form: document.forms object
	* return array
	*/
	getElements: function (form) {
		var elements = new Array ();
		for (var i = 0; i < form.elements.length; i++) {
			if (form.elements[i].type == "hidden"
					|| form.elements[i].type == "text"
					|| form.elements[i].type == "password"
					|| form.elements[i].type == "textarea"
					|| form.elements[i].type == "select-one"
					|| form.elements[i].type == "select-multiple"
					|| form.elements[i].type == "radio" && form.elements[i].checked
					|| form.elements[i].type == "checkbox" && form.elements[i].checked) {
				var newElement = new Object ();
				newElement.name = form.elements[i].name;
				newElement.value = encodeURIComponent (form.elements[i].value);
				elements.push (newElement);
			}
		}
		return elements;
	},


	/**
	* get wddx packet of an array
	* each level of the payload array might be either a numerical array or an object with attributes
	* param payload: array to convert
	* return string
	*/
	getWddx: function (payload) {
		var wddxObj = new WddxSerializer ();
		wddxPacket = wddxObj.serialize (payload);
		return wddxPacket;
	},


	/**
	* callback function for readystatechange of a httprequest object
	* return void
	*/
	onReadyStateChange: function () {
		for (var i = 0; i < cons.length; i++) {
			if (cons[i].requester.readyState == 4) {
				con = cons[i];
				cons.splice (i, 1);
				i--;

				con.processResponse (con.requester, con.url);
			}
		}
	},


	/**
	* default callback function for error processing
	* param requester: httprequest object with response
	* return void
	*/
	stdProcessError: function (requester, url) {
		alert ("Error in ajax-request for " + url  + ": " + requester.status + " " + requester.statusText + "\n\n" . requester.responseText);
	},


	/**
	* default callback function for response processing
	* the requester must have valid response XML with a root-node named "root" with only one level of childs
	* data in the childs must not have line breaks, these should be replaced by the plain text "\n"
	* each child-nodes data (besides <js></js>) will be used as innerHTML for an element with an id corresponding to the childs name
	* the content of the child <js></js> (if present) will be evaluated as javascript
	* param requester: httprequest object with response
	* return void
	*/
	stdProcessResponse: function (requester, url) {
		if (requester.responseXML != undefined && requester.responseXML != null) {
			if (requester.responseXML.childNodes.length) {
				node_root = requester.responseXML.getElementsByTagName ("root");
				node_root = node_root[0];

				if (node_root != undefined) {
					var formoverlay = false;
					var ctext = false;
					for (i = 0; i < node_root.childNodes.length; i++) {
						node_child = node_root.childNodes[i];
						if (node_child.nodeType != 3 && node_child.nodeName != "js") {
							if (document.getElementById (node_child.nodeName)) {
								if (node_child.firstChild) {
									tmpelement = node_child.firstChild;
									innerHTML = tmpelement.data.replace (/\\n/g, "\n");
									while (tmpelement.nextSibling) {
										tmpelement = tmpelement.nextSibling;
										innerHTML+= tmpelement.data.replace (/\\n/g, "\n");
									}
									$(node_child.nodeName).innerHTML = innerHTML;
									if (node_child.nodeName == "form") {
										formoverlay = true;
									}
									if (node_child.nodeName == "ctext") {
										ctext = true;
									}
								} else $(node_child.nodeName).innerHTML = "";
							}
						}
					}
					processLinks ();
					if ($("formoverlay2")) hideform2 ();
					if ($("formoverlay") && !formoverlay && !url.match (/keepform=/)) hideform ();
					if ($("formoverlay") && formoverlay) resizeform ();
					if ($("ctext") && ctext && !url.match (/reload=true/)) this.scrollToTop ();
					this.hideLoading ();
					js = requester.responseXML.getElementsByTagName ("js");
					if (js[0] && js[0].firstChild) {
						eval (js[0].firstChild.data.replace (/\\n/g, "\n"));
					}
				} else {
					if ($("formoverlay")) $("form").innerHTML = requester.responseText;
					else $("ctext").innerHTML = requester.responseText;
					this.hideLoading ();
				}
			} else {
				if ($("formoverlay")) $("form").innerHTML = requester.responseText;
				else $("ctext").innerHTML = requester.responseText;
				this.hideLoading ();
			}
		} else {
			if ($("formoverlay")) $("form").innerHTML = requester.responseText;
			else $("ctext").innerHTML = requester.responseText;
			this.hideLoading ();
		}
	},


	displayLoading: function () {
		if (this.options.element == undefined) var element = "contentarea";
		else var element = this.options.element;

		if (element == "none") return;

		if (element == "contentarea") {
			var childs = $("contentarea2").immediateDescendants ();
			var childHeight = 0;
			for (var i = 0; i < childs.length; i++) {
				if ($(childs[i]).getOuterHeight () > childHeight) childHeight = $(childs[i]).getOuterHeight ();
			}
			$("contentarea2").setInnerHeight (childHeight);
		}

		var divnode = document.createElement ("div");
		$(divnode).setid ("loadingshade" + element).addClassName ("loadingshade");
		if (element == "header" || element == "contentarea") {
			$(divnode).setPosition ($(element).getPagePosition ());
		} else {
			var tmppos = $(element).getPagePosition ();
			tmppos[1] = tmppos[1] - $("contentarea").scrollTop;
			$(divnode).setPosition (tmppos);
		}
		$(divnode).setOuterWidth ($(element).getOuterWidth ());
		$(divnode).setOuterHeight ($(element).getOuterHeight ());
		$("body").appendChild (divnode);

		//if (navigator.isMoz ()) {
			var imgnode = document.createElement ("img");
			$(imgnode).setid ("loadingimg" + element).className = "loadingimg";
			$(imgnode).src = "static/images/ajax-loader.gif";
			$(imgnode).style.visibility = "hidden";
			$("body").appendChild (imgnode);
			var pos = $(element).getPagePosition ();
			if (element == "header" || element == "contentarea") {
				var x = (pos[0] + $(element).getWidth () / 2 - 32 / 2);
				var y = (pos[1] + $(element).getHeight () / 2 - 32 / 2);
			} else {
				var x = (pos[0] + $(element).getWidth () / 2 - 32 / 2);
				var y = (pos[1] - $("contentarea").scrollTop + $(element).getHeight () / 2 - 32 / 2);
			}
			$(imgnode).setPosition ([x, y]);
			$(imgnode).style.visibility = "visible";
		//}
	},


	writeLoading: function (text) {
		if (this.options.element == undefined) var element = "contentarea";
		else var element = this.options.element;

		$("loadingshade" + element).innerHTML+= text;
		$("loadingshade" + element).scrollTop = 1000000;
	},


	hideLoading: function () {
		if (this.options.element == undefined) var element = "contentarea";
		else var element = this.options.element;

		if (element == "none") return;

		//if (navigator.isMoz ()) {
			$("loadingimg" + element).remove ();
		//}
		$("loadingshade" + element).remove ();
	},


	scrollToTop: function () {
		window.setTimeout ("$('contentarea').scrollToTop ();", 10);
		window.setTimeout ("$('contentarea2').setStyle ({ height: 'auto' });", scroller.durationMax);
	}
}
// array holding every AjaxCon object with its requester
cons = new Array ();

