/**
 * Асинхронный обмен с сервером
 *
 * @package go.js
 * @author  Григорьев Олег aka vasa_c
 */
go.ajax = new (function() {

/**
 * Конструктор аякс-объекта
 */
this.cAjax = (
	function(url)
	{
		this.url = url;
	}
);

this.getAction = (
	function(action)
	{
		var a = new _this.cAjax("/ajax/executor.php?action=" + encodeURIComponent(action) + "&rnd=" + (new Date()).getTime());
		a._action = true;
		return a;
	}
);

/**
 * Прототип аяксовых классов
 */
var pAjax = {

	"send": (
		function(timeout)
		{
			if (this._busy) {
				return false;
			}
			var req = _this.makeRequestObject();
			this.req = req;
			var url   = this.url;
			if (this.post) {
				method = "POST";
				var data = post2string(this.post);
			} else {
				method = "GET";
				var data = null;
			}
			if (this.get) {
				if (this._action) {
					url += "&" + post2string(this.get);
				} else {
					url += "?" + post2string(this.get);
				}
			}
			var _t = this;
			req.onreadystatechange = (function() {return _t.ready();});
			req.open(method, url, true);
			if (data) {
				req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			}
			req.send(data);
			this._busy = true;
			if (timeout) {
				this._tout = setTimeout((function() {return _t.onTimeout();}), timeout);
			}
			return true;
		}
	),

	"ready": (
		function()
		{
			var req = this.req;
			var rs  = req.readyState;
			if (rs < 4) {
				if (this["ready" + rs]) {
					me(this["ready" + rs], this);
				}
				return true;
			}
			this._busy = false;
			if (this._tout) {
				this._tout = false;
				clearTimeout(this._tout);
			}
			var rs = req.status;
			if (rs != 200) {
				if (this.error) {
					me(this.error, this);
				}
				var rrs = Math.round(rs / 100);
				if (this["error" + rrs]) {
					me(this["error" + rrs], this);
				}
				if (this["error" + rs]) {
					me(this["error" + rs], this);
				}
				return true;
			}
			this.responseS();
			me(this.handler, this);
			return true;
		}
	),

	"responseS": (
		function()
		{
			if (!this._action) {
				return true;
			}
			this._action = {};
			var r = this.req.responseXML.documentElement;
			var e = r.getElementsByTagName("result");
			if (e.length > 0) {
				this._action.ok = true;
				this._action.result = e.item(0);
				this._action.code   = e.item(0).getAttribute("code");
			} else {
				this._action.ok = false;
				e = r.getElementsByTagName("error");
				if (e.length > 0) {
					this._action.error = e.item(0);
					this._action.errorCode = e.item(0).getAttribute("code");
				}
			}
			return true;
		}
	),

	"JSON": (
		function()
		{
			if (!this._action) {
				return null;
			}
			if (this._action.json) {
				return this._action.json;
			}
			var parts = this._action.result && this._action.result.getElementsByTagName("part");				
			var js;
			if (parts) {
				js = [];
				for (var i = 0; i < parts.length; i++) {
					js.push(parts.item(i).firstChild.nodeValue);
				}
				js = js.join("");
			}
			var ret;
			if (js) {
				eval("ret = " + js);
			} else {
				ret = null;
			}
			this._action.json = ret;
			return ret;
		}
	),

	"onTimeout": (
		function()
		{
			if (!this._busy) {
				return false;
			}
			this.req.abort();
			this._tout = false;
			me(this.onAbort, true);
			return true;
		}
	),

	"onAbort": go.emptyFunction,

	"handler": (
		function()
		{
			return true;
		}
	)

};
this.cAjax.prototype = pAjax;

/**
 * Создание XHR-объекта
 *
 * @return XMLHttpRequest
 */
this.makeRequestObject = (
	function()
	{
		if (window.XMLHttpRequest) {
			_this.makeRequestObject = (function() {return new XMLHttpRequest;});
			return _this.makeRequestObject();
		}
		if (!window.ActiveXObject) {
			_this.makeRequestObject = go.falseFunction();
			return false;
		}
		var aV = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP'];
		for (var i = 0; i < aV.length; i++) {
			var name = aV[i];
			var f = (function() {return new ActiveXObject(name);});
			try {
				var obj = f();
				_this.makeRequestObject = f;
				return obj;
			} catch (e) {}
		}
		_this.makeRequestObject = Exp.falseFunction();
		return false;
	}
);

var _this = this;
var me = go.methodExec;

function post2string(post, bn)
{
	if (typeof(post) != "object") {
		if (post === true) {
			return 1;
		}
		if (post === false) {
			return 0;
		}
		return post;
	}
	var A = [];
	for (var name in post) {
		var e = post[name];
		if (bn) {
			name = bn + "[" + name + "]";
		}
		if (typeof(e) == "object") {
			A.push(arguments.callee(e, name));
		} else {
			if (e === true) {
				e = 1;
			} else if (e === false) {
				e = 0;
			}
			A.push(name + "=" + encodeURIComponent(e));
		}
	}
	return A.join("&");
}

})();