/**
 * AJAX Framework
 * 
 * @copyright Copyright (c) 2009 by Dirk Tetenberg
 * @author Dirk Tetenberg <tetenberg@nexus-de.com>
 * @version 2.0
*/


/**
 * AjaxRequest Klasse
 * 
 * @param application Anwendung
 * @param methodname Methode
 * @return Request Objekt
 */
function AjaxRequest(application, methodname)
{
	/**
	 * Methode (POST oder GET)
	 * 
	 * @var string
	 * @access public
	 */
	this.method = "get";
	
	/**
	 * Legt fest, ob der Aufruf asynchron erfolgen soll
	 * 
	 * @var bool
	 * @access public
	 */
	this.async = true;
	
	// Params array
	this.params = new Array();
	
	// URL
	this.application = application;
	
	// Methodname
	this.methodName = methodname;
	
	// Response handler
	this.oncompleted = null;
	
	// Create the XMLHttpRequest object
	var request = null;
	if (typeof XMLHttpRequest != 'undefined') {
		request = new XMLHttpRequest();
	} else if (typeof ActiveXObject != 'undefined') {
		try {
			request = new ActiveXObject("MSXML2.XMLHHTP");
		} catch(e) {
			try {
				request = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {
				request = null;
			}
		}
	}
	if (request == null) throw "Browser does not support Ajax";
	
	this.request = request;
	this.request.ajaxRequest = this;
	
	this.execute = function()
	{
		// We need an application and a method name
		if (this.application == "" || this.methodName == "") throw "No application or method name";
		
		// Parameters
		var params = this.params;
		params.push(formatString("method={1}", this.methodName));
		var paramstr = params.join("&");
		
		// URL
		var url = formatString("/bin/{1}.json", this.application);
		if (this.method == "get") {
			url += "?" + paramstr;
			paramstr = null;
		}
		
		// Execute request
		this.request.open(this.method, url, this.async);
		this.request.onreadystatechange = function()
		{
			var ajaxRequest = this.ajaxRequest;
			switch (this.readyState) {
				case 1:
					ajaxRequest.requestLoading();
					break;
				case 2:
					// Loaded
					ajaxRequest.requestLoaded();
					break;
				case 3:
					// Interactive
					ajaxRequest.requestInteractive();
					break;
				case 4:
					// Completed
					if (this.status == 200) {
						ajaxRequest.requestCompleted();
					} else {
						throw this.responseText;
					}
					break;
			}
		}
		if (this.method == "post") this.request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		this.request.send(paramstr);
	}
	
	this.requestLoading = function()
	{
		// reserved for future versions
	}
	
	this.requestLoaded = function()
	{
		// reserved for future versions
	}
	
	this.requestInteractive = function()
	{
		// reserved for future versions
	}
	
	this.requestCompleted = function()
	{
		if (typeof this.oncompleted == "function") {
			var response = eval("(" + this.request.responseText + ")");
			this.oncompleted(response);
		}
	}
}

/**
* readyState uninitialized
*
* @var int
*/
var READYSTATE_UNINITIALIZED      = 0;

/**
* readyState loading
*
* @var int
*/
var READYSTATE_LOADING            = 1;

/**
* readyState loaded
*
* @var int
*/
var READYSTATE_LOADED             = 2;

/**
* readyState interactive
*
* @var int
*/
var READYSTATE_INTERACTIVE        = 3;

/**
* readyState completed
*
* @var int
*/
var READYSTATE_COMPLETED          = 4;

/**
* Request Methode GET
*
* @var string
*/
var METHOD_GET                     = "get";

/**
* Request Methode POST
*
* @var string
*/
var METHOD_POST                    = "post";

/**
* Globales XMLHttpRequest Objekt
*
* @var mixed
*/
var ajaxRequest;
var responseHandler;

/**
* Erstellt ein XMLHttpRequest oder �quivalentes Objekt
*
* @return mixed XMLHttpRequest Objekt oder null, wenn kein Objekt erzeugt
* werden konnte
*/
function createAjaxRequest()
{
	var result = null;

	if (typeof XMLHttpRequest != 'undefined') {
		result = new XMLHttpRequest();
	} else if (typeof ActiveXObject != 'undefined') {
		try {
			result = new ActiveXObject("MSXML2.XMLHHTP");
		} catch(e) {
			try {
				result = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {
				result = null;
			}
		}
	}

	return result;
}

/**
* Erstellt und versendet einen XMLHttpRequest
*
* @param string method Methode GET oder POST
* @param string url URL
* @param function handler Handler f�r onreadystatechange
* @param mixed params Array oder string mit Parametern, die Abh�ngig von der
* method an die URL angeh�ngt oder als Formularvariablen �bergeben werden.
* @param bool async Legt fest, ob die Anfrage asynchron ausgrf�hrt wird
*/
function sendAjaxRequest(method, url, handler, params, async)
{
	var paramstr;
	var urlstr = new String(url);

	if (typeof params == "object")	{
		paramstr = params.join("&");
	} else if (typeof params == "string") {
		paramstr = new String(params);
	}

	if (method == METHOD_GET) {
		if (params != "") urlstr += "?" + paramstr;
		paramstr = null;
	}

	if (typeof async != "boolean") async = true;

	ajaxRequest = createAjaxRequest();
	ajaxRequest.open(method, urlstr, async);
	ajaxRequest.onreadystatechange = handler;
	if (method == METHOD_POST) {
		ajaxRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	}
	ajaxRequest.send(paramstr);
}

/**
* Extrahiert das Response Objekt aus einem XMLHttpRequest
*
* @param object request XMLHttpRequest
* @return object
*/
function extractResponseObject(request)
{
	var responseText = "(" + request.responseText + ")";
	return eval(responseText);
}

function alertDebugmessage(response)
{
	if (typeof response == "object") {
		var deb = response.debugmessage;
		if (typeof deb == "string") {
			deb = unescape(deb);
			if (deb != "") alert(deb);
		}
	}
}

function ajaxRequestResponse()
{
	if (ajaxRequest.readyState == 4) {
		if (ajaxRequest.status == 200) {
			var response = eval("(" + ajaxRequest.responseText + ")");
			if (typeof responseHandler == "function") {
				responseHandler(response);
			}
		} else {
			//if (progressWindow) progressWindow.hide();
			alert("Server error " + ajaxRequest.status);
		}
	}
}

function executeAjaxRequest(method, url, handler, params, async)
{
	responseHandler = handler;
	sendAjaxRequest(method, url, ajaxRequestResponse, params, async);
}

