/**
* Classes included in this file:
*     Ajax
*     SoapParameters
* Files required by this file:
*     None
**/
Object.Serialize = function(p_object)
{
	var v_xml = '';
	switch(typeof(p_object))
	{
		case 'function': break;
		case 'string': v_xml += p_object.toString().replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); break;
		case 'number': v_xml += p_object.toString(); break;
		case 'boolean': v_xml += p_object.toString(); break;
		case 'object':
			if(typeof(p_object.Serialize) == 'function') { v_xml += p_object.Serialize(); }
			else if(p_object.constructor.toString().indexOf('function Date()') > -1)
			{
				var v_year = p_object.getFullYear().toString();
				var v_month = (p_object.getMonth() + 1).toString(); v_month = (v_month.length == 1) ? '0' + v_month : v_month;
				var v_date = p_object.getDate().toString(); v_date = (v_date.length == 1) ? '0' + v_date : v_date;
				var v_hours = p_object.getHours().toString(); v_hours = (v_hours.length == 1) ? '0' + v_hours : v_hours;
				var v_minutes = p_object.getMinutes().toString(); v_minutes = (v_minutes.length == 1) ? '0' + v_minutes : v_minutes;
				var v_seconds = p_object.getSeconds().toString(); v_seconds = (v_seconds.length == 1) ? '0' + v_seconds : v_seconds;
				var v_milliseconds = p_object.getMilliseconds().toString();
				var v_tzminutes = Math.abs(p_object.getTimezoneOffset());
				var v_tzhours = 0;
				while(v_tzminutes >= 60) { v_tzhours++; v_tzminutes -= 60; }
				v_tzminutes = v_tzminutes.toString(); (v_tzminutes.length == 1) ? '0' + v_tzminutes : v_tzminutes;
				v_tzhours = v_tzhours.toString(); (v_tzhours.length == 1) ? '0' + v_tzhours : v_tzhours;
				var v_timezone = ((p_object.getTimezoneOffset() < 0) ? '+' : '-') + v_tzhours + ':' + v_tzminutes;
				v_xml += v_year + '-' + v_month + '-' + v_date + 'T' + v_hours + ':' + v_minutes + ':' + v_seconds + '.' + v_milliseconds + v_timezone;
			}
			else if(p_object.constructor.toString().indexOf('function Array()') > -1)
			{
				for(var v_index in p_object)
				{
					if(!isNaN(v_index)) // linear array
					{
						(/function\s+(\w*)\s*\(/ig).exec(p_object[v_index].constructor.toString());
						var v_type = RegExp.$1;
						switch(v_type)
						{
							case '': v_type = typeof(p_object[v_index]); break;
							case 'String': v_type = 'string'; break;
							case 'Number': v_type = 'int'; break;
							case 'Boolean': v_type = 'bool'; break;
							case 'Date': v_type = 'DateTime'; break;
						}
						v_xml += '<' + v_type + '>' + Object.Serialize(p_object[v_index]) + '<\/' + v_type + '>';
					}
					else { v_xml += '<' + v_index + '>' + Object.Serializet(p_object[v_index]) + '<\/' + v_index + '>'; } // associative array
				}
			}
			else { for(var v_name in p_object) { v_xml += '<' + v_name + '>' + Object.Serialize(p_object[v_name]) + '<\/' + v_name + '>'; } }
			break;
		default: break;
	}
	return v_xml;
}
Object.Deserialize = function(p_xmlNode, p_type)
{
	if(p_xmlNode == null) { return null; }
	var v_type_defined = p_type != undefined && p_type != null;
	if(p_xmlNode.nodeType == 3 || p_xmlNode.nodeType == 4)
	{
		var v_value = p_xmlNode.nodeValue;
		if(v_type_defined)
		{
			switch(p_type.toLowerCase())
			{
				default:
				case 'string': return v_value != null ? String(v_value) + '' : '';
				case 'boolean': return v_value == 'true';
				case 'short':
				case 'int':
				case 'long': return (v_value != null) ? parseInt(v_value, 10) : 0;
				case 'float':
				case 'double': return (v_value != null) ? parseFloat(v_value) : 0;
				case 'datetime':
					if(v_value == null || v_value.length <= 0) { return null; }
					else
					{
						v_value = v_value.substring(0, (v_value.lastIndexOf('.') == -1 ? v_value.length : v_value.lastIndexOf('.')));
						v_value = v_value.replace(/T/gi, ' ');
						v_value = v_value.replace(/-/gi, '/');
						return new Date(Date.parse(value));
					}
			}
		}
		return v_value != null ? String(v_value) + '' : '';
	}
	if(p_xmlNode.childNodes.length == 1 && (p_xmlNode.childNodes[0].nodeType == 3 || p_xmlNode.childNodes[0].nodeType == 4)) { return Object.Deserialize(p_xmlNode.childNodes[0], p_type); }
	var v_is_array = false;//!v_type_defined ? false : p_type.toLowerCase().indexOf('arrayof') != -1;
	var v_obj = v_is_array ? new Array() : (p_xmlNode.hasChildNodes() ? new Object() : null);
	for(var i = 0; i < p_xmlNode.childNodes.length; i++)
	{
		var v_node = p_xmlNode.childNodes[i];
		var v_type = v_type_defined ? p_type[v_node.nodeName] : null;
		v_obj[v_is_array ? i : v_node.nodeName] = Object.Deserialize(v_node, v_type);
	}
	return v_obj;
}
/*******************************************************************************/
function SoapParameters() { return; }
SoapParameters.prototype.GetType = function() { return 'SoapParameters'; }
SoapParameters.prototype.GetHashCode = function() { return this.ToString(); }
SoapParameters.prototype.ToString = function()
{
	v_string = '[Object: SoapParameters] { ';
	for(var v_name in this) { if(typeof(this[v_name]) != 'function' && this[v_name] != undefined) { v_string += v_name + ' : ' + this[v_name].toString() + ', '; } }
	return v_string.substr(0, v_string.length - 2) + ' }';
}
SoapParameters.prototype.toString = function() { return this.ToString(); }
SoapParameters.prototype.ToXml = function() { return Object.Serialize(this); }
SoapParameters.prototype.Add = function(p_name, p_value) { this[p_name] = p_value; return this; }
SoapParameters.prototype.Remove = function(p_name) { this[p_name] = undefined; return this; }
SoapParameters.Create = function(p_paramObject)
{
	var v_sp = new SoapParameters();
	for(var v_name in p_paramObject) { if(typeof(p_paramObject[v_name]) != 'function') { v_sp.Add(v_name, p_paramObject[v_name]); } }
	return v_sp;
}
/*******************************************************************************/
function Ajax(p_mimeType)
{
	// This is the MIME type that the XML HTTP object will use when performing the requests. Defaults to 'text/xml'.
	this.MimeType = p_mimeType ? p_mimeType : 'text/xml';
	this.Async = true;
	return;
}
Ajax.prototype.GetType = function() { return 'Ajax'; }
Ajax.prototype.GetHashCode = function() { return 'Ajax'; }
Ajax.prototype.ToString = function() { return '[Object: Ajax]'; }
Ajax.prototype.toString = function() { return this.ToString(); }
Ajax.prototype.Execute = function(p_url, p_params, p_callback, p_useGetMethod, p_identifier)
{
	var v_xmlhttp = new Ajax.XmlHttpWrapper(this.MimeType, this.Async, String(p_url), p_identifier);

	if(this.Async) { v_xmlhttp.XmlHttp.onreadystatechange = function() { if(v_xmlhttp.XmlHttp.readyState == 4) { __StateChangedCallback(); } return; } }
	v_xmlhttp.Send(String(p_params), p_useGetMethod);
	if(!this.Async) { return __StateChangedCallback(); }

	function __StateChangedCallback()
	{
		var v_status = 0;
		var v_response = '';
		try
		{
			v_status = v_xmlhttp.XmlHttp.status;
			v_response = v_xmlhttp.XmlHttp.responseText;
		}
		catch(e)
		{
			v_status = 500;
			v_response = e.toString();
		}
		if(!v_xmlhttp.Async)
		{
			if(v_status != 200) { throw new Error(v_status, v_response); }
			return v_response;
		}
		else if(typeof(p_callback) == 'function') { p_callback(v_status == 200, v_response, v_status, v_xmlhttp.Id); }
		return;
	}
	return;
}
Ajax.prototype.SubmitForm = function(p_formObject, p_url, p_callback, p_useGetMethod, p_identifier)
{
	this.Execute(p_url, Ajax.ParseFormValues(p_formObject), p_callback, p_useGetMethod, p_identifier);
	return;
}
Ajax.prototype.ExecuteSoapMethod = function(p_url, p_method, p_params, p_callback, p_identifier)
{
	var v_wdsl = Ajax.LoadWsdl(p_url);
	var v_name_space = (v_wdsl.documentElement.attributes['targetNamespace'] == undefined) ? v_wdsl.documentElement.attributes.getNamedItem('targetNamespace').nodeValue : v_wdsl.documentElement.attributes['targetNamespace'].value;
	var v_soap_xml = '<?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>'
		+ '<' + p_method + ' xmlns="' + v_name_space + '">'
		+ p_params.ToXml()
		+ '<\/' + p_method + '><\/soap:Body><\/soap:Envelope>';

	var v_xmlhttp = new Ajax.XmlHttpWrapper('text/xml', String(p_url), this.Async, p_identifier);
	if(this.Async) { v_xmlhttp.XmlHttp.onreadystatechange = function() { if(v_xmlhttp.XmlHttp.readyState == 4) { __StateChangedCallback(); } return; } }
	var v_soap_action = ((v_name_space.lastIndexOf('/') != v_name_space.length - 1) ? v_name_space + '/' : v_name_space) + p_method;
	v_xmlhttp.XmlHttp.open('POST', v_xmlhttp.Url, this.Async);
	v_xmlhttp.XmlHttp.setRequestHeader('SOAPAction', v_soap_action);
	v_xmlhttp.XmlHttp.setRequestHeader('Content-Type', 'text/xml; charset=utf-8');
	v_xmlhttp.XmlHttp.send(v_soap_xml);
	if(!this.Async) { return __StateChangedCallback(); }

	function __StateChangedCallback()
	{
		var v_status = 0;
		var v_response = null;
		try { v_status = v_xmlhttp.XmlHttp.status; }
		catch(e)
		{
			v_status = 500;
			v_response = e.toString();
			if(!v_xmlhttp.Async) { throw new Error(v_status, v_response); }
		}

		if(v_status == 200)
		{
			var v_nodes = null;
			try { v_nodes = v_xmlhttp.XmlHttp.responseXML.selectNodes(".//*[local-name()=\""+ p_method +"Result\"]"); }
			catch(e) { v_nodes = v_xmlhttp.XmlHttp.responseXML.getElementsByTagName(p_method + 'Result'); }
			if(v_nodes == null || v_nodes.length == 0)
			{
				if(v_xmlhttp.XmlHttp.responseXML.getElementsByTagName('faultcode').length > 0)
				{
					v_response = v_xmlhttp.XmlHttp.responseXML.getElementsByTagName('faultstring')[0].childNodes[0].nodeValue;
					if(!v_xmlhttp.Async) { throw new Error(v_status, v_response); }
				}
				else
				{
					v_status = 500;
					v_response = 'An error occured when retriving the webservice results set.';
					if(!v_xmlhttp.Async) { throw new Error(v_status, v_response); }
				}
			}
			else { v_response = Object.Deserialize(v_nodes[0], Ajax._GetReturnTypeArrayFromWsdl(p_method, v_wdsl)); }
		}
		
		if(!v_xmlhttp.Async) { return v_response; }
		else if(typeof(p_callback) == 'function') { p_callback(v_status == 200, v_response, v_status, v_xmlhttp.Id); }
		return;
	}
	return;
}

// Global static methods/members.

Ajax.XmlHttpWrapper = function(p_mimeType, p_async, p_url, p_id)
{
	this.Id = p_id;
	this.Async = p_async;
	this.Url = p_url;
	this.XmlHttp = Ajax.GetXmlHttpObject(p_mimeType);
	return;
}
Ajax.XmlHttpWrapper.prototype.GetType = function() { return 'Ajax.XmlHttpWrapper'; }
Ajax.XmlHttpWrapper.prototype.GetHashCode = function() { return this.Id + this.Url; }
Ajax.XmlHttpWrapper.prototype.toString = function() { return this.ToString(); }
Ajax.XmlHttpWrapper.prototype.ToString = function() { return this.Id; }
Ajax.XmlHttpWrapper.prototype.Send = function(p_params, p_useGetMethod)
{
	var v_method = p_useGetMethod ? 'GET' : 'POST';
	if(v_method == 'POST')
	{
		this.XmlHttp.open(v_method, this.Url, this.Async);
		this.XmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
		this.XmlHttp.setRequestHeader('Content-length', p_params.length);
		this.XmlHttp.setRequestHeader('Connection', 'close');
		this.XmlHttp.send(p_params);
	}
	else
	{
		var v_url_string = this.Url;
		if(p_params != null && p_params.length > 0) { v_url_string += '?' + p_params; }
		this.XmlHttp.open(v_method, v_url_string, this.Async);
		this.XmlHttp.send('');
	}
	return;
}

Ajax._IEProgId = '';
Ajax.GetXmlHttpObject = function(p_mimeType)
{
	if(window.ActiveXObject)
	{
		if(Ajax._IEProgId != '') { return new ActiveXObject(Ajax._IEProgId); }
		var v_ieprogids = ['Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
		for(var i = 0; i < v_ieprogids.length; i++)
		{
			try
			{
				var v_xmlhttp = new ActiveXObject(v_ieprogids[i]);
				Ajax._IEProgId = v_ieprogids[i];
				return v_xmlhttp;
			}
			catch(e) {  }
		}
	}
	else if(window.XMLHttpRequest)
	{
		var v_xmlhttp = new XMLHttpRequest()
		if(typeof(p_mimeType) == 'string' && p_mimeType.length > 0 && v_xmlhttp.overrideMimeType) { v_xmlhttp.overrideMimeType(p_mimeType); }
		// Some versions of Mozilla do not support the readyState property and the onreadystate event so we patch it!
		if(v_xmlhttp.readyState == null) 
		{
			v_xmlhttp.readyState = 1;
			v_xmlhttp.addEventListener("load", function() { v_xmlhttp.readyState = 4; if(typeof(v_xmlhttp.onreadystatechange) == "function") { v_xmlhttp.onreadystatechange(); } return; }, false);
		}
		return v_xmlhttp;
	}
	alert('Your browser does not fully support the technology used on this page. Some features may not work the way they were intended to.');
	return null;
}

// Normal AJAX execution static methods/members.

Ajax.ParseFormValues = function(p_htmlElement)
{
	var v_params = '';
	for(var i = 0; i < p_htmlElement.childNodes.length; i++)
	{
		var v_element = p_htmlElement.childNodes[i];
		if(v_element.tagName == 'INPUT')
		{
			if(v_element.type == 'text' || v_element.type == 'hidden' || v_element.type == 'password') { v_params += escape(v_element.name) + '=' + escape(v_element.value) + '&'; }
			else if(v_element.type == 'checkbox') { v_params += escape(v_element.name) + '=' + (v_element.checked ? escape(v_element.value) : '') + '&'; }
			else if(v_element.type == 'radio') { if(v_element.checked) { v_params += escape(v_element.name) + '=' + escape(v_element.value) + '&'; } }
		}
		else if(v_element.tagName == 'SELECT')
		{
			if(v_element.multiple)
            {
                for(var j = 0; j < v_element.options.length; j++)
                {
                    if(v_element.options[j].selected) { v_params += escape(v_element.name) + '=' + escape(v_element.options[j].value) + '&'; }
                }
            }
            else if(v_element.selectedIndex > -1) { v_params += escape(v_element.name) + '=' + escape(v_element.options[v_element.selectedIndex].value) + '&'; }
		}
		else if(v_element.tagName == 'TEXTAREA') { v_params += escape(v_element.name) + '=' + escape(v_element.value) + '&'; }
		else { v_params += Ajax.ParseFormValues(v_element); }
	}
	return v_params;
}

// SOAP static methods/members

Ajax._SoapWdslCache = new Object();
Ajax._SoapMethodTypesCache = new Object();
Ajax.IENSCustom = '';
Ajax.IENSCommon = 'xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:s="http://www.w3.org/2001/XMLSchema"';
Ajax.IENSSoap = 'xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"';
Ajax.IEUseNSCommon = false;
Ajax.IEUseNSSoap = false;
Ajax.LoadWsdl = function(p_url)
{
	var v_wsdl = Ajax._SoapWdslCache[p_url];
	if(v_wsdl != undefined) { return v_wsdl; }
	var v_xmlhttp = Ajax.GetXmlHttpObject('text/xml');
	Ajax._SendHtmlHttpRequest(v_xmlhttp, p_url, 'wsdl', true, false);
	var v_status = 0;
	var v_status_text = '';
	try
	{
		v_status = v_xmlhttp.status;
		v_status_text = v_xmlhttp.statusText;
	}
	catch(e)
	{
		v_status = 500;
		v_status_text = e.toString();
	}
	if(v_status != 200) { throw new Error(v_status, v_status_text); }
	v_wsdl = Ajax._SoapWdslCache[p_url] = v_xmlhttp.responseXML;
	return v_wsdl;
}

Ajax._GetReturnTypeArrayFromWsdl = function(p_method, p_wsdl)
{
	if(Ajax._SoapMethodTypesCache[p_method] != undefined) { return Ajax._SoapMethodTypesCache[p_method]; }
	var v_temp = Ajax.IEUseNSCommon
	var v_temp2 = Ajax.IEUseNSSoap;
	Ajax.IEUseNSCommon = true;
	Ajax.IEUseNSSoap = true;
	var v_node = Ajax._XpathSelectSingleNode(p_wsdl, '/wsdl:definitions/wsdl:types/s:schema/s:element[@name="' + p_method + 'Response"]/s:complexType/s:sequence/s:element[@name="' + p_method + 'Result"]');
	Ajax._GetReturnType(p_wsdl, Ajax._GetXmlElementAttributeValue(v_node, 'type'), Ajax._SoapMethodTypesCache[p_method]);
	Ajax.IEUseNSCommon = v_temp;
	Ajax.IEUseNSSoap = v_temp2;
	return Ajax._SoapMethodTypesCache[p_method];
}
Ajax._XpathSelectSingleNode = function(p_doc, p_xpath)
{
	try // IE
	{
		p_doc.setProperty('SelectionNamespaces', (Ajax.IEUseNSCommon ? Ajax.IENSCommon + ' ' : '') + (Ajax.IEUseNSSoap ? Ajax.IENSSoap + ' ' : '') + Ajax.IENSCustom);
		return p_doc.selectSingleNode(p_xpath);
	}
	catch(e) // Mozilla
	{
		var v_ns_resolver = p_doc.createNSResolver(p_doc.ownerDocument == null ? p_doc.documentElement : p_doc.ownerDocument.documentElement);
		var v_response_node = p_doc.evaluate(p_xpath, p_doc, v_ns_resolver, 9, null);
		return v_response_node.singleNodeValue;
	}
}
Ajax._GetXmlElementAttributeValue = function(p_element, p_attributeName)
{
	if(p_element != null && p_element.nodeType == 1)
	{
		if(p_element.attributes[p_attributeName] != undefined) { return p_element.attributes[p_attributeName] == null ? '' : p_element.attributes[p_attributeName].value; } // Mozilla based browsers.
		else if(p_element.attributes.getNamedItem(p_attributeName) != undefined) { return p_element.attributes.getNamedItem(p_attributeName) == null ? '' : p_element.attributes.getNamedItem(p_attributeName).nodeValue; } // IE
	}
	return '';
}
Ajax._GetReturnType = function(p_wsdl, p_type, p_array)
{
	switch(p_type)
	{
		case 's:string': p_array = 'string'; break;
		case 's:bool': p_array = 'bool'; break;
		case 's:short': p_array = 'short'; break;
		case 's:int': p_array = 'int'; break;
		case 's:long': p_array = 'long'; break;
		case 's:double': p_array = 'double'; break;
		case 's:float': p_array = 'float'; break;
		case 's:datetime': p_array = 'datetime'; break;
		default:
		{
			p_array = new Object();
			if(p_type.indexOf(':') != -1) { p_type = p_type.substr(p_type.indexOf(':') + 1, p_type.length); }
			var v_ct_node = Ajax._XpathSelectSingleNode(p_wsdl, '/wsdl:definitions/wsdl:types/s:schema/s:complexType[@name="' + p_type + '"]/s:sequence');
			for(var i = 0; i < v_ct_node.childNodes.length; i++)
			{
				if(v_ct_node.childNodes[i].nodeName == 's:element')
				{
					var v_ct_type = Ajax._GetXmlElementAttributeValue(v_ct_node.childNodes[i], 'type');
					var v_ct_name = Ajax._GetXmlElementAttributeValue(v_ct_node.childNodes[i], 'name');
					Ajax._GetReturnType(p_wsdl, v_ct_type, p_array[v_ct_name]);
				}
			}
		}
	}
	return;
}