
 function SOAPClientParameters(){
 	var _pl = new Array();
	this.add = function(name, value){
		_pl[name] = value;
		return this;
	}
	this.toXml = function(){
		var xml = "";
		for(var p in _pl){
			if(typeof(_pl[p]) != "function")
			xml += "<" + p + ">" + _pl[p].toString().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</" + p + ">";
	        }
		return xml;
	}

	this.toStringURL = function(){
		var xml = "";
		for(var p in _pl){
			if(typeof(_pl[p]) != "function")
			xml += "&" + p + "=" + _pl[p].toString().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/#/g,'__NUMERAL__').replace(/\+/g,'__SIGNOMAS__')  ;
	        }
		return xml;
	}
	
}

function SOAPClient() {}
SOAPClient.sDebug = "";

SOAPClient.invoke = function(url, meth, parameters, async, callback){
	this.busy = new lyBusy();
	this.busy.start();
	if(async)
		SOAPClient._loadWsdl(url, meth, parameters, async, callback);
	else
		return SOAPClient._loadWsdl(url, meth, parameters, async, callback);
}


SOAPClient._getURL = function(url, pl, sync){
	var xmlHttp = SOAPClient._getXmlHttp();
	var d = new Date();
	var t = d.getTime();
	if(url.indexOf("?")  > 0 )
		url = url + "&"+t;
	else
		url = url + "?"+t;
	if(typeof(pl) == 'object' ) url += pl.toStringURL();
	xmlHttp.open("GET", url, false);
	xmlHttp.send(null);
	var sRet = xmlHttp.responseText;
	sRet = sRet.replace(/\t/g,"");
	sRet = sRet.replace(/\>\n\</g,"><");
	return sRet;
}


SOAPClient._getUrlString = function(url, pl, sync){
	var d = new Date();
	var t = d.getTime();
	if(url.indexOf("?")  > 0 )
		url = url + "&"+t;
	else
		url = url + "?"+t;
	if(typeof(pl) == 'object' ) url += pl.toStringURL();
	return url;
}



SOAPClient._getXML = function(url, sync){
        var xmlHttp = SOAPClient._getXmlHttp();
        var d = new Date();
        var t = d.getTime();
        xmlHttp.open("POST", url + "?"+t, false);
        xmlHttp.send(null);
        return xmlHttp.responseXML;
}


 SOAPClient._loadWsdl = function(url, meth, parameters, async, callback){
    // load from cache?
	var wsdl = SOAPClient_cacheWsdl[url];
	if(wsdl + "" != "" && wsdl + "" != "undefined")
		return SOAPClient._sendSoapRequest(url, meth, parameters, async, callback, wsdl);
    	// get wsdl
	var xmlHttp = SOAPClient._getXmlHttp();
	var dDate  = new Date();
	var sTime = dDate.getTime();
	xmlHttp.open("GET", url + "?wsdl&"+sTime, async);
	if(async) {
		xmlHttp.onreadystatechange = function()	{
			if(xmlHttp.readyState == 4)
				SOAPClient._onLoadWsdl(url, meth, parameters, async, callback, xmlHttp);
		}
	}
	xmlHttp.send(null);
	if (!async)
		return SOAPClient._onLoadWsdl(url, meth, parameters, async, callback, xmlHttp);
}

 SOAPClient_cacheWsdl = new Array();

 SOAPClient._onLoadWsdl = function(url, meth, parameters, async, callback, req){
//	var wsdl = req.responseXML;
	var wsdl = loadXML(req.responseText);	
	SOAPClient_cacheWsdl[url] = wsdl;    // save a copy in cache
	return SOAPClient._sendSoapRequest(url, meth, parameters, async, callback, wsdl);
}

 SOAPClient._sendSoapRequest = function(url, meth, parameters, async, callback, wsdl) {
    // get namespace
	var ns = (wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.documentElement.attributes["targetNamespace"].value;
	 // build SOAP request
	var sr = "<\?xml version=\"1.0\" encoding=\"utf-8\"?>" +
		"<soap:Envelope " +
		"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
		"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
		"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
		"<soap:Body>" +
		"<" + meth + " xmlns=\"" + ns + "\">" +
		parameters.toXml() +
		"</" + meth + "></soap:Body></soap:Envelope>";
    // send request
	var xmlHttp = SOAPClient._getXmlHttp();
	xmlHttp.open("POST", url, async);
	var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + meth;
	xmlHttp.setRequestHeader("SOAPAction", soapaction);
	xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
	if(async) {
		xmlHttp.onreadystatechange = function(){
			if(xmlHttp.readyState == 4)
				SOAPClient._onSendSoapRequest(meth, async, callback, wsdl, xmlHttp);
		}
	}
	xmlHttp.send(sr);
	if (!async)
		return SOAPClient._onSendSoapRequest(meth, async, callback, wsdl, xmlHttp);
}

SOAPClient._onSendSoapRequest = function(meth, async, callback, wsdl, req){
	var o = null;
//	var nd = SOAPClient._getElementsByTagName(req.responseXML, meth + "Response");
//	var nd = SOAPClient._getElementsByTagName(req.responseXML, "sResult");
	var nd = SOAPClient._getElementsByTagName(loadXML(req.responseText), "sResult");

	this.busy.stop();
	if(nd.length == 0){
		var reqq = loadXML(req.responseText);
/*		if(req.responseXML.getElementsByTagName("faultcode").length > 0){
			if(async || callback)
				o = new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
			else
				throw new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
		}*/
		if(reqq.getElementsByTagName("faultcode").length > 0){
			if(async || callback)
				o = new Error(500, reqq.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
			else
				throw new Error(500, reqq.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
		}
	}
	else{
		o = SOAPClient._soapresult2object(nd[0], wsdl);
	}
	if(callback)
		callback(o, loadXML(req.responseText));
//		callback(o, req.responseXML);
	if(!async)
		return o;
}

SOAPClient._soapresult2object = function(node, wsdl){
	return SOAPClient._node2object(node, wsdl);
}
SOAPClient._node2object = function(node, wsdl){
	// null node
	if(node == null)
		return null;
	// text node
	if(node.nodeType == 3 || node.nodeType == 4)
		return SOAPClient._extractValue(node, wsdl);
	// leaf node
	if (node.childNodes.length == 1 && (node.childNodes[0].nodeType == 3 || node.childNodes[0].nodeType == 4))
		return SOAPClient._node2object(node.childNodes[0], wsdl);
	var isarray = SOAPClient._getTypeFromWsdl(node.nodeName, wsdl).toLowerCase().indexOf("arrayof") != -1;
	// object node
	if(!isarray)	{
		var obj = null;
		var sRet = "";
		if(node.hasChildNodes())
		obj = new Object();
		for(var i = 0; i < node.childNodes.length; i++)	{
			var p = SOAPClient._node2object(node.childNodes[i], wsdl);
			obj[node.childNodes[i].nodeName] = p;
			sRet += node.childNodes[i].nodeValue;
		}
//		return obj;
		return sRet;
	}
	// list node
	else	{
		// create node ref
		var l = new Array();
		for(var i = 0; i < node.childNodes.length; i++)
			l[l.length] = SOAPClient._node2object(node.childNodes[i], wsdl);
		return l;
	}
	return null;
}
SOAPClient._extractValue = function(node, wsdl){
	var value = node.nodeValue;
	switch(SOAPClient._getTypeFromWsdl(node.parentNode.nodeName, wsdl).toLowerCase()){
		default:
		case "s:string":
			return (value != null) ? value + "" : "";
		case "s:boolean":
			return value+"" == "true";
		case "s:int":
		case "s:long":
			return (value != null) ? parseInt(value + "", 10) : 0;
		case "s:double":
			return (value != null) ? parseFloat(value + "") : 0;
		case "s:datetime":
			if(value == null)
				return null;
			else	{
				value = value + "";
				value = value.substring(0, value.lastIndexOf("."));
				value = value.replace(/T/gi," ");
				value = value.replace(/-/gi,"/");
				var d = new Date();
				d.setTime(Date.parse(value));
				return d;
			}
	}
}

SOAPClient._getTypeFromWsdl = function(elementname, wsdl){
	var ell = wsdl.getElementsByTagName("s:element");    // IE
	if(ell.length == 0)
		ell = wsdl.getElementsByTagName("element");    // MOZ
	for(var i = 0; i < ell.length; i++){
		if(ell[i].attributes["name"] + "" == "undefined") {   // IE
			if(ell[i].attributes.getNamedItem("name") != null && ell[i].attributes.getNamedItem("name").nodeValue == elementname && ell[i].attributes.getNamedItem("type") != null)
				return ell[i].attributes.getNamedItem("type").nodeValue;
		}
		else { // MOZ
			if(ell[i].attributes["name"] != null && ell[i].attributes["name"].value == elementname && ell[i].attributes["type"] != null)
				return ell[i].attributes["type"].value;
		}
	}
	return "";
}

SOAPClient._getElementsByTagName = function(document, tagName){
	try{
		// trying to get node omitting any namespaces (latest versions of MSXML.XMLDocument)
		return document.selectNodes(".//*[local-name()=\""+ tagName +"\"]");
	}
	catch (ex) {}
	// old XML parser support
	return document.getElementsByTagName(tagName);
}

SOAPClient._getXmlHttp = function(){
	try{
		if(window.XMLHttpRequest){
			var req = new XMLHttpRequest();
			// some versions of Moz do not support the readyState property and the onreadystate event so we patch it!
			if(req.readyState == null)	{
				req.readyState = 1;
				req.addEventListener("load",
					function(){
						req.readyState = 4;
						if(typeof req.onreadystatechange == "function")
							req.onreadystatechange();
					},
					false);
			}
		return req;
		}
		if(window.ActiveXObject)
			return new ActiveXObject(SOAPClient._getXmlHttpProgID());
	}
	catch (ex) {}
	throw new Error("Your browser does not support XmlHttp objects");
}

SOAPClient._getXmlHttpProgID = function(){
	if(SOAPClient._getXmlHttpProgID.progid)
		return SOAPClient._getXmlHttpProgID.progid;
	var progids = ["Msxml2.XMLHTTP.5.0", "Msxml2.XMLHTTP.4.0", "MSXML2.XMLHTTP.3.0", "MSXML2.XMLHTTP", "Microsoft.XMLHTTP"];
	var o;
	for(var i = 0; i < progids.length; i++){
		try{
			o = new ActiveXObject(progids[i]);
			return SOAPClient._getXmlHttpProgID.progid = progids[i];
		}
		catch (ex) {};
	}
	throw new Error("Could not find an installed XML parser");
}




