/**
 * @author: Anatolij Rau
 * @copyright: Anatolij Rau
 * @access: 2010-07-14
 * @version: 2.3.3
 **/

function ajaxClass() {
	this.evalScripts = true; // Javascript innerhalb des Requests ausführen
	this.responseType = 'replace'; // Was soll mit dem ergebniss passieren (replace | append )
	this.method = 'GET'; // Request methode (GET | POST)
	this.charset = 'UTF-8';
	this.sychron = true;

	this.header = new Object();
	this.header['Accept-Charset'] = this.charset;
	this.header['Content-Type'] = 'text/html'; // Bei einem Post requst soll auf application/x-www-form-urlencoded gesetzt sein
	
	this.scriptDir = null;
	var nodes = document.getElementsByTagName("SCRIPT"), script_dir = null;
	for (var i = 0; i < nodes.length; i++) 
		if (nodes[i].src.indexOf("ajax.class") != -1) this.scriptDir = nodes[i].src.replace(/\\/g,'/').replace(/\/[^\/]*\/?$/, '')+'/';

	/** Requirements **/
	String.prototype.indexOf = function(match_str, search_start) {
			// wenn nichts mitgegeben wurde
			if (
				!match_str || !this ||
				match_str == 'undefined' || this == 'undefined' ||
				match_str == undefined || this == undefined ||
				match_str === null || this === null
			) return -1;

			// Wenn keine startposition mitgegeben wrude
			if (
				search_start == 'undefined' ||
				search_start === null ||
				search_start === false ||
				search_start == undefined
			) search_start = 0;

			var match = -1;
			var foundAt = this.substr(search_start).split(match_str);
			if (foundAt.length > 1) match = foundAt[0].length;
			if (match == -1) return match;
			else return match+search_start;
		};
	String.prototype.toId = function() {
		var r=0, c=0, h;
		while(c<this.length){
			h=this.charCodeAt(c++).toString(16);
			while(h.length<3) h="0"+h;
			if (parseFloat(h,16) >= 1) {
				if (r==0) r = parseFloat(h,16);
				r=r*parseFloat(h,16)*0.0001;
			} else r = r+parseFloat(h,16);
		}
		return r;
	};
	
	/**
	 * Load external url to a object
	 * @param {String} url if url is null or false relaod target object
	 * @param {String/Integer/Object/Function/null} targetObj html element or them id
	 */
	this.load = function(url, targetObj) {
		if (typeof targetObj == 'string' || typeof targetObj == 'number' ) {
			var tmp = false;
			// ignore strings
			if (targetObj != 'ibox' &&
			targetObj != 'iBox' &&
			targetObj != 'alert' &&
			(tmp = document.getElementById(targetObj))) {
				targetObj = tmp;
				if (url) targetObj.requestUri = url;
			}
		}
		
		// wenn es keine url mitgegeben ist schauen ob zielobjekt bereits
		// aufgerufen wurde und wenn ja wird es neu geladen
		if (!url && targetObj && targetObj.requestUri) 
			url = targetObj.requestUri;

		if (targetObj === null) targetObj = 'null';

		var xmlhttp;
		if (window.XMLHttpRequest) {
		  // IE7+, Firefox, Chrome, Opera, Safari
		  xmlhttp=new XMLHttpRequest();
	  }
		else {
			if (window.ActiveXObject) {
				try {
					xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
				 } catch (e) {
					try {
					   xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
					} catch (e) {
						alert("Browser does not support XMLHTTP!");
					}
				 }
			} else {
				alert("Browser does not support XMLHTTP!");
			}
		}
		
		
		var params = (url.indexOf('?') != -1) ? url.substring(url.indexOf('?')+1, url.length) : '';
		url = (url.indexOf('?') != -1) ? url.substring(0,url.indexOf('?')) : url;

		// Add timestamp Cache and IE Problem
		params += '&ajaxTS='+new Date().getTime();
		
		if (this.method == 'POST') {
			xmlhttp.open(this.method, url, this.sychron);
			this.header['Content-length'] = params.length;
			this.header['Connection'] =  'close';
		}
		else 
			xmlhttp.open(this.method, url+'?'+encodeURI(params), this.sychron);
		
		for (var i in this.header) xmlhttp.setRequestHeader(i, this.header[i]);
		
		xmlhttp.onreadystatechange = this.handleResult =(function(httpRequest, jxObj) {
			return function() { 
			// anfang
				if(httpRequest.readyState==4) {
					if (httpRequest.status == 404)
						alert('Target url not found "'+url+'"!');
					else {
						// Split script from HTML
						var resText = '';
						var resScript = '';
						var resScriptFiles = '';
						if (jxObj.evalScripts) {
							var s_data = ajaxObj.splitScript(httpRequest.responseText);
							resText = s_data.html;
							resScript = s_data.script;							
						} else resText = httpRequest.responseText;
						// Variable löschen damit die nicht so viel Platz nimmt
						delete httpRequest.responseText;
	
						if (typeof targetObj == 'string') {
							switch (targetObj) {
								case 'iBox':
								case 'ibox':
									iBoxObj.open(resText);
									break;
								case 'alert':
									alert(resText);
									break;
								case 'nothing':
								case 'null':
								case null:
									break;
							}
						}
						else if (typeof targetObj == 'function') {
							targetObj(resText);
						}
						else if (typeof targetObj === null) {
							return;
						}
						else {
							switch(jxObj.responseType) {
								case 'replace':
									targetObj.innerHTML = resText;
									break;
								case 'append':
									targetObj.innerHTML = targetObj.innerHTML+resText;
									break;
							}
							targetObj.innerHTML = resText ? resText : 'empty';
						}
						if (jxObj.evalScripts) {
							var sc = document.getElementsByTagName('script');
							var i = null;
							var id = '';
							var delEl = null;

							for (var key = 0; key < resScript.length; key++) {
								delEl = null;
								var script_element = document.createElement("script");
								script_element.type = "text/javascript";
								if (resScript[key].indexOf('URI:') === 0) {
									script_element.src = resScript[key].substring(4);
									id = 'ajaxObj_'+script_element.src.toId();
									if ((delEl = document.getElementById(id)))
										delEl.parentNode.removeChild(delEl);
									if (id) script_element.id = id;
								}
								else {
									script_element.text = resScript[key];
									id = 'ajaxObj_'+resScript[key].toId();
									if ((delEl = document.getElementById(id)))
										delEl.parentNode.removeChild(delEl);
									if (id) script_element.id = id;
								}
								var head = document.getElementsByTagName("head")[0];

								if (head) head.appendChild(script_element);
							}
						}
					}
				}
			// ende
			};
		})(xmlhttp, this);

		xmlhttp.send((this.method == 'POST')?encodeURI(params):null);
		
		if (!this.sychron) this.handleResult (xmlhttp, this);
		
		if(xmlhttp.readyState==4) return false;
		else return true;
	};
	
	/**
	 * Ständigen refresh ausführen
	 * @param {String} url
	 * @param {Mixed} targetObj
	 * @param {Integer} pause Wert in Millisekunden bis zum nächsten Ausführen.
	 **/
	this.autoRefrech = function(url, targetObj, pause) {
		if (!pause) pause = 300000; // 5 min
		window.setInterval((function(self_obj, url, targetObj) {
			return function() {
				self_obj.load(url, targetObj);
			};
		})(this, url, targetObj),pause);
	};
	
	/**
	 * Script aus html extrahieren
	 * @param {String} text_str
	 * @return {Object}
	 */
	this.splitScript = function(text_str) {
		this.scriptIndex = 0;

		if (!text_str) text_str = '';

		// in kleinbuchstaben umwandeln
		var lower_text_str = text_str.toLowerCase();
		
		var out = new Object();
		out['script'] = new Array();
		out['html'] = '';
		
		var sp = new Object();
		sp['st_begin'] = -1;
		sp['st_end'] = -1;
		sp['et_begin'] = -1;
		sp['et_end'] = -1;
		
		var ss_pos = 0; // Search start position
		var htmlStartPos = 0;
		
		while ((sp['st_begin'] = lower_text_str.indexOf('<script', ss_pos)) != -1) {
			ss_pos = sp['st_begin'];
			sp['st_end'] = lower_text_str.indexOf('>', ss_pos);

			if (sp['st_end'] != -1) {
				// Append script files
				var scriptTag = text_str.substring(ss_pos, sp['st_end']+1);
				if (scriptTag.toLowerCase().indexOf('src=') != -1) {
					var searchRes = scriptTag.match(/(^.*src[=]('|"))([^"']*\/)([^"']*)(.*)/i);
					out['script'][out['script'].length] = 'URI:'+searchRes[3]+searchRes[4];
				}

				ss_pos = sp['st_end'];
				sp['et_begin'] = lower_text_str.indexOf('</script', ss_pos);
				if (sp['et_begin'] != -1) {
					ss_pos = sp['et_begin'];
					sp['et_end'] = lower_text_str.indexOf('>', ss_pos);
					
					out['script'][out['script'].length] = text_str.substring(sp['st_end']+1, sp['et_begin']);
					out['html'] = out['html']+text_str.substring(htmlStartPos,sp['st_begin']);

					if (sp['et_end'] != -1) {
						ss_pos = sp['et_end'];
						htmlStartPos = ss_pos+1; 
					} else {
						alert(
							'JavaScript Endtag wurde an der Position '+sp['et_begin']+' gefunden!\n'+
							'Allerdings wurde der Script Tag nicht zugemacht! (</script...~)'
						);
					}
				} else {
					out['script'][out['script'].length] = text_str.substr(sp['st_end']+1);
					out['html'] = out['html']+text_str.substring(htmlStartPos,sp['st_begin']);
					htmlStartPos = text_str.length; 
				}
			} else {
				alert(
					'JavaScript Anfang wurde an der Position '+sp['st_begin']+' gefunden!\n'+
					'Allerdings wurde der Script Tag nicht zugemacht! (<script...~)'
				);
			}
		}
				
		if (out['html'].length < 1) out['html'] = text_str;
		return out;
	};

	/**
	 * Depricated: run Scripts
	 * @param {Object} container
	 */
	this.runRequestScripts = function(container) {
		var end = container.childNodes.length;
		for (var i = 0; i < end; i++ ) {
			if (container.childNodes[i].tagName == 'SCRIPT') {
				eval(container.childNodes[i].innerHTML);
			}
		}
	};

	/**
	 * Set request method
	 * @param {String} m GET or POST
	 */
	this.setMethod = function(m) {
		this.method = m;
		if (this.method == 'POST' || this.method == 'post') {
			this.method = 'POST';
			this.header['Content-type'] = 'application/x-www-form-urlencoded';
			this.header['Content-length'] = 0;// musst be set bevore send with "params.length";
			this.header['Connection'] = 'close';
		} else {
			this.header['Content-type'] = null;
			this.header['Content-length'] = null;
			this.header['Connection'] = null;
		}
	};
	
	this.setMethod(this.method);
}

var ajaxObj = new ajaxClass();
