/*
	Class UserHttpRequest
	Makes AJAX Http Request and calls defined callback
	@param:
		qUrlPath = full path to server script
		vars = [{'name':'GET_var_name', 'value:'GET_var_value'}, {'name':'GET_var_name', 'value:'GET_var_value'}, ...]
*/
	function UserHttpRequest (vars, qUrlPath) {

		var loadAttemptsTotal = 3;

		this.httpRequest = new JSHttpRequest();
		this.qTimeout = 0;
		this.maxTimeout = 15*1000;	// 15 sec
		this.qUrlPath = qUrlPath;
		this.q = new Object();
		this.vars = (vars) ? vars : new Array();
		this.autoReload = false;	// repeat load after timeout exceeding
		this.loadAttempt = loadAttemptsTotal;

		var this_closure = this; // enclose object's properties and method in local variable

		/*
			Clear Callback Methods
			Overload them in a caller function to process proper JS Http Callback
			Important: run method Clear_Timeout() if data is loaded successfull to prevent Exceed Timeout procedure execution
		*/
		this.onState_Uninitialized = function() {}
		this.onState_Loading = function() {}
		this.onState_Loaded = function() {}

		this.onSate_Interactive = function() {} // just notified english syntax error :)
		this.onState_Interactive = function() {}

		this.onSate_Complete = function() {} // just notified english syntax error :)
		this.onState_Complete = function() {}

		this.onState_Complete_globalCallback = 
			(typeof(window.UserHttpRequest_globalCallback) == 'function') ? window.UserHttpRequest_globalCallback : function() {}

		this.httpRequest.onreadystatechange = function() {
			switch(this_closure.httpRequest.readyState) {
				case 0: this_closure.onState_Uninitialized(); break;
				case 1: this_closure.onState_Loading(); break;
				case 2: this_closure.onState_Loaded(); break;
				case 3: {
					this_closure.onSate_Interactive();
					this_closure.onState_Interactive();
					break;
				}
				case 4: {
					this_closure.onSate_Complete();
					this_closure.onState_Complete();
					this_closure.onState_Complete_globalCallback();
					break;
				}
				default: break;
			}
			this_closure.Clear_Timeout();
		}
		this.Update_Properties = function(vars, qUrlPath) {
			this.q = (delete this.q, new Object());
			this.vars = (vars) ? vars : new Array();
			this.qUrlPath = (qUrlPath) ? qUrlPath : this.qUrlPath;
			this_closure = this;
		}
		this.Prepare = function() {
			this.q.dummy = Math.random();
			this.q.DEBUG_MODE = 0;
			for (var i=0; i < this.vars.length; i++) {
				this.q[this.vars[i].name] = this.vars[i].value;
			}
		}
		this.Load = function(autoReload) {
			this.autoReload = autoReload;	//see vars declaration
			this.Prepare();
			this.Set_Timeout();
			this.Do_BeforSend();
			// send http request
			this.httpRequest.caching = false;	// caching is "false" by defaults
			this.httpRequest.open('GET', this.qUrlPath, true);
			this.httpRequest.send(this.q);
		}
		this.Set_Timeout = function() {
			this.Clear_Timeout();
			this.qTimeout = setTimeout(this.Exceed_Timeout, this.maxTimeout);
		}
		this.Clear_Timeout = function() {
			if (this.qTimeout) clearTimeout(this.qTimeout);
		}
		this.Exceed_Timeout = function() {
			this_closure.httpRequest.abort();
			//alert('Время ожидания загрузки истекло. Попробуйте снова');
			this_closure.Do_After_ExceedTimeout();
			this_closure.Clear_Timeout();
			if (this_closure.autoReload === true) {
				if (this_closure.loadAttempt > 0) {
					this_closure.loadAttempt--;
					this_closure.Load(this_closure.autoReload);
				}
				else {
					this_closure.loadAttempt = loadAttemptsTotal;
				}
			}
		}
		//Overload this methods to assign proper variant actions after exceeding loading timeout limit
		this.Do_After_ExceedTimeout = function() {}
		this.Do_BeforSend = function() {}
	}
