// ASPNexusAjax
function ASPNexusAjax(page, errorHandler) {
	var me = this;
	var m_XMLHTTP = null
	var m_XmlRequest
	var m_XmlResponse
	var m_page = page
	var m_HandlerError = errorHandler
	var m_HandlerFinalize;
	var m_HandlerInitialize;
	var m_HandlerIntermediate;
	var m_appRoot = getRootPath()
	
	this.call = function (method, finalize, initialize, intermediate) {
		var isAsynch = true;
		m_HandlerFinalize = finalize;
		m_HandlerInitialize = initialize;
		m_HandlerIntermediate = intermediate;
		if (m_HandlerFinalize==null && method!='cancel') {
			isAsynch=false
		} else {
			if (m_HandlerInitialize!=null) {m_HandlerInitialize()}
		}
		
		xmlHttpInit()
		if (m_XMLHTTP!=null) {
			if (m_XmlRequest==null) {requestInit()}
			responseInit()
			if (isAsynch) {
				m_XMLHTTP.onreadystatechange = asynchHandler
			}
			m_XMLHTTP.open("POST", m_page+"?method=" + method, isAsynch);
			m_XMLHTTP.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
			m_XMLHTTP.send("RequestData="+m_XmlRequest.xml)
			if (isAsynch==false) {
				if (m_XMLHTTP.readyState == 4) {
					if (m_XMLHTTP.status == 200) {
						asynchHandler()
					} else {
						alert("status="+m_XMLHTTP.status+" :"+m_XMLHTTP.statusText)
					}
				} else {
					alert("m_XMLHTTP.readyState != 4, ="+m_XMLHTTP.readyState)
				}
				m_XMLHTTP = null
			}
			requestInit();
		} else {
			alert('Could not create XMLHTTP object!')
		}
	}
	this.cancel = function (){
		me.call('cancel', null, null, null)
	}
	this.addParam = function (name, value){
		switch (typeof(value)){
		case "string":
			addParameter(name, value, "string")
			break;
		case "number":
			addParameter(name, value.toString(), "number")
			break;
		case "boolean":
			addParameter(name, value.toString(), "boolean")
			break;
		case "object":
			if (value instanceof Date){
				addParameter(name, value.valueOf().toString(), "date")						
			} else if (value instanceof Array){
				addParameter(name, value.join("_:_"), "array")
			} else {
				try{
					var strXml = value.xml
					addParameter(name, strXml, "xml")
				} catch (e0){}
			}
			break;
		default:
			alert(typeof(value))
			break;
		}
	}
	this.getResult = function (name){
		if (m_XmlResponse!=null) {
			var res = m_XmlResponse.selectSingleNode("/Response/Result[@name='"+name+"']")
			if (res!=null) {
				var strResult = fromSafeString(res.text)
				switch (res.attributes.getNamedItem("type").value) {
				case "string":
					return strResult
					break;
				case "number":
					return new Number(strResult)
					break;
				case "boolean":
					if(strResult == 'false')
					    return false
					else
					    return true
					break;
				case "date":
					return new Date(new Number(strResult))
					break;
				case "xml":
					var xmlDoc = getXmlDocumentObject();
					xmlDoc.loadXML(strResult)
					return xmlDoc
					break;
				case "array":
					var arr = strResult.split("_:_");
					return arr
					break;
				}
			} else {
				return null
			}
		} else {
			alert("Response is null")
			return null
		}
	}
	this.resultType = function (name){
		if (m_XmlResponse!=null) {
			var res = m_XmlResponse.selectSingleNode("/Response/Result[@name='"+name+"']")
			if (res!=null) {
				return res.attributes.getNamedItem("type").value
			}
		}
	}
	this.sendFormVar = function (name){
		if (document.forms.item(0).all.namedItem(name) != null) {
			if (m_XmlRequest==null) {requestInit()}
			var elemFormVar = m_XmlRequest.createElement("Var")
			elemFormVar.setAttribute("name",name)
			var itemVal = document.forms.item(0).all.namedItem(name).value
			if (itemVal != null) {
				elemFormVar.setAttribute("value", toSafeString(String(itemVal)))
			} else {
				elemFormVar.setAttribute("value", "")
			}
			m_XmlRequest.selectSingleNode("/Request/FormVars").appendChild(elemFormVar)
		}
	}
	this.sendAllFormVars = function (){
		if (m_XmlRequest==null) {requestInit()}
		var formVars = m_XmlRequest.selectSingleNode("/Request/FormVars")
		var coll = document.forms.item(0).all
		for (var i=0; i<coll.length; i++) {
			if (coll.item(i).value!=null && coll.item(i).name!=null && coll.item(i).name!="" && coll.item(i).style.display!="none" && coll.item(i).name.substr(0,2)!="__") {
				var elemVar = m_XmlRequest.createElement("Var")
				elemVar.setAttribute("name", coll.item(i).name)
				if (coll.item(i).value!=null) {
					elemVar.setAttribute("value", toSafeString(String(coll.item(i).value)))
				} else {
					elemVar.setAttribute("value", "")
				}
				formVars.appendChild(elemVar)
			}
		}
	}
	this.error = function (){
		if (m_XmlResponse!=null) {
			var err = m_XmlResponse.selectSingleNode("/Response/Error")
			if (err!=null) {
				return err.text
			} else {
				return ""
			}
		} else {
			return null
		}
	}
	
	function xmlHttpInit(){
		try {
			m_XMLHTTP = new ActiveXObject("Msxml2.XMLHTTP.4.0");
		} catch(e0) {
			try {
				m_XMLHTTP = new ActiveXObject("Msxml2.XMLHTTP.3.0");
			} catch(e1) {
				try {
					m_XMLHTTP = new ActiveXObject("Msxml2.XMLHTTP");
				} catch(e2) {
					try {
						m_XMLHTTP = new ActiveXObject("Microsoft.XMLHTTP");
					} catch(e3) {
						try {
							m_XMLHTTP = new XMLHttpRequest();
						} catch(e4) {
							m_XMLHTTP = null;
						}
					}
				}
			}
		}
	}
	
	function requestInit(){
		m_XmlRequest = getXmlDocumentObject();
		m_XmlRequest.loadXML("<?xml version='1.0' encoding='utf-8' ?><Request><FormVars></FormVars></Request>")
	}
	
	function responseInit(){
		m_XmlResponse = getXmlDocumentObject();
		m_XmlResponse.loadXML("<?xml version='1.0' encoding='utf-8' ?><Response></Response>")
	}
	
	function asynchHandler(){
		if (m_XMLHTTP.readyState == 4) {
			var rt = m_XMLHTTP.responseText
			if (rt.substr(0,6)=="<html>") {
				var intStart = rt.indexOf("<title>")+7
				var intEnd = rt.indexOf("</title>", intStart)
				var strError = rt.substr(intStart, intEnd-intStart)
				intStart = rt.indexOf("Description:")+12
				intStart = rt.indexOf("</b>", intStart)+4
				intEnd = rt.indexOf("<br><br>", intStart)
				strError += "\n" + rt.substr(intStart, intEnd-intStart)
				intStart = rt.indexOf("Error Message:")+14
				intStart = rt.indexOf("</b>", intStart)+4
				intEnd = rt.indexOf("<br><br>", intStart)
				strError +="\nError: " + rt.substr(intStart, intEnd-intStart)
				intStart = rt.indexOf("<code><pre>")+11
				intEnd = rt.indexOf("</pre></code>", intStart)
				strError += rt.substr(intStart, intEnd-intStart)
				intStart = rt.indexOf("Source File:")+12
				intStart = rt.indexOf("</b>", intStart)+4
				intEnd = rt.indexOf("&nbsp;&nbsp;", intStart)
				strError +="\n\nFile: " + rt.substr(intStart, intEnd-intStart)
				intStart = rt.indexOf("</b>", intEnd)+4
				intEnd = rt.indexOf("<br><br>", intStart)
				strError +="\nLine: " + rt.substr(intStart, intEnd-intStart)
				var re = new RegExp("&quot;","g")
				strError = strError.replace(re,'"')
				re = new RegExp("&lt;","g")
				strError = strError.replace(re,'<')
				re = new RegExp("&gt;","g")
				strError = strError.replace(re,'>')
				re = new RegExp("<font color=red>","g")
				strError = strError.replace(re,'*** ')
				re = new RegExp("</font>","g")
				strError = strError.replace(re,'')
				alert(strError)
			} else {
				m_XmlResponse = getXmlDocumentObject();
				m_XmlResponse.loadXML(rt)
				if (m_XmlResponse.xml!=""){
					var m_ReturnState = m_XmlResponse.selectSingleNode("/Response").attributes.getNamedItem("state").value
					if (m_ReturnState=="intermediate") {
						if (m_HandlerIntermediate!=null) {
							m_HandlerIntermediate();
						}
					} else if (m_ReturnState=="finalize") {
						m_XMLHTTP = null
						if (m_HandlerFinalize!=null) {
							m_HandlerFinalize();
						}
					} else if (m_ReturnState=="error") {
						m_XMLHTTP = null
						if (me.error()=="logout") {
							window.location.replace(m_appRoot+"logout.aspx");
						} else {
							if (m_HandlerError!=null) {
								m_HandlerError();
							} else {
								alert("Error: " + me.error());
							}
						}
					} else if (m_ReturnState=="cancel") {
						m_XMLHTTP = null
						window.location.replace(m_appRoot+"action_generic.aspx?ajax=1");				
					}
				} else {
					alert("Problem with response: \n\n"+rt)
				}
			}
		}
	}

	function getXmlDocumentObject() {
		var xmlDoc
		try {
			xmlDoc = new ActiveXObject("Msxml2.DOMDocument.4.0");
		} catch(e0) {
			try {
				xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");
			} catch(e1) {
				try {
					xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
				} catch(e2) {
					xmlDoc = null;
				}
			}
		}
		return xmlDoc
	}

	function addParameter(name, value, type) {
		if (m_XmlRequest==null) {requestInit()}
		var elemParam = m_XmlRequest.createElement("Param")
		elemParam.setAttribute("name",name)
		elemParam.setAttribute("type",type)
		elemParam.text = toSafeString(value)
		m_XmlRequest.selectSingleNode("/Request").appendChild(elemParam)
	}
	
	function getRootPath(){
		var relPath = "./"
		var fullPath = document.location.pathname
		var indx = fullPath.indexOf("/",1)
		indx = fullPath.indexOf("/", indx)
		while (indx>0){
			relPath += "../"
			indx = fullPath.indexOf("/",indx+1)
		}
		return relPath
	}
	
	function toSafeString(value){
		var safeString = value
		var reLT = new RegExp("<","g")
		var reGT = new RegExp(">","g")
		var reAmp = new RegExp("&","g")
		var reSC = new RegExp(";","g")
		var reDQ = new RegExp('"',"g")
		var reSQ = new RegExp("'","g")
		safeString = safeString.replace(reLT, "_l_")
		safeString = safeString.replace(reGT, "_g_")
		safeString = safeString.replace(reAmp, "_a_")
		safeString = safeString.replace(reSC, "_s_")
		safeString = safeString.replace(reDQ, "_dq_")
		safeString = safeString.replace(reSQ, "_sq_")
		return safeString
	}
	function fromSafeString(value){
		var safeString = value
		var reLT = new RegExp("_l_","g")
		var reGT = new RegExp("_g_","g")
		var reAmp = new RegExp("_a_","g")
		var reSC = new RegExp("_s_","g")
		var reDQ = new RegExp("_dq_","g")
		var reSQ = new RegExp("_sq_","g")
		safeString = safeString.replace(reSQ, "'")
		safeString = safeString.replace(reDQ, '"')
		safeString = safeString.replace(reSC, ";")
		safeString = safeString.replace(reAmp, "&")
		safeString = safeString.replace(reGT, ">")
		safeString = safeString.replace(reLT, "<")
		/*
		safeString = safeString.replace(reLT, "<")
		safeString = safeString.replace(reGT, ">")
		safeString = safeString.replace(reAmp, "&")
		safeString = safeString.replace(reSC, ";")
		safeString = safeString.replace(reDQ, '"')
		safeString = safeString.replace(reSQ, "'")
		*/
		return safeString
	}
}
