/**
 Object: load
 Version: 1.0
 Autor: Александр Хрищанович
 Description: Ajax библиотека
 Require: 
 	- function.js v.1.0
*/
var load = {

	/* массив включённых файлов */
	includedFiles : new Array( ),

	/* объект XMLHttp */
	request : null,

	/* использовать кэширование */
	useCache : true,

	/* использовать синхронные запросы */
	useSynchron : false,

	/* Функция, которая выполниться до начала запроса на сервер */
	callBackFunctionStart : null,

	/* Функция, которая выполниться после загрузки данных с сервера */
	callBackFunctionEnd : null,

	/* Данные приходят в TEXT-mode */
	textMode : true,

	/* Url - путь к файлу-обработчику */
	urlFile : null,

	/* Использовать POST в запросе на сервер */
	typeQuery : 'GET',

	/* HTTP - заголовки к запросу */
	requestHeader : new Array( ),

	/* Массив данных для запроса */
	queryArray : new Array( ),


	/* Получение XMLHTTP объекта для ajax запроса на сервер */
	GetXMLHttpObject : function ( ) {

		var result = false;
		var i;
		var XMLHttpObjects = [
			function ( ) { return new XMLHttpRequest( ) },
			function ( ) { return new ActiveXObject( 'Msxml2.XMLHTTP' ) },
			function ( ) { return new ActiveXObject( 'Microsoft.XMLHTTP' ) }
		];

		for( i=0; i<XMLHttpObjects.length; i++ ) {

			try {
				result = XMLHttpObjects[i]( );
				break;
			}
			catch ( e ) { }

		}

		return result;

	},

	/* Включение запрошенного файла с сервера */
	Include : function ( urlFile, arrayQuery ) {

		if ( arrayQuery ) {
			this.queryArray = arrayQuery;
		}
		else {
			this.queryArray = new Array( );
		}
		
		this.urlFile = urlFile;

		var result = false;

		/* выполнение callback - функции до запроса на сервер */
		if ( this.callBackFunctionStart ) {
			this.callBackFunctionStart( );
		}

		/* проверка на использование кэширования */
		if ( this.useCache && this.includedFiles[this.urlFile] ) {
			result = this.includedFiles[this.urlFile];
		}
		else {

			result = this.Load( );

			if ( this.useSynchron ) {
				this.includedFiles[this.urlFile] = result;	
			}

		}

		/* выполнение callback - функции после запроса на сервер */
		if ( this.callBackFunctionEnd && result ) {

			var text = ( result.textResponse ) ? result.textResponse : result;
			var status = ( result.status ) ? result.status : 200;

			this.callBackFunctionEnd( text, status );
		}

		return result;

	},

	/* Запрос на сревер */
	Load : function ( ) {

		this.request = this.GetXMLHttpObject( );

		if ( !this.useSynchron ) {
			this.request.onreadystatechange = this.OnReadyStateChange.bindAjax( this );
		}
		
		var added = ( (this.typeQuery == 'GET' && this.queryArray.length > 0) ? ('?' + this.MakeRequest( ))  : '' )
		this.request.open( this.typeQuery, this.urlFile + added, !this.useSynchron );

		if ( this.typeQuery == 'POST' ) {

			this.requestHeader['Content-Type'] = 'application/x-www-form-urlencoded';

		}

		var context = this;
		
		this.requestHeader.EachHash (
			
			function ( item, sProperty ) {
				
				context.request.setRequestHeader( sProperty, item );
				
			}
		
		);
		
		this.request.send( ( this.typeQuery == 'POST' ? this.MakeRequest( )  : null) );

		if ( this.useSynchron ) {

			var textResponse = false;

			if ( this.request.status == 200 ) {
				textResponse = this.textMode ? this.request.responseText : this.request.responseXML;
			}

			return {
				textResponse : textResponse,
				status : this.request.status
			};

		}

		return false;

	},

	/* Подготовка строки запроса на сервер */
	MakeRequest : function ( ) {

		var string = '';

		this.queryArray.EachHash (
		
			function ( item, sProperty ) {
				string += sProperty + '=' + encodeURI( item ) + '&';	
			}
		
		);

		return string.substr( 0, string.length - 1 );

	},

	/* Системная функция для AJAX */
	OnReadyStateChange : function ( ) {

		if ( this.request.readyState == 4 ) {

			var textResponse = false;

			if ( this.request.status == 200 ) {
				
				textResponse = this.textMode ? this.request.responseText : this.request.responseXML;

			}

			this.includedFiles[this.urlFile] = textResponse;

			if ( this.callBackFunctionEnd ) {
				this.callBackFunctionEnd( this.includedFiles[this.urlFile], this.request.status );
			}

		}

	}

};


/* Производный класс от абстрактного объекта load */
Ajax = function ( ) { }
Ajax.prototype = load;
