/*
* AjaxHelper
* -----------------------
* @author       : Filatov Dmitry <alpha@design.ru>
* @last_modified: 09.03.2007
*/

function AjaxHelper(	
	oObject,
	sUrl,
	sMethod,
	aParams,
	oOptions
	) {
	
	this.oObject = oObject;
	this.sUrl = sUrl;
	this.sMethod = sMethod;
	this.aParams = aParams || [];
	
	this.oOptions = Common.Object.extend(		
		{
			bIgnoreCache : true
		},
		oOptions
		);
	
}

AjaxHelper.READY_STATE_UNITIALIZED = 0;
AjaxHelper.READY_STATE_LOADING     = 1;
AjaxHelper.READY_STATE_LOADED      = 2;
AjaxHelper.READY_STATE_INTERACTIVE = 3;
AjaxHelper.READY_STATE_COMPLETE    = 4;	

AjaxHelper.getTransport = function() {
	
	if(window.XMLHttpRequest) {
		return new XMLHttpRequest();
	}
		
	if(window.ActiveXObject) {			
		
		try {
			return new ActiveXObject('Msxml2.XMLHTTP');
		}
		catch(oError) {
			return new ActiveXObject('Microsoft.XMLHTTP');
		}
			
	}
			
	return null;
	
};

AjaxHelper.generateUid = function() {
	
	var sUid = '';
	
	for(var i = 0; i < 4; i++) {	
		sUid += (i > 0? '-' : '') + Math.floor(Math.random() * 9999);	
	}	
	
	return sUid;
		
};

AjaxHelper.encodeForRequest = function(sText) { 
	console.log("AjaxHelper.encodeForRequest sText:", sText);
	return escape(AjaxHelper.encodeUTF8(sText));
	
};

AjaxHelper.encodeUTF8 = function(sText) {

	sText = sText.replace(/\r\n/g, '\n');
	
	var sResult = "";

	for(var i = 0, sCharCode; i < sText.length; i++) {

		sCharCode = sText.charCodeAt(i);

		if(sCharCode < 128) {
			sResult += String.fromCharCode(sCharCode);
		}
		else if((sCharCode > 127) && (sCharCode < 2048)) {
			
			sResult += String.fromCharCode((sCharCode >> 6) | 192);
			sResult += String.fromCharCode((sCharCode & 63) | 128);
		
		}
		else {
	
			sResult += String.fromCharCode((sCharCode >> 12) | 224);
			sResult += String.fromCharCode(((sCharCode >> 6) & 63) | 128);
			sResult += String.fromCharCode((sCharCode & 63) | 128);
			
        }

	}

    return sResult;
    
};

AjaxHelper.decodeUTF8 = function(sText) {

	var
		sResult = "",
		i = 0,
		c = 0,
		c1 = 0,
		c2 = 0
		;

	while(i < sText.length) {

		c = sText.charCodeAt(i);

		if(c < 128) {
            	
			sResult += String.fromCharCode(c);
            i++;
                
		}
		else if((c > 191) && (c < 224)) {
            	
			c2 = sText.charCodeAt(i + 1);
			sResult += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
			i += 2;
                
		}
		else {
            	
			c2 = sText.charCodeAt(i + 1);
			c3 = sText.charCodeAt(i + 2);
			sResult += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
			i += 3;
                
		}

    }

	return sResult;
	
};

AjaxHelper.prototype = {
	
	send : function() {
	
		var
			sQueryParams = '',
			iParamsCount = 0,
			sUid = AjaxHelper.generateUid()
			;
							
		this.aParams.foreach(function(mKey, mParam) {			
			sQueryParams += (++iParamsCount == 1? '' : '&') + mKey + '=' + AjaxHelper.encodeForRequest(mParam);
		});
			
		var oRequest = AjaxHelper.getTransport();
		
		if(oRequest) {
		
			oRequest.open(
				this.sMethod,
				this.sUrl + (this.oOptions.bIgnoreCache? '?uid=' + sUid : ''),
				true
				);
			
			oRequest.setRequestHeader(
				'Content-type',
				'application/x-www-form-urlencoded; text/xml; charset=UTF-8'
				);							
			
			var oThis = this;
		
			oRequest.onreadystatechange = function() {
		
				oThis.handleResponse(oRequest);
		
			}
			
			oRequest.send(sQueryParams);
			
			return sUid;
			
		}
		
	},
	
	handleResponse : function(oRequest) {
	
		try {
		
			if(oRequest.readyState != AjaxHelper.READY_STATE_COMPLETE) {				
				return;
			}
				
			if(this.success(oRequest)) {					
				if(this.oObject.ajaxUpdate) {						
					this.oObject.ajaxUpdate(oRequest);
				}				
			}
			else if(this.oObject.ajaxError) {								
				this.oObject.ajaxError(oRequest);
			}			
		
		}
		catch(oException) {}
	
	},
	
	success : function(oRequest) {
	
		return oRequest.status == 0 ||
			(oRequest.status >= 200 && oRequest.status < 300);
	
	}
	
}