/**
 * @modified 2007-06-14 
 */

if (!Atira) var Atira = {};

/**
 * @constructor
 */
Atira.Request = function() {
	this.delegate = null;
	this.options = {method:'GET',parameters:null};
}

/**
 * Sets the delegate
 * @param {Object} delegate The delegate to receive events
 *                          , { onSuccess: function(HttpXmlRequest), onFailure: function(HttpXmlRequest), onError: function(Atira.Request)}
 *                          , onFailure is called if respnse is not 200
 *                          , onError is called if the transport could'nt be created
 */
Atira.Request.prototype.setDelegate = function(delegate) {
	this.delegate = delegate;
}


/**
 * Sends a request
 * @param {string} url The url to request
 * @param {Object} delegate (optional) The delegate to receive events
 * @param {Object} options (optional) Optional parameters
 *                         , { method: ['POST' | 'GET'], parameters: {key1:value1, key2:value2, ...} }
 *                         , (the parameters are only for POST's)
 */
Atira.Request.prototype.request = function(url,delegate,options) {
	if (options) this.options=options;
	if (delegate) this.delegate=delegate;
	this.initTransport();
	var req = this.transport;
	var self = this;
	req.onreadystatechange = function() {
		if (req.readyState == 4) {
			if (req.status == 200) {
				self.callDelegate('onSuccess');
			} else {
				self.callDelegate('onFailure');
			}
		} else {
			// Not yet ready
		}
	};
	req.open(this.options.method, url, true);
	var parameters = null;
    if (this.options.method=='POST' && this.options.parameters) {
		parameters = this.buildPostBody(this.options.parameters);
		req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		req.setRequestHeader("Content-length", parameters.length);
		req.setRequestHeader("Connection", "close");
	}
	req.send(parameters);
}

/**
 * @private
 */
Atira.Request.prototype.buildPostBody = function(parameters) {
	var output = '';
	for (param in parameters) {
		if (output.length>0) output+='&';
		output+=encodeURIComponent(param)+'='+encodeURIComponent(parameters[param]);
	}
	return output;
}

/**
 * @private
 */
Atira.Request.prototype.callDelegate = function(event) {
	if (this.delegate) {
		if (event=='onSuccess' && this.delegate.onSuccess) {
			this.delegate.onSuccess(this.transport);
		}
		else if (event=='onFailure' && this.delegate.onFailure) {
			this.delegate.onFailure(this.transport);
		}
		else if (event=='onError' && this.delegate.onError) {
			this.delegate.onError(this);
		}
	}
}

/**
 * @private
 */
Atira.Request.prototype.initTransport = function() {
	this.transport = this.createXMLHttpRequest();
}

/**
 * @private
 */
Atira.Request.prototype.createXMLHttpRequest = function() {
	try {
		if (window.XMLHttpRequest) {
			var req = new XMLHttpRequest();
			
			// some versions of Moz do not support the readyState property
			// and the onreadystate event so we patch it!
			if (req.readyState == null) {
				req.readyState = 1;
				req.addEventListener("load", function () {
					req.readyState = 4;
					if (typeof req.onreadystatechange == "function")
						req.onreadystatechange();
				}, false);
			}
			return req;
		}
		else if (window.ActiveXObject) {
			return new ActiveXObject(this.getXmlHttpPrefix() + ".XmlHttp");
		} else {
			// Could not create transport
			this.callDelegate('onError');
		}
	}
	catch (ex) {
		// Could not create transport
		this.callDelegate('onError');
	}
}

/**
 * @private
 * @todo: return the obj istead of the prefix
 */
Atira.Request.prototype.getXmlHttpPrefix = function() {
	if (Atira.Request.prefix) {
		return Atira.Request.prefix;
	}
	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o;
	for (var i = 0; i < prefixes.length; i++) {
		try {
			// try to create the objects
			o = new ActiveXObject(prefixes[i] + ".XmlHttp");
			return Atira.Request.prefix = prefixes[i];
		}
		catch (ex) {};
	}
	
	throw new Error("Could not find an installed XML parser");
}
