/**
* AjaxRequest Klasse
* Mit dieser Klasse lassen sich vereinfacht AjaxRequests ausführen.
* 
* Getested mit:
* Firefox 2/3
* Internet Explorer 5.5/6/7/8 Beta 2
* Opera 9.52
* Safari 3.1.2
* 
* @author Bauer
* @version 1.0
* 
* @param	options		Mögliche Optionen:
* 							method		GET/POST
*							url			An diese URL wird der Request gesendet
*							params		Diese Parameter werden mit dem Request mitgesendet
*							async		true/false
*							timeout		in ms, Wenn nach dieser Zeit keine Antwort kam wird der Request abgebrochen
*							beforeSend	Callback-Funktion: beforeSend
*							onerror		Callback-Funktion: onError
*							onsuccess	Callback-Funktion: onSuccess
*/
function AjaxRequest(options) {
	var self = this;
	var xmlHttpRequest = null;
	var timer = null;
	
	var timeout = null;
	var beforeSendCallback = null;
	var onErrorCallback = null;
	var onSuccessCallback = null;
	
	/**
	* Konstruktor
	*/
	this.constructor = function(options) {
		if(typeof options.method == "undefined") options.method = "GET";
		if(typeof options.url == "undefined") options.url = location.href;
		if(typeof options.params == "undefined") options.params = null;
		if(typeof options.async == "undefined") options.async = true;
		if(typeof options.timeout == "undefined") options.timeout = null;
		if(typeof options.beforeSend == "undefined") options.beforeSend = null;
		if(typeof options.onerror == "undefined") options.onerror = null;
		if(typeof options.onsuccess == "undefined") options.onsuccess = null;
		
		this.timeout = options.timeout;
		this.beforeSendCallback = options.beforeSend;
		this.onErrorCallback = options.onerror;
		this.onSuccessCallback = options.onsuccess;
		
		this.sendRequest(options.method, options.url, options.params, options.async);
	}
	
	/**
	* Sendet den Request
	* 
	* @param	method
	* @param	url
	* @param	params
	* @param	async
	*/
	this.sendRequest = function(method, url, params, async) {
		if(this.openXMLHttpRequest()) {
			this.xmlHttpRequest.onreadystatechange = this.handleResponse;
			
			if(method == "GET") {
				this.xmlHttpRequest.open(method, url + "?" + params, async);
				this.beforeSend();
				this.xmlHttpRequest.send(null);
				return true;
			} else if(method == "POST") {
				this.xmlHttpRequest.open(method, url, async);
				this.xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				this.beforeSend();
				this.xmlHttpRequest.send(params);
				return true;
			} else {
				alert("Unknown method!");
				return false;
			}
		}
		return false;
	}
	
	/**
	* Erstellt das XMLHttpRequest Objekt
	*/
	this.openXMLHttpRequest = function() {
		try {
			// Mozilla, Opera und Safari
			this.xmlHttpRequest = new XMLHttpRequest();
		} catch(e) {
			// Internet Explorer
			try {
				this.xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
			} catch(e) {
				try {
					this.xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
				} catch(e) {
					alert("Your browser does not support AJAX!");
					return false;
				}
			}
		}
		
		return true;
	}
	
	/**
	* OnReadyStateChange Funktion
	*/
	this.handleResponse = function() {
		try {
			if(self.xmlHttpRequest.readyState == 1) {
				if(self.timeout != null && self.timer == null) {
					self.timer = window.setTimeout(function() {
						self.xmlHttpRequest.onreadystatechange = function(){};
						self.xmlHttpRequest.abort();
						self.xmlHtppRequest = false;
						self.onError(408, "Request Time-out");
					}, self.timeout);
				}
			}
			
			if(self.xmlHttpRequest.readyState == 4) {
				window.clearTimeout(self.timer);
				
				if(self.xmlHttpRequest.status == 200) {
					// Alles OK
					self.onSuccess(self.xmlHttpRequest.responseText, self.xmlHttpRequest.status, self.xmlHttpRequest.statusText);
				} else if(self.xmlHttpRequest.status != 0) {
					// Es ist ein Fehler aufgetreten
					self.onError(self.xmlHttpRequest.status, self.xmlHttpRequest.statusText);
				}
			}
		} catch(e) {
			alert("Unknown Error:\n" + e);
		}
	}
	
	/**
	* Wird ausgeführt bevor der Request gesendet wird
	*/
	this.beforeSend = function() {
		if(typeof this.beforeSendCallback == "function") {
			this.beforeSendCallback();
		}
	}
	
	/**
	* Wird ausgeführt wenn ein Error auftritt
	*/
	this.onError = function(status, statusText) {
		if(typeof this.onErrorCallback == "function") {
			this.onErrorCallback(status, statusText);
		}
	}
	
	/**
	* Wird ausgeführt wenn der Request erfolgreich war
	*/
	this.onSuccess = function(responseText, status, statusText) {
		if(typeof this.onSuccessCallback == "function") {
			this.onSuccessCallback(responseText, status, statusText);
		}
	}
	
	// Konstruktor Aufruf
	this.constructor(options);
} 

