/**
 * @author mpoisson
 * @version 1.0
 * Class used to send requests to server and receive responses.
 */
function AjaxConnector() {
    this._xRequest = this.createHttpRequest();
}

// Private variables
AjaxConnector.prototype._xRequest = null;
AjaxConnector.prototype._service = null;

AjaxConnector.prototype.createHttpRequest = function() {
	var httpRequest = null;
	if ( window.ActiveXObject )  {
        var mSoftVersions = ['MSXML2.DOMDocument.5.0','MSXML2.DOMDocument.4.0', 'MSXML2.DOMDocument.3.0',
         					 'MSXML2.DOMDocument.2.0','MSXML2.DOMDocument','Microsoft.XmlDom',
         					 'Msxml2.XMLHTTP','Microsoft.XMLHTTP'];

        for (i=0; i< mSoftVersions.length; i++)  {
            try {
                httpRequest = new ActiveXObject (mSoftVersions[i]);
            }  catch (  e  )  {
				//alert("Error 1" + e.name + " - " + e.message);
			}
        }
    }  else if (!httpRequest && typeof XMLHttpRequest != 'undefined')  {
        try {
            httpRequest = new XMLHttpRequest();
			//this.http.multipart = true;
        }  catch (  e  )  {
			//alert("Error 2" + e.name + " - " + e.message);
		}
    }  else if (!httpRequest && window.createRequest)  {
        try {
            httpRequest = window.createRequest;
        }  catch (  e  )  {
			//alert("Error 3" + e.name + " - " + e.message);
		}
    }

	return httpRequest;

};

// Handles asynchonous calls responses of onreadystatechange event
AjaxConnector.prototype.manageResponse = function () {
	var documentToLoad;
	try {
		if (this._xRequest.readyState == 4) {
			if (this._xRequest.status == 200) {
				try {
					// Used with xml larger than 4096 bytes (Firefox only)
					this._xRequest.responseXML.normalize();
				} catch (e) {
					// Fails if navigator is other than firefox
				}

				try {
					documentToLoad = this._xRequest.responseXML.documentElement;
				} catch (e) {
					this._service.getResult().setErrorCode(10000);
					this._service.getResult().setErrorDescription('Unexpected error, service aborted!');
				}

				try {
					this._service.getResult().loadXML(documentToLoad);
				} catch (e) {
					this._service.getResult().setErrorCode(10001);
					this._service.getResult().setErrorDescription('Error loading xml response!');
				}

				if (oEnviroment.getDebugMode()) {
					logServiceResponse(this._service);
				}

				// This is only for square, is not generic and must be removed on other projects
				if (this._service.getResult().getErrorCode() == 99) {

					var helper = new UserHelper();
					helper.deleteSession();
					KillSessionScheduler();
					oEnviroment.getUser().clear();

					gotoURL('login.php', 'main');

				} else {
					this._service.throwOnServiceComplete();
				}

			} else {
				//check if an error callback handler has been defined
				if(this.onError !== undefined) {
					//pass an object to the callback handler with info
					//about the error
					this.onError({status:this_request.status,
							statusText:this._request.statusText});
				}
			}
		}
	} catch (e) {
		this._service.getResult().setErrorCode(10002);
		this._service.getResult().setErrorDescription('Unexpected error, Service status error!');
	}
};

// Private: build service parameter querystring
AjaxConnector.prototype._buildParameters = function() {
	var parameters = "";
    for (i=0; i < this._service.getParamCount(); i++) {
		if (i>0) { parameters += '&'; }
		parameters += this._service.getKey(i) + "=" + encodeURIComponent(this._service.getParameterByIndex(i));
	}
	return parameters;
};

// Executes Asynchronous call
AjaxConnector.prototype.asyncRun = function (service) {
	this._service = service;
	// As onreadystatechange event does not handle "this" operator
	// we must set local variables in order to call object instance
	// methods and variables.
	if (oEnviroment.getDebugMode()) {
		logServiceCall(service);
	}
	var obj = this;
	//this._xRequest = this.createHttpRequest();
	if (this._xRequest) {
		var parameters = this._buildParameters();
		var targetUrl =  this._service.getURL() + "?service=" + this._service.getName() + "&sid=" + this._service.getSID();
		// Check if we need parameter encoding process
		if (this._service.getMethod() == 'GET') { targetUrl += '&' + parameters; }
		this._xRequest.onreadystatechange = function () { obj.manageResponse(); };
		this._xRequest.open(this._service.getMethod(), targetUrl, true);
	    this._xRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
		this._xRequest.send(parameters);
	}
};

// Executes Synchronous call
AjaxConnector.prototype.syncRun = function (service) {
	this._service = service;

	var obj = this;
	if (oEnviroment.getDebugMode()) {
		logServiceCall(service);
	}

	//this._xRequest = this.createHttpRequest();
	if (this._xRequest) {

		var parameters = this._buildParameters();

		var targetUrl =  this._service.getURL() + "?service=" + this._service.getName() + "&sid=" + this._service.getSID();
		// Check if we need parameter encoding process
		if (this._service.getMethod() == 'GET') { targetUrl += '&' + parameters; }
		this._xRequest.open(this._service.getMethod(), targetUrl, false);
	    this._xRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
		this._xRequest.send(parameters);
		if (this._xRequest.status == 200) {
			try {
				// Used with xml larger than 4096 bytes (Firefox only)
				this._xRequest.responseXML.normalize();
			} catch (e) {
				// Fails if navigator is other than firefox
			}

			this._service.getResult().loadXML(this._xRequest.responseXML.documentElement);
		}
	}

	return this._service;
};

// Aborts a call
AjaxConnector.prototype.abort = function () {
	if (this._xRequest) {
	    this._xRequest.abort();
	}
};