/**
 * AJAX надстройка (облегчённая версия, без использования jQuery),
 *		но синтаксис такой же как и у неё
 *
 *		$ajax.get( String url, [ Object params, [Function handler( String data, Boolean status)] ] );
 *		$ajax.post( String url, [ Object params, [Function handler( String data, Boolean status)] ] );
 *
 *		За исключением того, что в функцию обработчик передаётся два аргумента:
 *			это старая добрая "data" и булев тип "status", который отражает результат загрузки
 *				true - успешная загрузка
 *				false - ошибка загрузки ("data" содержит код загрузки документа XMLHttpRequest.status )
 *				null - прерывание запроса по таймауту (ошибка загрузки) ("data" содержит код загрузки документа XMLHttpRequest.status на момент срабатывания таймера )
 *
 */
var $ajax = new (function(){

	var par = ({
			timeout: 5000, // время, по истечении которого запрос считается потеряным
			empty: ''
		});


	this.get = function(){

		return query( getParams( 'GET',  arguments ) );
	};

	this.post = function(){

		return query( getParams( 'POST',  arguments ) );
	};

	function getParams ( method, arg ) {

		var obj = {
				method: method,
				url: null,
				async: true,
				params: null,
				handler: null
			};

		if ( arg.length ) {
			obj.url = arg[0].toString();

			if ( arg[1] && typeof arg[1] == 'function' ) {
				obj.handler = arg[1];

			} else if ( arg[1] && typeof arg[1] == 'object' ) {

				if ( method == 'GET' ) {
					obj.url += ((obj.url.indexOf('?')<0)? '?':'&' ) + encode(arg[1]);
				} else {
					obj.params = encode(arg[1]);
					//alert(obj.params);
				}

				if ( arg[2] && typeof arg[2] == 'function' ) obj.handler = arg[2];
			}
		}
		return obj;
	}

	function encode ( obj ) {

		var s = [];
		for(var k in obj) {

			if ( typeof obj[k] != 'object' ) s.push( k.toString() + "=" + encodeURIComponent( obj[k] ) );
			//if ( typeof obj[k] != 'object' ) s.push( k.toString() + "=" + encodeURIComponent( encodeURI(obj[k]) ) );
		}
		return s.join('&');
	}

	var xhr = window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
			function() {
				return new window.XMLHttpRequest();
			} :
			function() {
				try {
					return new window.ActiveXObject("Microsoft.XMLHTTP");
				} catch(e) {}
			};

	function query ( obj ){

		var hr = xhr(), err = false, timer, t;

			hr.open( obj.method, obj.url, obj.async );
			hr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

			var complete = function () {
				if ( timer ) clearTimeout( timer );
				obj.handler( hr.responseText, true );
			};

			if ( obj.handler ) {

					var noLeaks = function (){
						if ( hr.readyState == 4 ) {
							if ( !err ) {
								if ( hr.status == 200 )  {
									complete();
								} else {
									handler(hr.status, false);
								}
							}
						} else {
							return false;
						}
					};
					var leaks = function (){
						if ( !noLeaks() ) t = setTimeout( leaks, 10 );
					};


					if ( -[1,] && !document.querySelector ) {
						// memory leaks? ... ie7 and lower ... just in case...
						leaks();
					} else {
						hr.onreadystatechange = noLeaks;
					}

					timer = setTimeout( (function(){

										err=true;
										if ( t ) clearTimeout( t );

										var st = hr.status;
										hr.abort();
										obj.handler( st, null );

									}), par.timeout );
			}

			hr.send( obj.params );

			return hr;
	}

})();
