	////////////////////////////////////////////////////////////////////
	// This file is part of zephWeb.  This software (zephWeb) is not  //
	// licensed for use to ANYONE without the express written consent //
	// of myself during it's development stage (now).                 //
	//                                                                //
	// ©2008 Levi Lansing - All Rights Reserved - www.levilansing.com //
	////////////////////////////////////////////////////////////////////

function isArray(obj) {
	if(!obj || !obj.constructor)
		return false;
		
	return obj.constructor == Array;
};

function isString(str) {
		if(str != null && typeof(str) == "string")
			return true;
		return false;
};

// ajax :)
// core code modified from http://www.captain.at/howto-ajax-form-post-request.php
Ajax.prototype.http_request = null;
Ajax.prototype.returnFunct = null;
Ajax.prototype.failFunct = null;
Ajax.prototype.returnParam = null;
Ajax.prototype.url = null;
Ajax.prototype.parameters = null;
Ajax.prototype.status = null;
Ajax.prototype.responseType = null;

function Ajax(url,parameters,responseType)
{
	this.url = url;
	this.parameters = parameters;
	this.responseType = responseType;
};

Ajax.prototype.post = function(url, parameters, returnFunct, returnParam, failFunct, method)
{
	if(url != null)
		this.url = url;
	if(this.url == null || this.url == '')
		this.url = window.location;
	if(parameters != null)
		this.parameters = parameters;
	if(method == null)
		method = 'POST';
	
	this.status = 'sending';

	this.cleanUp();
	if(returnFunct)
		this.returnFunct = returnFunct;
	if(returnParam)
		this.returnParam = returnParam;
	if(failFunct)
		this.failFunct = failFunct;
	if(window.XMLHttpRequest) { // Mozilla, Safari,...
		 this.http_request = new XMLHttpRequest();
		 if(this.http_request.overrideMimeType)
				this.http_request.overrideMimeType(this.responseType == null ? 'text/xml' : this.responseType);
	} else if(window.ActiveXObject) { // IE
		 try {
				this.http_request = new ActiveXObject("Msxml2.XMLHTTP");
		 } catch (e) {
				try {
					 this.http_request = new ActiveXObject("Microsoft.XMLHTTP");
				} catch (e) {}
		 }
	}
	if(!this.http_request) {
		var msg = "Your browser appears to not be supported.  This site requires a browser with AJAX capabilities and may not work properly.\nPlease try a different web browser.";
		if(this.failFunct)
			this.failFunct(msg);
		else
			alert(msg);
		return false;
	}
	
	// prepare parameters
	var params = '';
	if(this.parameters != null) {
		if(isString(this.parameters))
			params = this.parameters;
		else
		{
			for(var k in this.parameters) {
				params += this.createParam(k,this.parameters[k]);
			}
		}
	}
	// params = "a=1&b=2&", should we remove the & at the end?
	//if(params.length > 0)
	//	params = params.substring(0,params.length-1);
	
	var this1 = this;
	this.http_request.onreadystatechange = function(){ this1.AjaxReturn() };
	if (method == 'POST') {
		this.http_request.open('POST',this.url,true);
		this.http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		this.http_request.setRequestHeader("Content-length", params.length);
		this.http_request.setRequestHeader("Connection", "close");
		this.http_request.send(params);
	} else { // using GET
		this.http_request.open('GET',this.url+'?'+params,true);
		this.http_request.setRequestHeader("Content-type", "text/plain");
		this.http_request.setRequestHeader("Content-length", 0);
		this.http_request.setRequestHeader("Connection", "close");
		this.http_request.send(null);
	}
	return true;
};

// creates a url encoded parameter string for the given variable
// supports converting arrays into a[]=1&a[]=2
Ajax.prototype.createParam = function(k,p,b) {
	if(b == null)
		b = '';
	if(isArray(p)) {
		var r = '';
		for(var i=0; i<p.length; i++)
			r += this.createParam(k,p[i],b+'[]');
		return r;
	}
	return k+b+'='+escape(p)+'&';
};

Ajax.prototype.AjaxReturn = function() {
	this.status = 'receiving';
	if(this.http_request.readyState == 4) {
		if (this.http_request.status == 200) {
			this.status = 'received';
			if(this.returnFunct)
				this.returnFunct(this,this.returnParam);
			this.processResponse();
		}
		else {
			// fail funct required if an error needs to be displayed
			var msg = "There was a problem with the request.  Please try again.";
			if(this.failFunct)
				this.failFunct(this.returnParam,this,msg);
		}
	}
};

Ajax.prototype.processResponse = function() {
	var xml = this.http_request.responseXML;
	
	// check for javascript and execute it
	var root = xml.getElementsByTagName('ajax')[0];
	if(root) {
		var head = document.getElementsByTagName("head")[0];
		var js = root.getElementsByTagName('_javascript');
		for(var i=0; i<js.length; i++) {
			var script = document.createElement('SCRIPT');
				script.type = 'text/javascript';
				if(document.all)
					script.text = this.unescapeString(js[i].firstChild.nodeValue);		// IE: putting js in innerHTML causes an error in IE
				else
					script.innerHTML = this.unescapeString(js[i].firstChild.nodeValue);		// for Safari, everyone else is ok with .text
			head.appendChild(script);
		}
	
		// check for a redirect
		var redirect = root.getElementsByTagName('_redirect')[0];
		if(redirect)
			window.location = this.unescapeString(redirect.firstChild.nodeValue);
	}
};

Ajax.prototype.getXML = function() {
	if(this.status == 'received')
		return this.http_request.responseXML;
};

Ajax.prototype.getText = function() {
	if(this.status == 'received')
		return this.http_request.responseText;
};

Ajax.prototype.getHTML = function() {
	return this.unescapeString(this.getData('_html',''));
};

Ajax.prototype.getData = function(key,def,attributes) {
	var tag = this.getTag(key);
	attributes = {};
	if(tag && tag.length > 0 && tag[0].firstChild) {
		attributes = this.unescapeAttributes(tag[0].attributes);
		return this.unescapeString(tag[0].firstChild.nodeValue);
	}
	return def;
};

Ajax.prototype.unescapeString = function(string)
{
	return string.replace(/&amp;/gi,'&');
};

Ajax.prototype.unescapeAttributes = function(attributes)
{
	//if(!attributes)
	//	return {};
	var obj = {};
	for(var i=0; i<attributes.length; i++)
		obj[attributes[i].nodeName] = this.unescapeString(attributes[i].nodeValue);
	return obj;
};

Ajax.prototype.submitForm = function(form,returnFunct,returnParam,failFunct) {
	var post = "";
	for(var i=0; i<form.elements.length; i++) {
		var value = null;
		var el = form.elements[i];
		if(el.nodeName == "INPUT") {
			if(el.type == "checkbox" || el.type == "radio") {
				if(el.checked)
					value = el.value;
			}
			else
				value = el.value;
		}
		else if(el.nodeName == "SELECT")
			value = el.options[el.selectedIndex].value;
		else if(el.nodeName == "TEXTAREA")
			value = el.value;

		if(value != null)
			post += el.name + "=" + escape(value) + "&";
	}
	
	this.post(form.action,post,returnFunct,returnParam,failFunct);
};

Ajax.prototype.getDataArray = function(key,def) {
	var tag = this.getTag(key);
	var a = Array();
	if(tag == null) {
		if(def == null)
			return a;
		return def;
	}
	
	for(var i=0; i<tag.length; i++)
		a.push({value:this.unescapeString(tag[i].firstChild.nodeValue),attributes:this.unescapeAttributes(tag[i].attributes)});
	
	return a;
};

Ajax.prototype.getTag = function(key) {
	var root = this.getXML().getElementsByTagName('ajax')[0];
	if(!root)
		return null;
	
	var tag = null;
	if(isArray(key)) {
		tag = root.getElementsByTagName(key[0]);
		for(var i=0; (tag.firstChild && i<key.length); i++)
			tag = tag.getElementsByTagName(key[i]);
	}
	else
		tag = root.getElementsByTagName(key);
	return tag;
};

Ajax.prototype.cleanUp = function() {
	if(this.http_request != null)
		delete this.http_request;
	this.http_request = null;
};
