/**
 * Ajax Transport Class
 * 
 *  Core handling of XMLHttpRequest requests.
 * @author Jared Armstrong
 * @version 0.1
 * @requires extension.js
 *
 * Example Usage:
 * --------------
 * new Ajax.Request("/test.php", {method: "get"}, function(response) { alert(response); });
 * new Ajax.Request("/post.php", {method: "post", vars: {"test": "value", "page": "testpage"}}, function(response, mime) {
 *    if (mime == "text/javascript") {
 *       eval(response);
 *    }
 * });
 */
var Ajax = {
	Request: Class.create(),
	getTransport: function () {
		return Try.these( (function(){ return new ActiveXObject("Msxml2.XMLHTTP"); }), (function(){ return new ActiveXObject("Microsoft.XMLHTTP"); }), (function(){ return new XMLHttpRequest(); }) );
	},
	makePostBody: function(v) {
		var q = ""; for (var i in v) { if (q!="")q+="&"; q+=escape(i)+'='+escape(v[i]); } return q;
	},
	Timestamp: function() { var d = new Date(); return d.getTime(); }
}

Ajax.Request.prototype = {
	url: null,
	transport: null,
	__construct: function(url, opts, callback) {
		this.url = url;
		this.transport = Ajax.getTransport();	
		this.transport.onreadystatechange = this.handleStateChange.bind(this);
		this.callback = callback;
		
		if (opts.method == 'GET' || opts.method == 'get') {
			this.get();
			return;	
		}		
		
		if (opts.vars) var vars = opts.vars; 
		else if (opts.variables) var vars = opts.variables;
		else var vars = {};
		
		this.post(vars);
	},
	post: function(vars) { 
		var postBody;
		if (typeof vars == 'object') {
			postBody = Ajax.makePostBody(vars);	
		}
		
		this.transport.open("POST", this.url, true);
		this.sendHeaders();
		this.transport.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		this.transport.send(postBody);			
		

	}	,
	get: function() { 		
		this.transport.open("GET", this.url, true);
		this.sendHeaders();
		this.transport.send(null);		
	},
	sendHeaders: function() { 
		this.transport.setRequestHeader('X-JSRequestedAt', Ajax.Timestamp());
		this.transport.setRequestHeader("X-RequestFrom", "javascript/ajax-call");					
	}, 
	handleStateChange: function() { 
		if (this.transport.readyState == 4) {
			// Prevent IE memory leak
			this.transport.onreadystatechange = function() { }
			if (this.transport.status == 200) {
				if (typeof this.callback == 'function') this.callback(this.transport.responseText, this.transport.getResponseHeader('content-type'));	
			}	
			delete(this.transport);
		}	
	}
}
