
function parseXml(strXml)
{
	try //Internet Explorer
	{
		xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async="false";
		xmlDoc.loadXML(strXml);
	}
	catch(e)
	{
		try //Firefox, Mozilla, Opera, etc.
		{
			parser=new DOMParser();
			xmlDoc=parser.parseFromString(strXml,"text/xml");
		}
		catch(e) {alert(e.message)}
	}
	return xmlDoc;
}

function PXml(strXml)
{
	// call example:
	//var retVals = {}						- or -
	//var retVals = {a:1, b:'!!', c:dt}		if you want to assign default values
	//var xmlDoc = pXml(strXml, retVals)
	// a param, called "callerName" is always returned (it's the root node of xml returned by PHP "BuildAjaxResponse" function,
	// that is the name of the "action" requested by ajax call.
	//alert(strXml);
	// following lines refers to arguments with index 1 because it assumes the 1st parameter (strXml, arg index=0) is mandatory!
	strXml = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>'+strXml;
	var xd = parseXml(strXml);
	var xmlRoot = xd.documentElement;
	var intNOfParams = xd.getElementsByTagName('param').length;
	var params = xd.getElementsByTagName('param');
	arguments[1]['callerName'] = xmlRoot.nodeName;
	for (i=0; i<intNOfParams; i++) {
		var names = params[i].getElementsByTagName("name");
		var values = params[i].getElementsByTagName("value");
		var parName = names[0].firstChild.nodeValue;
		var parValue;
		if (values[0].firstChild != null)
		{
			parValue = values[0].firstChild.nodeValue;
			arguments[1][parName] = parValue;
		}
	}
}

function AjaxSendRequest(strAction, strMethod, strUrl, varParams, strCallBackFunction, blnTimeStamp) 
{
	// strAction: 	Concept similar to function name, will be checked into server-side script to decide which code to run
	//				it will be attached to url by this function.
	// strMethod: 	Must be 'GET' or 'POST'
	// strUrl:		The Url to call
	// strParams:	Parameters in the "par1=val1&par2=val2&parn=valn" format (standard url format).
	//				They will be attached to url or to content depending by the call method.
	// strCallBackFunction:	the function that will get the result from the server-side script execution
	// blnTimeStamp:If true, a timestamp value is added to make the url unique (see about caching issues below)
	//				this parameter makes sense only for GET calls (POST calls are never cached!)
	//				Default: true
	
	// This function is pretty similar to the 'SjaxSendRequest', except for the fact that this call is Asyncronous.
	// That means the browser will NOT be waiting for the server response before to proceed through the code execution.
	// A sort of "trigger" is raised when the server response is complete, and the callback function is called.
	// The response, usually, can be made of pure html or xml. See Wiki for more details.
	/*******************************************************************************************************
	a brief consideration about using of GET or POST methods in AJAX (and not only):
	. If the call is to retrieve data from the server then use GET. 
	. If the value to be retrieved is expected to vary over time as a result of other processes updating it 
		then add a current time parameter to what you are passing in your GET call so that the later calls 
		will not use an earlier cached copy of the result that is no longer correct. 
	. If your call is going to write any data at all to the server then use POST.
	*******************************************************************************************************/
	
	switch (varParams.constructor) {
	case String:
		// If it's a string, then the format par1=val1&par2=val2 etc... is assumed.
		// In this case, it is no longer possible to encode it before to pass to Ajax.
		var strParams = varParams;
		break;
	case Array:
		// If it's an Array, we assume that it is an array of form elements
		// Then, we serialize as needed, encoding in the meantime.
		var i = 0, length = varParams.length;
		var strParams = '';
		for (var objP = varParams[0]; i<length; objP=varParams[++i] ) {
			if (i>0) {
				strParams += '+';
			}
			strParams += encodeURIComponent(objP.id) + '=' + encodeURIComponent(objP.value);
		}
		break;
	case Object:
		// If it's an Object, we assume that it is made of key/value pairs (hash)
		// Then again, we serialize as needed, encoding in the meantime.
		var i = 0, length = varParams.length;
		var strParams = '';
		if (length == undefined) {
			// All other cases except Internet Explorer
			for (var objP in varParams) {
				var objTmp = varParams[objP];
				if (typeof(objTmp) == 'object') {
					strParams += encodeURIComponent(objTmp.id) + '=' + encodeURIComponent(objTmp.value) + '&';
				} else {
					strParams += encodeURIComponent(objP) + '=' + encodeURIComponent(objTmp) + '&';
				}
			}
			strParams = strParams.substr(0, strParams.length - 1);
		} else {
			// Internet Explorer's case
			for (var objP = varParams[0]; i<length; objP=varParams[++i] ) {
				if (i>0) {
					strParams += '&';
				}
				strParams += encodeURIComponent(objP.id) + '=' + encodeURIComponent(objP.value);
			}
		}
	}
	if(blnTimeStamp===undefined) blnTimeStamp=true;
	var xmlHttpReq = false;
	var self = this;
	// Mozilla/Safari
	if (window.XMLHttpRequest) {
		xmlHttpReq = new XMLHttpRequest();
	}
	// IE
	else if (window.ActiveXObject) {
		xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
	}
	var strUrlToSend;
	switch (strMethod.toUpperCase()) {
	case 'GET': 
		strUrlToSend = strUrl+'?action='+strAction+'&'+strParams
		if(blnTimeStamp===true) strUrlToSend += "&timestamp=" + new Date().getTime();
		xmlHttpReq.open('GET', strUrlToSend, true);
		xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		//xmlHttpReq.setRequestHeader('Content-Type', 'text/html; charset=ISO-8859-1');
		break;
	case 'POST':
		strUrlToSend = strUrl+'?action='+strAction;
		xmlHttpReq.open('POST', strUrl+'?action='+strAction, true);
		xmlHttpReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		//xmlHttpReq.setRequestHeader('Content-Type', 'text/html; charset=ISO-8859-1');
		xmlHttpReq.setRequestHeader("Content-length", strParams.length);
		xmlHttpReq.setRequestHeader("Connection", "close");
		break;
	}
	xmlHttpReq.onreadystatechange = function() {
		if (xmlHttpReq.readyState == 4) {
			eval(strCallBackFunction + '(xmlHttpReq.responseText)');
		}
	}
	switch (strMethod.toUpperCase()) {
	case 'GET': 
		xmlHttpReq.send(strUrl+'?action='+strAction+'&'+strParams);
		break;
	case 'POST':
		xmlHttpReq.send(strParams);
		break;
	}
}


function SjaxSendRequest(strAction, strMethod, strUrl, varParams, blnTimeStamp) 
{
	// strAction: 	Concept similar to function name, will be checked into server-side script to decide which code to run
	//				it will be attached to url by this function.
	// strMethod: 	Must be 'GET' or 'POST'
	// strUrl:		The Url to call
	// strParams:	Parameters in the "par1=val1&par2=val2&parn=valn" format (standard url format).
	//				They will be attached to url or to content depending by the call method.
	// blnTimeStamp:If true, a timestamp value is added to make the url unique (see about caching issues below)
	//				this parameter makes sense only for GET calls (POST calls are never cached!)
	//				Default: true
	
	// This function is pretty similar to the 'AjaxSendRequest', except for the fact that this call is Syncronous.
	// That means the browser will be waiting for the server response before to proceed through the code execution.
	// Due to his nature, no callback function can be specified when calling this function
	/*******************************************************************************************************
	a brief consideration about using of GET or POST methods in AJAX (and not only):
	. If the call is to retrieve data from the server then use GET. 
	. If the value to be retrieved is expected to vary over time as a result of other processes updating it 
		then add a current time parameter to what you are passing in your GET call so that the later calls 
		will not use an earlier cached copy of the result that is no longer correct. 
	. If your call is going to write any data at all to the server then use POST.
	*******************************************************************************************************/

	// case in which varPar is a string:
	//varParams = 'a=uno&b=2';
	
	// case in which varPar is an Array:
	//varParams = [];
	//varParams.push (document.getElementById('txtImp_6353_1'));
	//varParams.push (document.getElementById('txtImp_6353_2'));
	
	// case in which varPar is an hash of simple elements (numbers, strings):
	//var varParams = {a:1, b:2, c:'tre'};
	
	// case in which varPar is a mixed hash with simple types and objects:
	//var objC = document.getElementById('txtImp_6353_1');
	//var varParams = {a:1, b:'due', c:objC};
	switch (varParams.constructor) {
	case String:
		// If it's a string, then the format par1=val1&par2=val2 etc... is assumed.
		// In this case, it is no longer possible to encode it before to pass to Ajax.
		var strParams = varParams;
		break;
	case Array:
		// If it's an Array, we assume that it is an array of form elements
		// Then, we serialize as needed, encoding in the meantime.
		var i = 0, length = varParams.length;
		var strParams = '';
		for (var objP = varParams[0]; i<length; objP=varParams[++i] ) {
			if (i>0) {
				strParams += '+';
			}
			strParams += encodeURIComponent(objP.id) + '=' + encodeURIComponent(objP.value);
		}
		break;
	case Object:
		// If it's an Object, we assume that it is made of key/value pairs (hash)
		// Then again, we serialize as needed, encoding in the meantime.
		var i = 0, length = varParams.length;
		var strParams = '';
		if (length == undefined) {
			// All other cases except Internet Explorer
			for (var objP in varParams) {
				var objTmp = varParams[objP];
				if (typeof(objTmp) == 'object') {
					strParams += encodeURIComponent(objTmp.id) + '=' + encodeURIComponent(objTmp.value) + '&';
				} else {
					strParams += encodeURIComponent(objP) + '=' + encodeURIComponent(objTmp) + '&';
				}
			}
			strParams = strParams.substr(0, strParams.length - 1);
		} else {
			// Internet Explorer's case
			for (var objP = varParams[0]; i<length; objP=varParams[++i] ) {
				if (i>0) {
					strParams += '&';
				}
				strParams += encodeURIComponent(objP.id) + '=' + encodeURIComponent(objP.value);
			}
		}
	}
	//alert(strParams);

	if(blnTimeStamp===undefined) blnTimeStamp=true;
	var xmlHttpReq = null;
	//var self = this;
	// Mozilla/Safari
	if (window.XMLHttpRequest) {
		xmlHttpReq = new XMLHttpRequest();
	}
	// IE
	else if (window.ActiveXObject) {
		xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
	}
	var strUrlToSend;

	switch (strMethod.toUpperCase()) {
	case 'GET': 
		strUrlToSend = strUrl+'?action='+strAction+'&'+strParams
		if(blnTimeStamp===true) strUrlToSend += "&timestamp=" + new Date().getTime();
		xmlHttpReq.open('GET', strUrlToSend, false);
		xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		//xmlHttpReq.setRequestHeader('Content-Type', 'text/html; charset=ISO-8859-1');
		break;
	case 'POST':
		strUrlToSend = strUrl+'?action='+strAction;
		xmlHttpReq.open('POST', strUrl+'?action='+strAction, false);
		xmlHttpReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		//xmlHttpReq.setRequestHeader('Content-Type', 'text/html; charset=ISO-8859-1');
		xmlHttpReq.setRequestHeader("Content-length", strParams.length);
		xmlHttpReq.setRequestHeader("Connection", "close");
		break;
	}
	/*
	xmlHttpReq.onreadystatechange = function() {
		if (xmlHttpReq.readyState == 4) {
			eval(strCallBackFunction + '(xmlHttpReq.responseText)');
		}
	}
	*/
	switch (strMethod.toUpperCase()) {
	case 'GET': 
		xmlHttpReq.send(strUrl+'?action='+strAction+'&'+strParams);
		break;
	case 'POST':
		xmlHttpReq.send(strParams);
		break;
	}

	return xmlHttpReq.responseText;
}

/**
*
*  UTF-8 data encode / decode
*  http://www.webtoolkit.info/
*
**/

function Utf8Encode(string)
{
	// public method for url encoding
	if (string == undefined) {
		return '';
	} else {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
		for (var n = 0; n < string.length; n++) {
			var c = string.charCodeAt(n);
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
		}
		return utftext;
	}
}

function Utf8Decode(utftext)
{
	// public method for url decoding
	if (utftext == undefined) {
		return '';
	} else {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
		while ( i < utftext.length ) {
			c = utftext.charCodeAt(i);
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
		}
		return string;
	}
}

function DecodeHtmlSpecialChars(htmlText)
{
	// this function is supposed to be the opposite of PHP htmlSpecialChars function.
	// according to php documentation,
	// '&' (ampersand) becomes '&amp;'
	// '"' (double quote) becomes '&quot;' when ENT_NOQUOTES is not set.
	// ''' (single quote) becomes '&#039;' only when ENT_QUOTES is set.
	// '<' (less than) becomes '&lt;'
	// '>' (greater than) becomes '&gt;'
	if (!((htmlText == undefined) || (htmlText == ''))) {
		var strDecodedText = htmlText.replace('&amp;', '&').replace('&quot;', '"').replace('&#039;', "'").replace('&lt;', '<').replace('&gt;', '>');
	}
	return strDecodedText;
}