//The allofe AJAX class.
//If there are changes, be SURE you know what it's affecting
//Preferable changes = changes to internal working not the syntax!

function aoeAJAX(requestFile) {
	this.failed = null;
	this.xmlhttp = null;
	this.sendData = null;
	this.callbackFunctionName = null;
	this.callbackJSObjectName = null;
	this.callbackJSObjectFunction = null;
	this.response = null;
	this.URLString = "";
	this.requestFile = requestFile;
	this.method = "post";
	
	this.onLoading = function() { };
	this.onLoaded = function() { };
	this.onInteractive = function() { };
	this.onCompletion = function() { };
	
	this.createAJAX = function() {
		try {
			this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (oc) {
				this.xmlhttp = null;
			}
		}
		if(!this.xmlhttp && typeof XMLHttpRequest != "undefined")
			this.xmlhttp = new XMLHttpRequest();
		if (!this.xmlhttp){
			// no XMLHttpRequest support, so no AJAX.
			this.failed = true; 
		}
	}
	
	this.setMethod = function(method) {
		this.method = method;
	}
	
	this.getMethod = function(method) {
		return this.method;
	}
	
	this.setSendData = function(data) {
		this.sendData = data;
	}
	
	this.setResponseCallback = function(callbackFunctionName) {
		this.callbackFunctionName = callbackFunctionName;
	}

	this.runCallback = function() {
		if (typeof(this.callbackFunctionName) == "object")
		{
			this.callbackFunctionName[0][this.callbackFunctionName[1]](this.response);
		}
		else
		{
			var callback = eval(this.callbackFunctionName);
			callback(this.response);
		}
	}

	this.getURLString = function(){
		var newSendData = new Array();
		for(var key in this.sendData) {
			if (this.encodeURIString) {
				if (key.indexOf('amp;') != -1){
					key = key.substring(4);
				}
				newSendData[newSendData.length] = encodeURIComponent(key)+"="+encodeURIComponent(this.sendData[key]);
			}
			else {
				newSendData[newSendData.length] = key+"="+this.sendData[key];
			}
		}
		return newSendData.join('&');
	}
	
	this.send = function() {
		if (this.xmlhttp) {
			var self = this; // wierd fix for odd behavior where "this" wouldn't work in the readystate function.
			this.xmlhttp.open(this.method, this.requestFile, true);
			if (this.method == "post") { this.xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded') }
//			if (this.method == "post") { this.xmlhttp.setRequestHeader('Content-Type', 'application/multipart-form-data') }
//alert(this.getURLString());
			this.xmlhttp.send(this.getURLString());
			this.xmlhttp.onreadystatechange = function() {
				switch (self.xmlhttp.readyState){
					case 1: // Loading.
						self.onLoading();
					break;
					case 2: // Loaded.
						self.onLoaded();
					break;
					case 3: // Interactive - is called every 4096 bytes.. pretty much just tells you it's downloading data.
						self.onInteractive();
					break;
					case 4: // Completed.
						self.response = self.xmlhttp.responseText
						self.onCompletion();
						if(self.callbackFunctionName){ self.runCallback(); }
					break;
				}
			};
		}
	}

	// Initialize the xmlhttp object
	this.createAJAX();
}

function exec_ajax(the_data, callback, the_url) {
	var exec_ajax_obj = new aoeAJAX(the_url);
	exec_ajax_obj.setResponseCallback(callback);
	exec_ajax_obj.setMethod("post");
	exec_ajax_obj.setSendData(the_data);
	exec_ajax_obj.send();
}

function exec_ajax_js_function(the_data, callback_js_obj, callback_js_fn, the_url){
	var exec_ajax_obj = new aoeAJAX(the_url);
	exec_ajax_obj.setResponseCallback({0:callback_js_obj,1:callback_js_fn});
	exec_ajax_obj.setMethod("post");
	exec_ajax_obj.setSendData(the_data);
	exec_ajax_obj.send();
}

function exec_ajax_php(the_data, callback, ajax_php_id) {
	the_data["ajax_php_id"] = ajax_php_id;
	exec_ajax(the_data, callback, "../../common/includes/ajax_exec.php");
}


function exec_javascript_includes(response){
	var regexp = /<script[^>]*src\s?=\s?['"]([^'">]*)['"][^>]*>/gi;
	var includes_loading = false;
	while ((src = regexp.exec(response))) {
		var scriptTag = document.createElement("script");
		scriptTag.language = 'javascript';
		scriptTag.type = 'text/javascript';
		scriptTag.src = src[1];
		document.body.appendChild(scriptTag);
		includes_loading = true;
	}
	return includes_loading;
}

//quickly exec included javascript sometimes has issues with globals in IE
//so test carefully when using, however the speed gain is noticeable
function fast_exec_javascript(response) {
	var includes_loading = exec_javascript_includes(response);		
	var script, scripts = [], regexp = /<script[^>]*>([\s\S]*?)<\/script>/gi;
	while ((script = regexp.exec(response))) scripts.push(script[1]);
	scripts = scripts.join('\n');
	if (includes_loading) window.setTimeout(scripts, 250);
	else window.setTimeout(scripts, 0);
}

function exec_javascript_code(response){
	var response = unescape(response);
	var script, scripts = [], regexp = /<script[^>]*>([\s\S]*?)<\/script>/gi;
	while ((script = regexp.exec(response))) scripts.push(script[1]);
	scripts = scripts.join('\n');
	var js = document.createElement("script");
	js.setAttribute('language', 'javascript');
	js.setAttribute('type', 'text/javascript');
	js.text = scripts;		
	document.body.appendChild(js);
}

function exec_javascript(response) {
	exec_javascript_includes(response);		
	setTimeout("exec_javascript_code('"+escape(response)+"')", 1);
}