//
// 2007-09-11
// (a) nolar@howard-studio.ru
// (c) http://www.howard-studio.ru/
//

var ajax_pool = [];

function ajax (params)
{
	var xmlhttp = null;
	try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"   ); } catch (exception1) {
	try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (exception2) {
	try { xmlhttp = new XMLHttpRequest();                   } catch (exception3) {
	}}}
	if (!xmlhttp) return false;

	if (typeof(params.object) == 'object')
		params.rawtext = params.object.toJSONString();
	if (typeof(params.rawtext) == 'undefined')
		params.rawtext = '';

	if (typeof(params.method) != 'string')
		params.method = 'POST';
	else	params.method = params.method.toUpperCase();

	if (typeof(params.url) == 'undefined')
		params.url = '';

	var index = ajax_pool.length;
	ajax_pool[index] = {};
	ajax_pool[index].params  = params;
	ajax_pool[index].xmlhttp = xmlhttp;
	ajax_pool[index].timer   = params.interval ? setInterval("ajax_timer("+index+");", params.interval) : -1;
	ajax_pool[index].count   = 0;

	if (typeof params.async == 'undefined') params.async = true;
	xmlhttp.open(params.method, params.url, params.async);

	var onreadystatechange_triggered = 0;
	var onreadystatechange = xmlhttp.onreadystatechange = function() {
		onreadystatechange_triggered++;
		if (params.on_state) params.on_state(params, xmlhttp.readyState);
		if (xmlhttp.readyState == 4)
		{
			if (ajax_pool[index].timer >= 0) clearInterval(ajax_pool[index].timer);
			switch (xmlhttp.status)
			{
				case 200:// ok
				case 304:// not modified
					var response_text = xmlhttp.responseText;

					var pos = response_text.indexOf("<!--CONTENT-ENDS-HERE-->");
					if (pos >= 0)
					{
						debug_text    = response_text.substr(pos);
						response_text = response_text.substr(0, pos);

						if (params.on_debug)
						params.on_debug(params, debug_text, response_text);
					}

					var response_parsed = true;
					try { var response_object = eval("(" + response_text + ")"); }
					catch (exception) { response_parsed = false; }

					if (response_parsed && (typeof(response_object) == 'object') && response_object._is_exception_)
                                        {
						if (params.on_exception)
						params.on_exception(params, response_object.text, response_object.id, response_object.type);
                                        } else
                                        if (response_parsed)
                                        {
						if (params.on_success)
						params.on_success(params, response_object);
                                        } else
                                        {
						if (params.on_rawtext)
						params.on_rawtext(params, response_text);
					}
					break;
				default:
					{
						if (params.on_httperror)
						params.on_httperror(params, xmlhttp.statusText, xmlhttp.status);
					}
					break;
			}
			delete xmlhttp;
		}
	};

	if (params.on_start) params.on_start(params, 0, 0);

	xmlhttp.setRequestHeader("Content-type", "text/plain");
	xmlhttp.setRequestHeader("Content-length", params.rawtext.length);
	xmlhttp.setRequestHeader("Connection", "close");
	xmlhttp.send(params.rawtext);

	if (!params.async && !onreadystatechange_triggered) onreadystatechange();// workaround for FF bug with synchronous requests

	return true;
}

function ajax_timer (index)
{
	var count  = ++(ajax_pool[index].count );
	var params =   (ajax_pool[index].params);
	if (params.timeout && ((count * params.interval) >= params.timeout))
	{
		clearInterval(ajax_pool[index].timer);
		if (params.on_timeout) params.on_timeout(params, count * params.interval, count);
		ajax_pool[index].xmlhttp.onreadystatechange = function(){};
		ajax_pool[index].xmlhttp.abort();
		delete ajax_pool[index].xmlhttp;
		delete ajax_pool[index];
	} else
	{
		if (params.on_timer) params.on_timer(params, count * params.interval, count);
	}
}

function ajax_state_text (state)
{
	switch (state)
	{
		case 0: return "Инициализация";
		case -1:return "Ждите...";//not xmlhttprequest's, but internal for us
		case 1: return "Ждите...";
		case 2: return "Запрос отправлен";
		case 3: return "Получение данных";
		case 4: return "Операция выполнена";
		default: return "Статус '" + state + "'";
	}
}

function ajax_debug2 (params, debug_text, response_text)
{
	alert(response_text);
	alert(debug_text);
}
function ajax_debug (params, debug_text, response_text)
{
//	alert(response_text);
//	alert(debug_text);
}
function ajax_rawtext (params, response_text)
{
	alert(response_text);
}

