/* 
** xhnaut.js - Simple XML HTTP Request (XHR) interface
**
**  author: Adam Saponara
**    date: 10 Oct 2007
** version: 0.1
** license: Attribution-Noncommercial-Share Alike 3.0 United States
**          See http://creativecommons.org/licenses/by-nc-sa/3.0/us/
*/

function XHNaut() {

	var xhr = null;
	var queue = [];
	var busy = false;
	var self = this;
	
	try { xhr = new XMLHttpRequest(); }
	catch (e) { try { xhr = new ActiveXObject('Msxml2.XMLHTTP'); }
	catch (e) { try { xhr = new ActiveXObject('Microsoft.XMLHTTP'); }
	catch (e) { xhr = false }}}

	if (!xhr) return null;
	
	function eat(params) {
		if (!params || typeof params != 'object') return '';
		var s = [];
		for (var k in params) if (params.hasOwnProperty(k)) 
			s.push(encodeURIComponent(k) + '=' + encodeURIComponent(params[k]));
		return s.join('&');
	}
	
	this.request = function(url, method, params, callback) {
		params = eat(params);
		if (!xhr) return false;
		if (busy) {
			queue.push(arguments);
			return true;
		}
		busy = true;
		method = method.toUpperCase();
		try {
			if (method == 'GET') {
				xhr.open(method, url + '?' + params, true);
				params = '';
			}
			else {
				xhr.open(method, url, true);
				xhr.setRequestHeader('Method', 'POST ' + url + ' HTTP/1.1');
				xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			}
			xhr.onreadystatechange = function() {
				if (xhr.readyState == 4 && busy) {
					var result = null;
					busy = false;
					if (!callback) return;
					try { result = eval('(' + xhr.responseText + ')'); }
					catch (e) { result = xhr.responseText; }
					callback(result);
					if (queue.length > 0) self.request.apply(self, queue.shift());
				}
			};
			xhr.send(params);
		}
		catch (e) {
			return false;
		}
		return true;
	};
	
	this.process = function(form, callback) {
		if (!form || !form.elements) return false;
		var el, params = {};
		for (var i = 0, l = form.elements.length; i < l; i++) {
			el = form.elements[i];
			if (!el.name || el.name.length < 1) continue;
			params[el.name] = el.value;
		}
		if (callback && typeof callback == 'function') callback.form = form;
		return this.request(form.action, form.method, params, callback);
	}
	
	return this;
}

