

function ajax(ajaxName) {

	// controllo se e' specificato il nome dell'oggetto
	if (ajaxName)
		this.name = ajaxName;
	else	
		this.name = 'asocket';

	this.asyncronous = true;
	this.goCB = null;
	this.onError = null;
	this.stillExecuting = false;
	this.useEscape = false;

	var A;
	try {
		A=new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
		try {
			A=new ActiveXObject("Microsoft.XMLHTTP");
		} catch (oc) {
			A=null;
		}
	}
	if(!A && typeof XMLHttpRequest != "undefined")
		A = new XMLHttpRequest();
		
		
		
	// controllo che piattaforma e'
	if (A) {
		this.available = true;
	} else {
		this.available = false;
	}
	
	// distruggo l'oggetto
	this.ajaxObject = A;

	this.init = function() {
		
		// controllo che piattaforma e' Microsoft uso XMLHttp
		var A;
		try {
			A = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				A = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (oc) {
				A = null;
			}
		}
		if(!A && typeof XMLHttpRequest != "undefined")
			A = new XMLHttpRequest();
		
		return A;	
	}

	this.abort = function() {
		this.stillExecuting = false;
		try {
			if (this.ajaxObject) {
				this.ajaxObject.abort();
				delete this.ajaxObject;
				this.ajaxObject = null;
			}
		} catch (e) {
			
		}
	}

	this.getXml = function(remoteCall) {
		var ajaxObj = this.ajaxObject;
		// controllo se l'oggetto esiste
		if (ajaxObj) {
		
			var aj = this;
		
			ajaxObj.open("GET", remoteCall, false);
			ajaxObj.send("");
			
			var xmlRes = ajaxObj;
			
			// restituisco l'xml
			return xmlRes;
		}
	}

	this.getResponse = function(remoteCall, cb, getObj) {
		
		var ajaxObj = null;
		if (!this.ajaxObject) {
			this.ajaxObject = this.init();
			ajaxObj = this.ajaxObject;
	 	} else {
			ajaxObj = this.ajaxObject;
		}
		
		// controllo se l'oggetto esiste
		if (ajaxObj) {
		
			var aj = this;
			
			
			
			ajaxObj.open("GET", remoteCall, this.asyncronous);
			
			
			ajaxObj.setRequestHeader("Method", "GET " + remoteCall + " HTTP/1.1");
			//ajaxObj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			
			
			// controllo se e' asincrono
			if (this.asyncronous) {
				ajaxObj.onreadystatechange = function() {
					if (ajaxObj.readyState != 4) 
						return;
					
					var status;
					var data;
					
					
					if (getObj) {
						// nodi sotto root cnAjax
						cb(aj, ajaxObj);
					} else {
						cb(ajaxObj.responseText);
					}
					if (!document.all) {
						delete ajaxObj;
						delete this.ajaxObject;
						this.ajaxObject = null;
					}
				}
			}
			
			
			
			ajaxObj.send("");
			
			
			
			if (!this.asyncronous) {
				// restituisco i dati in maniera sincrona rispetto 
				// alla chiamatata del metodo
				if (!getObj) {
					var data = ajaxObj.responseText;
					return data;
				} else {
					var resObject = ajax_responseXmlToObject((ajaxObj.responseXML && ajaxObj.responseXML.childNodes.length) ? ajaxObj.responseXML : ajaxObj.responseText);
					
					return resObject;
				}
			}
			
			
			
		}
		
		
	}
	
	this.getObject = function(remoteCall, cb) {
	
		if (this.asyncronous) {
			if (cb)
				this.goCB = cb;
			else
				this.goCB = this.callBackFunction;
			
			this.getResponse(remoteCall, ajax_getObjectCB, true);
		} else {
			// restituisco l'oggetto
			return this.getResponse(remoteCall, null, true);
		}
	}
	
	this.getObjectCB = function(nodes) {
		try {
			this.goCB(ajax_responseXmlToObject(nodes));
		} catch (exc) {
		
			
			try {console.log(exc);}catch(e) {};
		
			if (this.onError)
				this.onError(exc);
		}
		//this.goCB = null;
	}
	
	this.postObject = ajax_postObject;
}



function ajax_postObject(remoteCall, o, cb) {
	
	var ajaxObj = null;
	if (!this.ajaxObject)
		this.ajaxObject = this.init();
	
	ajaxObj = this.ajaxObject;

	if (this.asyncronous) {

		if (cb)
			this.goCB = cb;
		else
			this.goCB = this.callBackFunction;
	}
		
	// ciclo per tutte le proprieta
	var urlEncoded = '';
	
	for (prop in o) {
		
		// Firefox 1.0.7 o prec non implementa
		// instanceof correttamente su MacOs X
		// uso questo workaround sperando che il problema
		// venga risolto con la versione 1.5
		
		//if (o[prop] instanceof Array) {
		
		if (typeof(o[prop]) != 'function') {
			if (o[prop] && o[prop].join) {
				for (var i = 0; i < o[prop].length; i++) {
					if (!this.useEscape)
						urlEncoded += '&'+prop+'='+encodeURI(o[prop][i]).split('&').join('%26').split('+').join('%2B');
					else
						urlEncoded += '&'+prop+'='+escape(o[prop][i]);
				}
			} else {
				
				if (!this.useEscape)
					urlEncoded += '&'+prop+'='+encodeURI(o[prop]).split('&').join('%26').split('+').join('%2B');
				else
					urlEncoded += '&'+prop+'='+escape(o[prop]).split('+').join('%2B');
				
			}
		}
	}
	try {
		
	} catch (e) {
	
	}
	
	// tolgo il primo carattere &
	urlEncoded = urlEncoded.substr(1);

		
	try {console.log(urlEncoded);}catch(e){};
	
	
	var ajaxObj = this.ajaxObject;
	var aj = this;
	// controllo se l'oggetto esiste
	if (ajaxObj) {

		// imposto gli header http appropriati
		ajaxObj.open("POST", remoteCall, this.asyncronous);
		ajaxObj.setRequestHeader('Method', 'POST ' + remoteCall + ' HTTP/1.1');
		ajaxObj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		ajaxObj.setRequestHeader('Content-Length', urlEncoded.length);
		
		
		// controllo se e' asincrono
		if (this.asyncronous) {
			ajaxObj.onreadystatechange = function() {
				
					
				if (ajaxObj.readyState != 4) 
					return;
				
				aj.stillExecuting = false;
				
				// nodi sotto root cnAjax
				ajax_getObjectCB(aj, ajaxObj);
				
				if (!document.all) {
					delete ajaxObj;
					delete this.ajaxObject;
					this.ajaxObject = null;
				}
					
				
			}
		} else {
			ajaxObj.onreadystatechange = new function() {};
		}
		
		aj.stillExecuting = true;
		ajaxObj.send(urlEncoded);

		
		if (!this.asyncronous) {
		
		
			aj.stillExecuting = false;
			// restituisco i dati in maniera sincrona rispetto 
			// alla chiamatata del metodo
			
			var resObject = null;
			try {

				try {

					resObject = ajax_responseXmlToObject((ajaxObj.responseXML && ajaxObj.responseXML.childNodes.length) ? ajaxObj.responseXML : ajaxObj.responseText);
					
					
					try {
						console.log(resObject);
					} catch (e) {
						
					}
				} catch (exc) {
					if (this.onError)
						this.onError(exc);
				}
				
				
			} catch (e) {

			}
		
			return resObject;
		}
		
		
		
	}

}


function ajax_responseXmlToObject(xmlResponse) {
	
	
	var d = new Date();
	try {console.log(d.getSeconds() + ' ' + d.getMilliseconds());} catch (e) {};

	if (xmlResponse.childNodes) {
	
		try {console.log('XMLResponse');} catch (e) {};

		for (var i = 0; i < xmlResponse.childNodes.length; i++) {

			if (parseInt(xmlResponse.childNodes[i].nodeType) == 1) {
				var nodeName = xmlResponse.childNodes[i].nodeName;
				if ((nodeName == 'cnAjax') || (nodeName == 'ca') || (nodeName == 'hyphenAjax')) {
					var res = ajax_xmlToObject(xmlResponse.childNodes[i].childNodes, nodeName == 'ca');
					var d = new Date();
					try {console.log(d.getSeconds() + ' ' + d.getMilliseconds());} catch (e) {};
					try {console.log(res);}catch(e) {};
					return res;
					break;
				} else {
					// xml semplice: provo a trasformarlo in oggetto
					if (xmlResponse.childNodes[i].nodeName && (xmlResponse.childNodes[i].nodeName != '#comment') && (xmlResponse.childNodes[i].nodeName != 'xml')) {
						return ajax_simpleXmlToObject(xmlResponse.childNodes[i].childNodes);
						break;
					}
				}
			}
		}
		
		return null;
	} else {
		// oggetto javascript
		// .split('\'').join('\\\'')
		try {
			res = eval('___o = ' + xmlResponse);
		} catch (e) {
			try{console.log(e)}catch(e1){};
			res = null;
		}
		
		var d = new Date();
		try {console.log(d.getSeconds() + ' ' + d.getMilliseconds());} catch (e) {};
		try {console.log(res);}catch(e) {};
		
		return res;
	}
	
	

	
}


function ajax_simpleXmlToObject(xmlNodes) {
	var res = new Object();
	var atLeastOne = false;
	for (var i = 0; i < xmlNodes.length; i++) {
		if (parseInt(xmlNodes[i].nodeType) == 1) {
			// controllo se ha altri nodi
			atLeastOne = true;
			if (xmlNodes[i].childNodes.length > 1) {
				res[xmlNodes[i].nodeName] = ajax_simpleXmlToObject(xmlNodes[i].childNodes);
			} else {
				res[xmlNodes[i].nodeName] = ajax_getNodeValue(xmlNodes[i]);	
			}
		}
	}
	
	if (!atLeastOne) {
		// lettura risultato
		res = (xmlNodes[0].nodeValue);
	}
	
	
	return res;
}

function ajax_xmlToObject(xmlNodes, shortForm) {
	var res = new Object();
	// ciclo per tutti i nodi
	for (var i = 0; i < xmlNodes.length; i++) {
		if (parseInt(xmlNodes[i].nodeType) == 1) {
			var objValue = null;
			var xType = xmlNodes[i].getAttribute(shortForm ? 't' : 'xtype');
			
			if (!xType)
				xType = xmlNodes[i].getAttribute('type');
			
			switch (xType) {
			case 'Var':		// variabile "variant"
			case 'V':		
				objValue = ajax_getNodeValue(xmlNodes[i]);
				if (objValue != null) {
					if (isNaN(objValue)) {
						if ((objValue.toLowerCase() == 'false') || (objValue.toLowerCase() == 'true')) {
							objValue = objValue.toLowerCase() == 'true';
							
						}
					} else {
						objValue = parseFloat(objValue);
					}
				}
				break;
			case 'Real':
			case 'R':
				objValue = ajax_getNodeValue(xmlNodes[i]);
				objValue = parseFloat(objValue);
				break;
			case 'Int':
			case 'I':
				objValue = ajax_getNodeValue(xmlNodes[i]);
				objValue = parseInt(objValue);
				break;
			case 'Bool':
			case 'B':
				objValue = ajax_getNodeValue(xmlNodes[i]);
				objValue = (objValue == '1') || (objValue == 'true') || (objValue == 'True');
				break;
			case 'String':
			case 'S':
				objValue = ajax_getNodeValue(xmlNodes[i]);
			
				//objValue = xmlNodes[i].firstChild.nodeValue;
				break;
			case 'Array':
			case 'A':
				objValue = new Array();
				var thisNodes = xmlNodes[i].childNodes;
				if (thisNodes) {
					for (var j = 0; j < thisNodes.length; j++) {
						// controllo se e' un elemento
						if (parseInt(thisNodes[j].nodeType) == 1) {
							objValue[objValue.length] = ajax_xmlToObject(thisNodes[j].childNodes, shortForm);
						}
					}
				}
				break;
			case 'IntArray':
			case 'IA':
				objValue = new Array();
				var thisNodes = xmlNodes[i].childNodes;
				if (thisNodes) {
					for (var j = 0; j < thisNodes.length; j++) {
						// controllo se e' un elemento
						if (parseInt(thisNodes[j].nodeType) == 1) {
							objValue[objValue.length] = parseInt(ajax_getNodeValue(thisNodes[j]));
						}
					}
				}
				break;
			case 'StringArray':
			case 'SA':
				objValue = new Array();
				var thisNodes = xmlNodes[i].childNodes;
				if (thisNodes) {
					for (var j = 0; j < thisNodes.length; j++) {
						// controllo se e' un elemento
						if (parseInt(thisNodes[j].nodeType) == 1) {
							objValue[objValue.length] = ajax_getNodeValue(thisNodes[j]);
						}
					}
				}
				break;
			case 'Object':
			case 'O':
				objValue = ajax_xmlToObject(xmlNodes[i].childNodes, shortForm);
				break;
			default:
				objValue = ajax_getNodeValue(xmlNodes[i]);
				//objValue = xmlNodes[i].firstChild.nodeValue;
				break;
			}
			res[xmlNodes[i].getAttribute(shortForm ? 'n' : 'name')] = objValue;
		}
	}
	return res;	
}

// funzione per lettura valore del nodo xml
function ajax_getNodeValue(node) {
	
	var objValue = null;
	if (node.childNodes.length > 1) {
		objValue = node.childNodes[1].nodeValue;
	} else {
		try {
			objValue = node.firstChild.nodeValue;
		} catch (e) {
			objValue = null;
		}
	}
	
	return objValue;
	
}

function ajax_getObjectCB(ajObj, xml) {
	ajObj.getObjectCB((xml.responseXML && xml.responseXML.childNodes.length) ? xml.responseXML: xml.responseText);
	
} 



//onsubmit="return Hyphen.Sockets.postForm(event, this);"
