/*
.overrideMimeType('text/xml; charset=ISO-8859-1');
http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_a_1.html
*/

/*
	Objekt: Ajax
	Version 0.1.0
	
	Ein einfaches HTTPRequest Objekt, mit der eine AJAX Abfrage durchgeführt werden kann. 
	Es läßt immer nur eine Abfrage gleichzeitig zu.
	
	
*/
var Ajax = new function() {
	// Das xml_http Objekt
	function XMLHttp() {
		// readyState Callback Funktionen
		// http://www.w3.org/TR/2006/WD-XMLHttpRequest-20060405/#xmlhttprequest
		this.onbefore	=	// 0: 	The initial value.
		this.onopen 	= 	// 1: 	he open() method has been successfully called
		this.onrequest 	=	// 2: 	The UA successfully completed the request,
							//			but no data has yet been received.
		this.onheader 	=	// 3: 	Immediately before receiving the message body (if any). 
							// 		All HTTP headers have been received. 
		this.oncomplete	=	// 4: 	The data transfer has been completed.	
		this.onerror	=
		this.onchange 	= 
		function() {return false;}; // Dummyfunktion

		var obj =  // Das XMLHttp Objekt erzeugen
		window.XMLHttpRequest ?  new XMLHttpRequest() : 
		window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : null;

		if(!obj) throw('Kann kein XMLHttp Objekt erzeugen.');

		// Objekt ok.
	
		var self = this;
		var url;
		var idle = false;
		var status = '';
		var time;
		var param = {};
		
		// callback Funktion für den Request
		function ready() {
			var s = obj.readyState;
			
			if(obj.readyState > 3) status = '[' + obj.status + '] ' + obj.statusText;
			
			self.onchange(s);
			
			if(s == 0) self.onbefore(self);
			else if(s == 1) self.onopen(self);
			else if(s == 2) self.onrequest(self);
			else if(s == 3) self.onheader(self);
			else if(s == 4) {

				time = (new Date()) - time;
				var msg = '';

				switch(obj.status) {
					case 200 || 304:
						// erfolgreiche Übertragung.
						self.lastModified = new Date( self.header('Last-Modified') );
						self.contentType = self.header('Content-Type');
						self.oncomplete(self);
					break;
					
					case 403:
					msg = 'Zugriff verweigert. (' + url + ')';
					break;
					case 404  : 
					msg = 'Datei nicht gefunden. (' + url + ')';
					break;
					case 408  : 
					msg = 'Timeout. (' + url + ')';
					break;
					case 500: 
					msg = 'Server Fehler. (' + url + ')';
					break;
					default: 
					msg = 'Bei der Übertragung trat ein Fehler auf.' + url;
				}
				if(msg) return self.onerror(msg + ' (' + status + ')');
				idle = false;
				return true;
			}
		}
		// Parameter kodieren
		function p() {
			var tmp = [];
			for(var a in param) {
				tmp.push(encodeURIComponent(a) + '=' + encodeURIComponent(param[a]));
			}
			return tmp.join('&');
		}
		
		// open(url)
		this.open = function(u, method, type, charset) {
			
			if(!obj) return this.onerror('Kein XMLHttp Objekt');
			if(this.isIdle()) return this.onerror('Request ist in Bearbeitung');
			
			if(u) url = u;
			
			if(!url) throw('Keine URL');
			
			if(!method) method = 'POST';
			method = method.toUpperCase();
			if(method != 'GET' && method != 'POST') method = 'GET';
			
			type = ( 'text/' + (type ? type : 'xml') );
			charset = (charset ? charset : 'utf-8');

			obj.open(method, url + '?' + (method == 'GET' ? p() + '&' : '') + Math.random(),
			true);
			
			if (obj.overrideMimeType) {
				this.mimeType = 'text/' + type + '; charset=' + charset;
				obj.overrideMimeType(this.mimeType);
			} else if(typeof obj.setRequestHeader != 'undefined'){
				obj.setRequestHeader('Charset', charset);
			}

			if(method == 'POST') {
				obj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
				obj.setRequestHeader("Content-length", p().length);
				obj.setRequestHeader("Connection", "close");
			} else {
				obj.setRequestHeader('Content-Type', type);
			}

			idle = true;
			time = new Date();

			obj.onreadystatechange = ready;
			obj.send(method == 'POST' ? p(): null);
			
			return true;
		};
		
		this.header = function(name) {
			if(!obj) return null;
			if(!name) return obj.getAllResponseHeaders();
			return obj.getResponseHeader(name);
		};

		this.response = function(forceText) {
			var type = this.header('content-type');
			if(!forceText && type == 'application/xml') return  obj.responseXML;
			return obj.responseText;
		};
		
		this.status = function() { return status; };
		this.isIdle = function() { return idle; };
		this.time = function() { return time;};
		
		/*
			Methode: param()
			
			setzen, abfragen und löschen der zu übertragenden HTTP-Parameter.
			
			Parameter
			
			-			löscht alle Parameter
			object		kopiert das objekt in das Parameter Objekt, 
						vorhandene Werte werden überschrieben
			name, wert[, name, wert ...] setzen der jeweiligen Werte
			string		Gibt den aktuellen Wert des entsprechenden Parameters zurück
		*/
		this.param = function() {
			if(typeof arguments[0] == 'undefined') {param = {}; } // alle Parameter löschen
			else if(typeof arguments[0] == 'object') {
				var arg = arguments[0];
				for(var a in arg) param[a] = arg[a]; 
			} else if(arguments.length % 2 == 0){
				for(var i = 0; i < arguments.length; i += 2){
					param[arguments[i]] = arguments[i + 1];
				}
			} else {
				return param[arguments[0]];
			}
			return param;
		};

		this.size = function() {
			var size = self.header('Content-Length') ||  self.response().length;
			return typeof byteConvert != 'undefined' ? byteConvert(size, 0) : size;
		};
		
		this.abort = function() { obj.abort(); };
	} // XMLHttp-Objekt
	
	this.request = function() {
		return new XMLHttp();
	}
};

