// Базовый объект
var net = new Object();
// Состояния запроса
net.READY_STATE_UNINITIALIZED = 0;
net.READY_STATE_LOADING = 1;
net.READY_STATE_LOADED = 2;
net.READY_STATE_INTERACTIVE = 3;
net.READY_STATE_COMPLETE = 4;
// Конструктор
// key - Ключ запроса в массиве requestsHash
// method - метод отправки запроса (POST, GET)
// url - URL скрипта на сервере, который обработает запрос
// params - параметры запроса (test=1&flag=2)
// onload - callback-функция, обработчик после загрузки
// onerror - callback-функция, обработчик в случае ошибки
// contentType - тип контента запроса (text/html)
// headers - прочие заголовки, кроме content-type, например, Expires
net.ContentLoader = function(key, method, url, params, onload, onerror, contentType, headers) {
	this.hashKey = key; 
	// Свойство для рапознавания браузеров, не поддерживающих request
	this.unrequestBrowser = false;
	// request - объект
	this.req = null;
	this.onload = onload;
	// Если её нет, вызывается дефолтный обработчик
	this.onerror = (onerror) ? onerror : this.defaultError;
	// Вызываем метод для генерации запроса
	this.loadXMLDoc(method, url, params, contentType, headers);
}
// Все методы записаны в прототип
net.ContentLoader.prototype = { // Methods
	// loadXMLDoc - метод, для генерации request-запроса
	loadXMLDoc : function(method, url, params, contentType, headers) {
		if (!method) method="GET";
		if (!contentType && method=="POST") contentType='application/x-www-form-urlencoded';
		if (window.XMLHttpRequest) {
			this.req=new XMLHttpRequest(); 
		} else if (window.ActiveXObject) {
			this.req=new ActiveXObject("Microsoft.XMLHTTP");
		} else {
			this.unrequestBrowser = true;
			return;
		}
		if (this.req) {
			try {
				this.req.open(method,url,true);
				if (contentType){
					this.req.setRequestHeader('Content-Type', contentType);
				}
				if (headers) {
					for (var h in headers) {
						this.req.setRequestHeader(h,headers[h]);
					}
				}
				var loader=this;
				this.req.onreadystatechange=function() {
					loader.onReadyState.call(loader);
				}
				this.req.send(params);
			} catch (err){
				this.onerror.call(this);
			}
		}
	},
	// onReadyState - метод для обработки ответов сервера
	onReadyState : function() {
		var req=this.req;
		var ready=req.readyState;
		if (ready==net.READY_STATE_COMPLETE) {
			var httpStatus=req.status;
			if (httpStatus==200 || httpStatus==0) {
				this.onload.call(this);
			} else {
				this.onerror.call(this);
			}
		}
	},
	// defaultError - метод обработки ошибок по умолчанию 
	defaultError : function() {
		alert("error fetching data!"+"\n\nreadyState:"+this.req.readyState +"\nstatus: "+this.req.status+"\nheaders: "+this.req.getAllResponseHeaders());
	}
}
// Массив для хранения нескольких запросов
var requestsHash = [];
// Функция, создающая новый экземпляр объекта net.ContentLoader
// Записывает запросы в requestsHash
// Возвращает свойство unrequestBrowser
function setAjaxRequest(method, url, params, onload, onerror, contentType, headers) {
	// Check of necessary parameters
	if (!url) {
		alert("Necessary parameters are not specified");
		return;
	}
	requestsHash.push(new net.ContentLoader(requestsHash.length, method, url, params, onload, onerror, contentType, headers));
	return requestsHash[requestsHash.length - 1].unrequestBrowser;
}  
