/*
 *	ajaxObject - универсальный объект для работы с ajax-объектом XMLHttpRequest.
 * 	Объект определяет единственный метод go(). Этот метод принимает 7 параметоров,
 * 	2 - обязательные. Параметры: method, url, mode, callback, data, showHeaders, cache.
 * 	Определяет метод, адрес, режим выполнения запроса, функцию обратного вызова, 
 * 	данные для метода POST, отображение заголовка ответа сервера, кэширование.
 * 
 *  Также есть механизм, с помощью которого ограничивается продолжительность ответа
 *  от сервера (функция _handleReadyState).
 * 
 * 	Переопределена функция toString(), при ее вызове (явно или нет), выводится
 * 	интерфейс функции go().
 * 
 *  При получении ответа от сервера, результат анализируется на : DOM-объект,
 * 	исполняемый javascript и простой текст.
 * 
 *  Данные для POST-запроса в фунцкию go() должны передаваться как объект,
 *  _makePostData преобразует данные для POST-запроса.
 * 
 */

	var ajaxObject = (function() {
		
		return {
			
			get: function(url, callback, showHeaders, cache) {
					var http = ajaxObject._getXMLHttpRequest();
					if (cache == undefined) url += "?cache="+(new Date().getTime());
					http.open('GET', url);
					ajaxObject._handleReadyState(http, callback, showHeaders);
					http.send(null);
			},
			
			post: function(url, callback, data, showHeaders, cache) {
					var http = ajaxObject._getXMLHttpRequest();
					if (cache == undefined) url += "?cache="+(new Date().getTime());
					data = ajaxObject._makePostData(data);
					http.open('POST', url);
					http.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
					http.send(data);
					ajaxObject._handleReadyState(http, callback, showHeaders);
			},
			
			toString: function () {
					return  "function(method,url,mode,callback,data,showHeaders,cache), where:\n\n"
						+ "METHOD - string, with http-method(get, post, head)\n\n"
						+ "URL - string, with resourse's url\n\n"
						+ "MODE - boolean, mean ajax-mode: synchronous or asynchronous\n\n"
						+ "CALLBACK - function of converse call\n\n"
						+ "DATA - object or array for POST-request\n\n"
						+ "SHOWHEADERS - display alert with http-headers reply\n\n"
						+ "MAKECASHE - boolean value, if value equal true - that answer from servel will be cache\n\n";
				
			},
			
			_getXMLHttpRequest: function () {
					var http; 

					try {
						http = new XMLHttpRequest();
					}
					catch (e) { 
						var msxml = [ 
						'MSXML2.XMLHTTP.3.0',
						'MSXML2.XMLHTTP',  
						'Microsoft.XMLHTTP' 
						];
						for ( var i = 0, len = msxml.length; i < len; ++i) {
							try { 
								http = new ActiveXObject(msxml[i]); 
								break; 
							}
							catch (e) {}
						}
					}
					return http;
			},
			
			_handleReadyState: function (o, callback, showHeaders) {
					var poll = setInterval(function () {
						if (o.readyState == 4) {
							window.clearInterval(poll);
							if (callback) {
								if (showHeaders) ajaxObject._getHeaders(o);
								callback(ajaxObject._getResponse(o));
							}
						}
					},
					50);
			},
			
			_getHeaders: function (request) {
					alert(request.getAllResponseHeaders());
			},
			
			_getResponse: function (request) {
					switch (request.getResponseHeader("Content-Type")) {
						case "text/xml":
							return request.responseXML;
						case "text/javascript":
						case "text/json":
						case "application/javascript":
						case "application/x-javascript":
							return eval(request.responseText);
						default:
							return request.responseText;
					}
			},

			_makePostData: function (data) {
					if (typeof data != 'object' && typeof data != 'undefined') {
						throw new TypeError('Данные для POST-запроса должны быть объектом или массивом.');
					}
					var pairs = [];
					var regexp = /%20/g;
					for (var name in data) {
						var value = data[name].toString();
						var pair = encodeURIComponent(name).replace(regexp, "+") + '=' +
							encodeURIComponent(value).replace(regexp, "+");
						pairs.push(pair);
						
					}
					return pairs.join("&");
			}
		}
	})();