/**
 * Kaizen Framework - JavaScript
 * 
 * @author Vasil Georgiev Dinkov - Kaizen Web-Productions (http://www.kaizen-web.com)
 * @version 1.0
 * @copyright Copyright(C), Kaizen Web-Productions, 2004-2008, All Rights Reserved.
 * @package KaizenFramework
 */

/**
 * AJAX Functionality
 * Adds the ability to do asyncron and syncron connections.
 * 
 * @author Vasil Georgiev Dinkov - Kaizen Web-Productions (http://www.kaizen-web.com)
 * @version 1.0
 * @copyright Copyright(C), Kaizen Web-Productions, 2004-2008, All Rights Reserved.
 * @package KaizenFramework
 * @subpackage Ajax
 */

Kaizen.AJAX = {

	// AJAXObject class
	AJAXObject: function() {
		this.XMLHttp = null;
		if (window.XMLHttpRequest)
			this.XMLHttp = new XMLHttpRequest();
		else
			try {
				this.XMLHttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {
				try {
					this.XMLHttp = new ActiveXObject('Msxml2.XMLHTTP');
				} catch(E) { };
			};
	},

	// stores created AJAXObjects for reuse
	AJAXObjects: [],

	// get AJAXObject - if this.AJAXObjects contains available return it, else create a new one and store it in this.AJAXObjects
	getAJAXObject: function() {
		var cur = null;
		for(var i = 0, l = this.AJAXObjects.length; i < l; i++){
			cur = this.AJAXObjects[i];
			if(!cur.inProgress)
				return cur;
		}
		return this.AJAXObjects[this.AJAXObjects.length] = new this.AJAXObject();
	},

	// async, user, pass are optional with default async=true
	Request: function(url, callbackFunc, async, user, pass) {
		this.url = url;
		this.callbackFunc = callbackFunc;
		this.async = typeof async != 'undefined' ? async : true;
		this.user = user || '';
		this.pass = pass || '';
	}

}

Kaizen.AJAX.AJAXObject.prototype.onReadyStateChange = function() {
	var readyState = this.XMLHttp.readyState;
	if (readyState == 4) {
		this.callbackFunc(this.XMLHttp.status, this.XMLHttp.responseText, this.XMLHttp.responseXML);
		this.XMLHttp.onreadystatechange = function(){};
		this.inProgress = false;
	}
}

Kaizen.AJAX.Request.prototype.load = function(data, method, headers) {
	this.AJAXObject = Kaizen.AJAX.getAJAXObject();
	this.AJAXObject.inProgress = true;
	this.AJAXObject.callbackFunc = this.callbackFunc;

	var object = this.AJAXObject;
	var XMLHttp = object.XMLHttp;
	var uri = this.url;
	var timestamp = new Date().getTime();

	if (typeof method == 'object') {
		headers = method;
		method = 'POST';
	}

	if (!method || /post/i.test(method)) {
		XMLHttp.open('POST', uri, this.async, this.user, this.pass);
	} else {
		uri += (/\?/.test(uri) ? '&' : '?') + data + '&timestamp=' + timestamp;
		XMLHttp.open('GET', uri, this.async, this.user, this.pass);
		data = null;
	}

	XMLHttp.onreadystatechange = function(){object.onReadyStateChange.apply(object)};

	if (headers) {
		for (var i in headers) {
			XMLHttp.setRequestHeader(i, headers[i]);
		}
	} else if (!method || /post/i.test(method)) {
		XMLHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
		XMLHttp.setRequestHeader('Content-Length', data.length);
	}

	XMLHttp.send(data);
}

Kaizen.AJAX.Request.prototype.abort = function() {
	var object = this.AJAXObject;
	var XMLHttp = object.XMLHttp;
	object.callbackFunc = function(){};
	try {
		XMLHttp.onreadystatechange = function(){};
	} catch(e) { };
	XMLHttp.abort();
	object.inProgress = false;
}

// usage will be
// request = new Kaizen.AJAX.Request('http://www.dsfdsf.com/', mycallbackFunction, true, 'user', 'pass');
// request.load('myVar1=value1&myVar2=value2');
// request.abort();
// request.load('myVar3=value3');

// Check any string for valid JSON syntax - based on isJSON method from Prototype - http://www.prototypejs.org/
String.prototype.isJSON = function() {
	if (this.length == 0)
		return false;
	var str = this;
	if (/,,|:,|:\}|\[,|,\]/.test(str))
		return false;
	str = str.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
	return /^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/.test(str);
}
