﻿function PrototypeSerializeObject(tag) 
{
    var tagname = tag;
    if(this.hasOwnProperty('__XmlTagname') && this.__XmlTagname) 
    {
        tagname = this.__XmlTagname;
    }
    var xml = tagname ? '<' + tagname + '>' : '';
    
    for(var prop in this)
    {
        if(typeof(this[prop]) == 'function')
        {
            continue;
        }
        
        if(!this[prop]) 
        {
            //De tag is leeg
            continue;
        }
    
        if(typeof(this[prop].Serialize) == 'function') 
        {
            xml += this[prop].Serialize(prop);
            continue;
        } 
		else 
		{
			xml += "<" + prop + ">" + this[prop].toString().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</" + prop + ">";
		}
    }
    
    xml += tagname ? '</' + tagname + '>' : '';
    
    return xml;
}

function PrototypeSerializeArray(tag) 
{
    var tagname = tag;
    if(this.hasOwnProperty('__XmlTagname') && this.__XmlTagname) 
    {
        tagname = this.__XmlTagname;
    }

    var xml = '<' + tagname + '>';

    for(var i=0; i<this.length; i++) 
    {
        if(this.hasOwnProperty('__XmlItemTagname') && this.__XmlItemTagname)
        {
            xml += this[i].Serialize(this.__XmlItemTagname);
        }
        else if(this[i].__XmlTagname)
        {
            xml += this[i].Serialize(this[i].__XmlTagname);
        }
        else 
        {
            xml += this[i].Serialize('ArrayItem_' + i.toString());
        }
    }

    xml += '</' + tagname + '>';
    return xml;
}

function PrototypeSerializeString(tag) 
{
    //Wanneer een property met __ begint moet deze niet opgenomen worden
    if(tag.indexOf('__') > -1) 
    {
        return '';
    }
    
    var tagname = tag;
    if(this.hasOwnProperty('__XmlTagname') && this.__XmlTagname) 
    {
        tagname = this.__XmlTagname;
    }

    var xml = "<" + tagname + ">" + this.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</" + tagname + ">";
    
    return xml;
}


function PrototypeSerializeDate(tag) 
{
    //Wanneer een property met __ begint moet deze niet opgenomen worden
    if(tag.indexOf('__') > -1) 
    {
        return '';
    }
    
    var tagname = tag;
    if(this.hasOwnProperty('__XmlTagname') && this.__XmlTagname) 
    {
        tagname = this.__XmlTagname;
    }

    var xml = "<" + tagname + ">" + this.ToSoapDate() + "</" + tagname + ">";
    
    return xml;
}

function PrototypeSerializeBoolean(tag) 
{
    //Wanneer een property met __ begint moet deze niet opgenomen worden
    if(tag.indexOf('__') > -1) 
    {
        return '';
    }
    
    var tagname = tag;
    if(this.hasOwnProperty('__XmlTagname') && this.__XmlTagname) 
    {
        tagname = this.__XmlTagname;
    }

    var xml = "<" + tagname + ">" + this.toString() + "</" + tagname + ">";
    
    return xml;
}

function PrototypeSerializeNumber(tag) 
{
    //Wanneer een property met __ begint moet deze niet opgenomen worden
    if(tag.toString().indexOf('__') > -1) 
    {
        return '';
    }
    
    var tagname = tag;
    if(this.hasOwnProperty('__XmlTagname') && this.__XmlTagname) 
    {
        tagname = this.__XmlTagname;
    }

    var xml = "<" + tagname + ">" + this.toString() + "</" + tagname + ">";
    
    return xml;
}

function PrefixWithZero(datenumber)
{
    return (datenumber.toString().length == 1 ? '0'+datenumber.toString() : datenumber.toString() );
}

function ToSoapDate()
{
    return this.getFullYear() + '-' +
    PrefixWithZero(this.getMonth() + 1) + '-' +
    PrefixWithZero(this.getDate()) + 'T' +
    PrefixWithZero(this.getHours()) + ':' +
    PrefixWithZero(this.getMinutes()) + ':' +
    PrefixWithZero(this.getSeconds()) + '.' +
    this.getMilliseconds() + '+' + PrefixWithZero(-this.getTimezoneOffset()/60) + ':00';
}

function AttachSerializeMethod(o)
{
	var type = typeof(o);
	
	if(type == 'object')
	{
		if(o.constructor === Array) {
			type = 'array';
		}
		else if(o.constructor === Date) 
		{
			type = 'date';
		}
	}

	if(!o.__XmlTagname)
	{
		o.__XmlTagname = '';
	}
	
	var children = false;
	switch(type)
	{
		case 'number':
			o.Serialize = PrototypeSerializeNumber;
		    break;
		case 'string':
			o.Serialize = PrototypeSerializeString;
		    break;
		case 'boolean':
			o.Serialize = PrototypeSerializeBoolean;
		    break;
		case 'object':
			o.Serialize = PrototypeSerializeObject;
			children = true;
		    break;
		case 'array':
			o.Serialize = PrototypeSerializeArray;
			children = true;
		    break;
		case 'date':
			o.Serialize = PrototypeSerializeDate;
			o.ToSoapDate = ToSoapDate;
		    break;
	}
	
	if (children)
	{
        for(var p in o) 
        {
	        if(o[p] != null) 
	        {		
		        AttachSerializeMethod(o[p]);
	        }
        }
	}
}

/*****************************************************************************\

 Javascript "SOAP Client" library

 @version: 1.1 - 2005.11.11
 @author: Matteo Casati - http://www.guru4.net/
 @description: the SOAPClientParameters.toXML method has been updated to allow
               special characters ("<", ">" and "&"). Thanks to Linh.

 @version: 1.0 - 2005.09.08
 @author: Matteo Casati - http://www.guru4.net/
 @notes: first release.

\*****************************************************************************/

var siCounter=0;
function showStatusIndicator()
{
	siCounter++;
	if (siCounter>0) // eerste is begonnen, tonen die hap!
	{
		var st = document.getElementById("hsStatusIndicator");
		if (st) { st.style.display="block"; }
		if (document.body)
		{
			document.body.style.cursor="wait";
		}
	}
}
function hideStatusIndicator()
{
	siCounter--;
	if (siCounter==0) // laatste is klaar, nu echt weghalen!
	{
		var st = document.getElementById("hsStatusIndicator");
		if (st) { st.style.display="none"; }
		if (document.body)
		{
			document.body.style.cursor="";
		}
	}
}

function isSoapClientBusy()
{
    return (siCounter > 0);
}

function SOAPClientParameters()
{
	var _pl = new Object();
	this.add = function(name, value) { _pl[name] = value; }
	this.toXml = function()
	{
		var xml = "";

		AttachSerializeMethod(_pl);

		for(var p in _pl)
		{
		    //Mag geen method zijn
		    //Mag niet undefined zijn
		    //Mag niet starten met __ (Dan gaat het om een tagname)
		
			if (    typeof(_pl[p]) != "undefined" && 
			        typeof(_pl[p]) != "function" && 
			        p.indexOf('__') < 0)
		    {	
		        if(typeof( _pl[p] ) == "object")
		        {
		            xml += _pl[p].Serialize(p.toString());
		        }
		        else 
		        {
			        xml += "<" + p + ">" + _pl[p].toString().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;") + "</" + p + ">";
			    }
			}
		}
		return xml;	
	}
}

function SOAPClient() {}

SOAPClient.invoke = function(url, method, parameters, async, callback)
{
	if(async)
		SOAPClient._loadWsdl(url, method, parameters, async, callback);
	else
		return SOAPClient._loadWsdl(url, method, parameters, async, callback);
}

// private: wsdl cache
var SOAPClient_cacheWsdl = new Array();

// private: invoke async
SOAPClient._loadWsdl = function(url, method, parameters, async, callback)
{
	// load from cache?
	var wsdl = SOAPClient_cacheWsdl[url];
	if(wsdl + "" != "" && wsdl + "" != "undefined")
	{
		SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl);
		return;
	}
	// get wsdl
	var xmlHttp = SOAPClient._getXmlHttp();
	xmlHttp.open("GET", url + "?wsdl", async);
	if(async) 
	{
		xmlHttp.onreadystatechange = function() 
		{
			if(xmlHttp.readyState == 4)
				SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp);
		}
	}
	xmlHttp.send(null);

	if (!async)
		return SOAPClient._onLoadWsdl(url, method, parameters, async, callback, xmlHttp);
}
SOAPClient._onLoadWsdl = function(url, method, parameters, async, callback, req)
{
	var wsdl = new SOAPClient.WsdlCache(req.responseXML);
	SOAPClient_cacheWsdl[url] = wsdl;	// save a copy in cache
	return SOAPClient._sendSoapRequest(url, method, parameters, async, callback, wsdl);
}
SOAPClient._sendSoapRequest = function(url, method, parameters, async, callback, wsdl)
{
	// get namespace
	var ns = (wsdl.Wsdl.documentElement.attributes["targetNamespace"] + "" == "undefined") ? wsdl.Wsdl.documentElement.attributes.getNamedItem("targetNamespace").nodeValue : wsdl.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>" +
				"<" + method + " xmlns=\"" + ns + "\">" +
				parameters.toXml() +
				"</" + method + "></soap:Body></soap:Envelope>";
//alert(sr);
	// send request
	var xmlHttp = SOAPClient._getXmlHttp();
	xmlHttp.open("POST", url, async);
	var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + method;
	xmlHttp.setRequestHeader("SOAPAction", soapaction);
	xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
	if(async) 
	{
		xmlHttp.onreadystatechange = function() 
		{
			if(xmlHttp.readyState == 4)
				SOAPClient._onSendSoapRequest(method, async, callback, wsdl, xmlHttp);
		}
	}
	xmlHttp.send(sr);

	showStatusIndicator();
	
	if (!async)
		return SOAPClient._onSendSoapRequest(method, async, callback, wsdl, xmlHttp);
}
SOAPClient._onSendSoapRequest = function(method, async, callback, wsdl, req)
{
	var o = null;
	var nd = req.responseXML.getElementsByTagName(method + "Result");
	if(nd.length == 0)
	{
		hideStatusIndicator();
		
		if(req.responseXML.getElementsByTagName("faultcode").length > 0)
			throw new Error(500, req.responseXML.getElementsByTagName("faultstring")[0].childNodes[0].nodeValue);
	}
	else
		o = SOAPClient._soapresult2object(nd[0], wsdl);

	hideStatusIndicator();

	if(callback)
	{
	// alert('start callback');
		callback(o);
	// alert('end callback');
	}
	if(!async)
		return o;		
}

// private: utils

//Gets the typename minus tns:
SOAPClient._getTypeName = function(typeName)
{
    var idx = typeName.indexOf(":");
    if (idx != -1)
    {
        typeName = typeName.substr(idx + 1);
    }
    return typeName;
}

SOAPClient._soapresult2object = function(node, wsdl)
{
	return SOAPClient._node2object(node, wsdl);
}
SOAPClient._node2object = function(node, wsdl, parentName)
{
	// null node
	if(node == null)
		return null;
	// text node
	if(node.nodeType == 3 || node.nodeType == 4)
	{
		return SOAPClient._extractValue(node, wsdl, parentName);
	}
	
	// leaf node
	if (node.childNodes.length == 1 && (node.childNodes[0].nodeType == 3 || node.childNodes[0].nodeType == 4))
	{
		return SOAPClient._node2object(node.childNodes[0], wsdl, parentName);
	}
	var wsdlTypeOriginal = SOAPClient._getTypeFromWsdl(node.nodeName, wsdl);
	
	var wsdlType = wsdlTypeOriginal.toLowerCase();
	
	var isarray = wsdlType.indexOf("arrayof") != -1;
	// object node
	if(!isarray)
	{
		if (node.nodeType==1 && wsdlType == "s:string" && node.firstChild)
		{
			var s = "";
			for(var i = 0; i < node.childNodes.length; i++)
			{
				s += SOAPClient._extractValue(node.childNodes[i], wsdl);
			}
			return s;
		}

		var obj = null;
		var typeName = "";
		if(node.hasChildNodes())
		{
			obj = new Object();
			typeName = wsdlType;
			
			typeName = this._getTypeName(typeName);
			
			/*
            var idx = typeName.indexOf(":");
            if (idx != -1)
            {
                typeName = typeName.substr(idx + 1);
            }
            
            if (typeName.indexOf("tns:") == 0)
            {
                typeName = typeName.substr(4);
            }
            */
		}

		for(var i = 0; i < node.childNodes.length; i++)
		{
			var p = SOAPClient._node2object(node.childNodes[i], wsdl, typeName);
			obj[node.childNodes[i].nodeName] = p;
		}
		return obj;
	}
	// list node
	else
	{
		// create node ref
		var l = new Array();
		
		
		//Wanneer je hier komt begint het type met arrayof
		//De xmlitemtagname wordt gehaald uit het wsdltype vanaf het 7e karakter: ArrayOfNameValueClass ,na arrayof
		l.__XmlItemTagname = this._getTypeName(wsdlTypeOriginal).substring(7);

		
		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, parentName)
{
	var value = node.nodeValue;

	var type = "";
	
	if (!type)
	{
		type = SOAPClient._getTypeFromWsdl(node.parentNode.nodeName, wsdl, parentName)
	}
	
	switch(type.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)
			{
				return null;
			}
			else
			{
				value = value + "";
				var idx = value.lastIndexOf(".");
				if (idx >= 0)
				{
					value = value.substring(0, idx);
				}
				value = value.replace(/T/gi," ");
				value = value.replace(/-/gi,"/");
				var d = new Date();
				d.setTime(Date.parse(value));										
				return d;				
			}
	}
}

SOAPClient._checkWithParent = function(elem, parentName)
{
	if (!parentName)
	{
		return true;
	}
	
	var attrib, typeAttrib;
	
	elem = elem.parentNode;
	while(elem && elem.attributes)
	{
		attrib = elem.attributes["name"];
		if(attrib + "" == "undefined")	// IE
		{
			attrib = elem.attributes.getNamedItem("name");
			if(attrib && attrib.nodeValue.toLowerCase() == parentName) 
			{
				return true;
			}
		}	
		else // MOZ
		{
			if(attrib && attrib.value.toLowerCase() == parentName)
			{
				return true;
			}
		}

		elem = elem.parentNode;
	}
	
	return false;
};

SOAPClient._getTypeFromWsdl = function(elementname, wsdl, parentName)
{
	// check cache first...
	var cacheName = "";
	if (parentName) 
	{
		cacheName = parentName + ".";
	}
	cacheName += elementname;
	var type = wsdl.ElementCache[cacheName];
	if (type) return type;
	
	var ell = wsdl.Wsdl.getElementsByTagName("s:element");	// IE
	if(ell.length == 0)
		ell = wsdl.Wsdl.getElementsByTagName("element");	// MOZ
		
	var attrib, typeAttrib, elem, anyType = "";
	for(var i = ell.length-1; i >=0; i--)
	{
		attrib = (elem = ell[i]).attributes["name"];
		if(attrib + "" == "undefined")	// IE
		{
			attrib = elem.attributes.getNamedItem("name");
			if(attrib && attrib.nodeValue == elementname && (typeAttrib = elem.attributes.getNamedItem("type")) != null) 
			{			
			    if (SOAPClient._checkWithParent(elem, parentName))
			    {
				    type = typeAttrib.nodeValue;
				    break;
				}

				if (!anyType)
				{
				    anyType = typeAttrib.nodeValue;
				}
			}
		}	
		else // MOZ
		{
			if(attrib && attrib.value == elementname && (typeAttrib = elem.attributes["type"]) != null)
			{
			    if (SOAPClient._checkWithParent(elem, parentName))
			    {
				    type = typeAttrib.value;
				    break;
				}
				
				if (!anyType)
				{
				    anyType = typeAttrib.value;
				}
			}
		}
	}
	
	if (!type)
	{
	    type = anyType;
	}
	
	if (type)
	{
		wsdl.ElementCache[cacheName] = type;
		return type;
	}
	
	return "";
}
// private: xmlhttp factory
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.onerror = window.onerror; // link errorhandling
                req.addEventListener("load",
									function()
									{
									    req.readyState = 4;
									    if (typeof req.onreadystatechange == "function")
									        req.onreadystatechange();
									},
									false);
            }
            return req;
        }
        if (window.ActiveXObject)
            return new ActiveXObject(SOAPClient._getXmlHttpPrefix() + ".XmlHttp");
    }
    catch (ex) { }
    throw new Error("Your browser does not support XmlHttp objects");
}
SOAPClient._getXmlHttpPrefix = function()
{
	if(SOAPClient._getXmlHttpPrefix.prefix)
		return SOAPClient._getXmlHttpPrefix.prefix;
	var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
	var o;
	for(var i = 0; i < prefixes.length; i++)
	{
		try
		{
			o = new ActiveXObject(prefixes[i] + ".XmlHttp");
			return SOAPClient._getXmlHttpPrefix.prefix = prefixes[i];
		}
		catch (ex) {};
	}
	throw new Error("Could not find an installed XML parser");
}

SOAPClient.WsdlCache = function(wsdl)
{
	this.Wsdl = wsdl;
	this.ElementCache = new Object();
};