/*

	qGet
	
	Quick-Get

*/
var qGet = new (function() {
	// This is what we tell the destination URL we are calling as
	// so it can know it's being called from within a web page
	// and output accordingly
	var defHeaders = {'X-Requested-Via' : 'XmlHttp'};
	
	// Different strokes for different folks
	// Know what I mean?
	// Just make sure we return SOMETHING that strokes
	function getRequest() {
		var requestors = [function() { return new ActiveXObject("MSXML2.XMLHTTP"); },function() { return new ActiveXObject("Microsoft.XMLHTTP"); },function() { return new XMLHttpRequest(); }];
		for (var i = 0; i < requestors.length; i++) try {return requestors[i]();} catch (e) { };
		return null;
	}
	
	// make a clone of an object
	function enclone(orig, def) {
		var clone = new Object();
		if (def) clone = enclone(def);	// clone the default object, if it exists
		for (var c in orig) clone[c] = orig[c];
		return clone;
	}
	
	function onReadyStateChange(options) {
		if (this.readyState == 4) {
			var stat;
			try {stat = this.status.toString();} catch (e) {stat = "";}
			if (stat.substr(0, 1) == "2") {
				if (options.id) document.getElementById(options.id).innerHTML = this.responseText;
				var contentType = this.getResponseHeader("Content-Type");
				if (/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i.test(contentType)) eval(this.responseText);
				if (options.onSuccess) {options.onSuccess(this, this.responseText);}
			} else {
				if (options.onFailure) options.onFailure(this, this.responseText);
			}
			if (options.onComplete) {options.onComplete(this, this.responseText);}
		}
	}
	
	function qget(method, url, headers, data, async, onReadyStateChange, options, username, password) {
		var req = getRequest();
		if (req) {
			if (method == "GET" && data) url = url.indexOf("?") == -1 ? url + "?" + data : url.substr(0, url.indexOf("?")) + "?" + data;
			req.open(method, url, async, username, password);
			if (headers) for (var h in headers) req.setRequestHeader(h, headers[h]);
			if (onReadyStateChange) req.onreadystatechange = function() { onReadyStateChange.apply(req, [options]); };
			req.send(method == "POST" ? data : "");
			if (!async && req.overrideMimeType && onReadyStateChange) onReadyStateChange.apply(req, [options]);
			return false;
		}
		
		return true; // tell the link to forget about the onclick and just href
	}
	
	this.request = function(url, options) {
		var method = options && options.method == "POST" ? "POST" : "GET";
		var headers = options && options.headers ? enclone(options.headers, defHeaders) : defHeaders;
		var data = options && options.data ? options.data : "";
		var async = options && options.async == false ? false : true;
		var username = options && options.username ? options.username : undefined;
		var password = options && options.password ? options.password : undefined;
		return qget(method, url, headers, data, async, onReadyStateChange, options || {}, username, password);
	};
	
	this.submit = function(form, options) {
		var o = enclone(options, {method : form.method.toUpperCase(), headers : {"Content-Type" : "application/x-www-form-urlencoded"}});
		o.data = this.serialize(form);
		if (options.data) o.data += o.data ? "&" + options.data : options.data;
		return this.request(form.action, o);
	};
	
	this.update = function(id, url, options) {
		var myOptions = enclone(options);
		myOptions.id = id;
		return this.request(url, myOptions);
	};
	
	this.serialize = function(form) {
		var a = new Array();
		var name, value;
		var v;
		for (var i = 0; i < form.length; i++) {
			var name = form[i].name;
			if (!form[i].disabled) {
				value = null;
				switch (form[i].type) {
				case "hidden":
				case "password":
				case "text":
				case "textarea":
					value = form[i].value;
					break;
				case "select":
				case "select-one":
					value = form[i].options[form[i].selectedIndex].value;
					break;
				case "select-multiple":
					for (var j = 0; j < form[i].options.length; j++) {
						if (form[i].options[j].selected) {
							a.push(escape(form[i].name) + "=" + escape(form[i].options[j].value));
						}
					}
					break;
				case "radio":
				case "checkbox":
					if (form[i].checked) value = form[i].value;
					break;
				}
				if (value != null) a.push(escape(form[i].name) + "=" + escape(form[i].value));
			}
		}
		return a.join("&");
	};
})();
