/*
name: workspace.XML
extends: workspace
*/
workspace.XML = {}
workspace.XML._construct = function()
{
	var bNoCache = workspace.isRefresh
	
	if (bNoCache) workspace.attachEvent('afteronload', fnClearNoCache)
	
	function fnClearNoCache() { bNoCache = false; }
	
	this.getNoCache = function() { return bNoCache; }
	this.putNoCache = function(value)
	{
		workspace.detachEvent('afteronload', fnClearNoCache)
		bNoCache = value
	}
 
	function request(Method, URL, Data, CallBack, CallBackOnThis)
	{
		var ThrowError = (CallBack && CallBack.isBoolean) ? CallBack : false
		var bAsync = (CallBack && typeof(CallBack) == 'function') ? true : false
		var bCalledBack = false;
		var retVal
		
		var oXMLHttp = getHTTP()
		
		if (bAsync)
		{
			oXMLHttp.onreadystatechange = fnCallBack
			retVal = oXMLHttp
		}
	
		oXMLHttp.open(Method, workspace.dealiasUrl(URL), bAsync)
		if (bNoCache)
		{
			oXMLHttp.setRequestHeader('Pragma', 'no-cache')
		}	
		oXMLHttp.send(Data)
		
		if (oXMLHttp.readyState == workspace.XML.readyState.Completed && !bCalledBack)
		{
			// MSXML doesn't always use the call back if response returned quickly
			fnCallBack()
		
			if (!bAsync) retVal = getDOMFromRequest(oXMLHttp, ThrowError)
		}
		
		return retVal
		
		function fnCallBack()
		{
			if (oXMLHttp.readyState == workspace.XML.readyState.Completed)
			{
				bCalledBack = true
				if (bAsync) CallBack.call(CallBackOnThis, oXMLHttp)
				oXMLHttp.onreadystatechange = workspace.fnNull
			}
		}
		
	}

	function clearRequest(roXMLHttp)
	{
		if (roXMLHttp)
		{
			roXMLHttp.onreadystatechange = workspace.fnNull
			if (roXMLHttp.readyState != workspace.XML.readyState.Completed)
				roXMLHttp.abort()
			return true
		}		
	}
	
	function buildParseErrorXML(parseError)
	{
		var oError = workspace.XML.getElem("<error />")

		addElem(oError,"source", "MSXML Parser")
		addElem(oError,"number", parseError.errorCode)
		addElem(oError,"description", parseError.reason + '\r\n' )
		addElem(oError,"sourceCode", parseError.srcText)
		addElem(oError,"line", parseError.line)
		addElem(oError,"column", parseError.linepos)
							
		return oError
	}
	
	function buildEmptyXmlErrorXML(xmlHttp)
	{
		var oError = workspace.XML.getElem("<error />")

		addElem(oError,"source", "XML Response Error")
		addElem(oError,"number", 1)
		addElem(oError,"description",  'The XML request did not return any XML, however some data was returned\r\n' )
		addElem(oError,"responseText", xmlHttp.responseText)
		addElem(oError,"line", 0)
		addElem(oError,"column", 0)
							
		return oError
	}

	function getDOMFromRequest(xmlHttp, ThrowError, XMLFromText)
	{
		
		var oDOM
		var oError

		if (XMLFromText)
		{
			oDOM = parseDOM(xmlHttp.responseText)
		}
		else
		{
			oDOM = xmlHttp.responseXML
			try {oDOM.setProperty('SelectionLanguage', 'XPath'); } catch(err) {}
			if (!workspace.isIE) _moz_handleParseError.call(oDOM)
		}
				
		if (oDOM.parseError.errorCode)
			oError = buildParseErrorXML(oDOM.parseError)
		else
			oError = oDOM.selectSingleNode("/error")
		
		if (oError)
		{
			if (ThrowError)
				throw oError
			else
				showFriendlyError(oError)
		}
		else
		{
			if (oDOM.documentElement == null && (/\<html/i).test(xmlHttp.responseText))
			{
				if (ThrowError)
					throw buildEmptyXmlErrorXML(xmlHttp)
				else 
					showResponse(xmlHttp)
			}
			else
			{
				return oDOM
			}
		}
	}
	
	function addElem(elem, name, value)
	{
		var oElem = elem.ownerDocument.createElement(name)
		if (value != null) oElem.text = value
		elem.appendChild(oElem)
	}

	function requestText(Method, URL, Data, CallBack, CallBackOnThis)
	{
		var ThrowError = (CallBack && CallBack.isBoolean) ? CallBack : false
		var bAsync = (CallBack && typeof(CallBack) == 'function') ? true : false
		var bCalledBack = false;
		var retVal
		
		var oXMLHttp = getHTTP()
		
		if (bAsync)
		{
			oXMLHttp.onreadystatechange = fnCallBack
			retVal = oXMLHttp
		}
	
		oXMLHttp.open(Method, workspace.dealiasUrl(URL), bAsync)
		if (bNoCache)
		{
			oXMLHttp.setRequestHeader('pragma', 'no-cache')
		}	
		
		oXMLHttp.send(Data)
		
		if (oXMLHttp.readyState == workspace.XML.readyState.Completed && !bCalledBack)
		{
			// MSXML doesn't always use the call back if response returned quickly
			fnCallBack()
		
			if (!bAsync)
			{
		        var oError; 
		        oError = oXMLHttp.responseXML.selectSingleNode("/error")
        		
		        if (oError)
		        {
			        if (ThrowError)
				        throw oError
			        else
				        showFriendlyError(oError)
		        }
		        else
		        {
			        return oXMLHttp.responseText
		        }			
			}
		}
		function fnCallBack()
		{
			if (oXMLHttp.readyState == workspace.XML.readyState.Completed)
			{
				bCalledBack = true
				if (bAsync) CallBack.call(CallBackOnThis, oXMLHttp)
				oXMLHttp.onreadystatechange = workspace.fnNull
			}
		}		
	}

	function showFriendlyError(xml)
	{

        if (xml.selectSingleNode("//isCustomMessage")){
            var xsl = getElem("~/Message.asp?dialog=1")		
        }else{
		    var xsl = getElem("~/xslerror.asp?dialog=1")		
        }
		var sResponse = xml.ownerDocument.transformNode(xsl)
		
		var diS = new Object()
		diS.onload = function(diaDocument)
		{
			var oNewDoc = diaDocument.open("text/html", "replace");
			oNewDoc.write(sResponse)
		}
		
		if (workspace.isIE)
			window.showModalDialog(workspace.dealiasUrl("~/dialogSurrogate.htm"),diS)
		else
			window.openDialog(workspace.dealiasUrl("~/dialogSurrogate.htm"), diS)

	}

	function showResponse(xmlhttp)
	{
		var diS = {}
		diS.onload = function(diaDocument)
		{
			var oNewDoc = diaDocument.open("text/html", "replace");
			oNewDoc.write(xmlhttp.responseText);
		}
		
		if (workspace.isIE)
			window.showModalDialog(workspace.dealiasUrl("~/dialogSurrogate.htm"),diS)
		else
			window.openDialog(workspace.dealiasUrl("~/dialogSurrogate.htm"), diS)
	}

	function expand(oXML, processingInstruction)
	{
		oXML.insertBefore(oXML.createProcessingInstruction("x-unionsquare-expansion", processingInstruction), oXML.documentElement)
		return workspace.XML.post('~/XMLExpansion/Expand.asp', oXML, false)	
	}


	if (!workspace.isIE)
	{

		function _moz_Document_load(url)
		{
			_moz_changeReadyState(this, 1)
			this.__load__(url)
		}

		function _moz_handleParseError()
		{
			if (this.documentElement.tagName == 'parseerror')
			{
				this.parseError = new IXMLDOMParseError(this.xml)
				this.removeChild(this.firstChild);
			}
			else
			{
				this.parseError = new IXMLDOMParseError();
			}
			
		}
		
		function _moz_Document_onload()
		{
			_moz_handleParseError.call(this)
			_moz_changeReadyState(this, 4)
		}

		function _moz_Document_loadXML(xml)
		{
			_moz_changeReadyState(this, 1)
			var oParser = new DOMParser()
			var dom = oParser.parseFromString(xml, "text/xml")
			
			while (this.hasChildNodes())
				this.removeChild(this.lastChild);
				
			for (var i=0; i < dom.childNodes.length; i++)
			{
				var oNode = this.importNode(dom.childNodes[i], true)
				this.appendChild(oNode)
			}
			
			_moz_handleParseError.call(this)			
			_moz_changeReadyState(this, 4)
		}

		function _moz_Document_getText()
		{
			if (this.documentElement)
				return this.documentElement.textContent
			else
				return ''
		}
		
		function _moz_changeReadyState(oDOM, lReadyState)
		{
			oDOM.readyState = lReadyState
			if (oDOM.onreadystatechange) oDOM.onreadystatechange()
		}

		function _moz_Node_getXML()
		{
			return (new XMLSerializer()).serializeToString(this)
		}


		function _moz_Node_selectSingleNode(XPath)
		{
			var doc = this.ownerDocument == null ? this : this.ownerDocument
			var nsResolver = doc.nsResolver ? doc.nsResolver : doc.nsResolver = doc.createNSResolver(doc.documentElement)

			return doc.evaluate(XPath, this, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE , null).singleNodeValue
		}
		
		function _moz_Node_selectNodes(XPath) { return new IXMLDOMNodeList(this, XPath); }
		
		
		function IXMLDOMNodeList(node, XPath)
		{
			var doc = node.ownerDocument == null ? node : node.ownerDocument
			var nsResolver = doc.nsResolver ? doc.nsResolver : doc.nsResolver = document.createNSResolver(doc.documentElement)

			this.result = doc.evaluate(XPath, node, nsResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE , null)
			this.iteratorIndex = 0
		}
		IXMLDOMNodeList.prototype.getLength = function()
		{
			return this.result.snapshotLength;
		}
		IXMLDOMNodeList.prototype.__defineGetter__("length", IXMLDOMNodeList.prototype.getLength)
		IXMLDOMNodeList.prototype.item = function(index)
		{
			if (index >= 0 && index < this.result.snapshotLength)
				return this.result.snapshotItem(index)
			else
				return null
		}
		IXMLDOMNodeList.prototype.nextNode = function() { return this.item(this.iteratorIndex++); }
		IXMLDOMNodeList.prototype.reset = function() { this.iteratorIndex = 0; }
		
		mrgxParseError = />(\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/
		
		function IXMLDOMParseError(xml)
		{
			this.errorCode = 0;
			if (xml)
			{
				mrgxParseError.test(sXmlError);
				this.errorCode = -1
				this.filepos = 0
				this.reason = RegExp.$1
				this.file = RegExp.$2
				this.line = RegExp.$3
				this.linepos = RegExp.$4
				this.srcText = RegExp.$5
			}
		}
		
		Document.prototype.loadXML = _moz_Document_loadXML
		Document.prototype.readyState = 0
		Document.prototype.__load__ = Document.prototype.load
		Document.prototype.load = _moz_Document_load
		Document.prototype.onload = _moz_Document_onload
		Document.prototype.__defineGetter__("text", _moz_Document_getText)
		
		Node.prototype.__defineGetter__("xml", _moz_Node_getXML)
		Node.prototype.selectSingleNode = _moz_Node_selectSingleNode
		Node.prototype.selectNodes = _moz_Node_selectSingleNode
		Node.prototype.__defineGetter__("text", function() {return this.textContent; } )
		Node.prototype.__defineSetter__("text", function(value) { this.textContent = value; } )
		
	}

	function getHTTP()
	{
		if (window.XMLHttpRequest)
			return new XMLHttpRequest()
		else
			return new ActiveXObject("MSXML2.XMLHTTP.3.0")
	}

	function getDOM(sURL)
	{
		var oDOM
		if (!workspace.isIE)
		{
			oDOM = document.implementation.createDocument("", "", null)
			oDOM.addEventListener("load", _moz_Document_onload, false)
		}
		else
		{
			var oDOM = new ActiveXObject("MSXML2.DOMDocument.3.0");
			oDOM.setProperty("SelectionLanguage", "XPath")
			try { oDOM.setProperty("ForcedResync", false) } catch(e) {}
			oDOM.async = false
		}
		
		if (sURL) oDOM.load(workspace.dealiasUrl(sURL))
		return oDOM
	}

	function parseDOM(xml)
	{
		var oDOM
		
		if (workspace.isIE)
		{
			oDOM = getDOM()
			oDOM.loadXML(xml)
		}
		else
		{
			var oParser = new DOMParser()
			oDOM = oParser.parseFromString(xml, "text/xml")
			_moz_handleParseError.call(oDOM)
		}
		return oDOM
	}
	
	function getFreeThreadedDOM(sURL)
	{
		if (workspace.isIE)
		{
			var oDOM = new ActiveXObject("MSXML2.FreeThreadedDOMDocument.3.0")
			oDOM.setProperty("SelectionLanguage", "XPath")
			try { oDOM.setProperty("ForcedResync", false) } catch(e) {}
			oDOM.async = false
			if (sURL) oDOM.load(sURL)
			return oDOM
		}
		else
			return getDOM.apply(this, arguments)
	}
	
	function getXSLTemplate(sURL)
	{
		var oXSL = new ActiveXObject('MSXML2.XSLTemplate.3.0')
		if (sURL) oXSL.stylesheet = getFreeThreadedDOM(sURL)
		return oXSL
	}
	
	function getProcessor(transform)
	{
		var oProcessor
		
		try {oProcessor = transform.createProcessor(); }
		catch (e) {}
		
		if (!oProcessor)
		{
			if (transform && transform.isString && transform.charAt(0) == '#')
			{
					oProcessor = workspace.config.page.getRes(transform.slice(1), "text/xsl").createProcessor()
			}		
			else
			{
				var oDOM = getFreeThreadedDOM()
				
				try
				{
					if (transform.element != null)
						transform = transform.element.ownerDocument
				} catch (e) {}
				
				oDOM.load(transform)
				var oTransform = getXSLTemplate()
				oTransform.stylesheet = oDOM
				oProcessor = oTransform.createProcessor()
			}
		}		
		return oProcessor
	}
	
	function getElem(source)
	{
			var oDOM
			var oElem

			if (source == null)
			{
					oDOM = parseDOM('<root />')
			}
			else if (source.isString)
			{
				switch (source.match(/\S/)[0]) {
					case '<':
						oDOM = parseDOM(source)
						break;
					case '#':
						oElem = workspace.config.page.getRes(source.slice(1), 'text/xml').element
						break;
					default:
						oDOM = getDOM(source)
				}
			}        
			else if (typeof(source) == "object")
			{
				if (source.nodeType == nodeType.document) oDOM = source
				else if (source.nodeType == nodeType.element) oElem = source
				else if (typeof(source.lbound) != "undefined") oDOM = getDOM(), oDOM.load(source)
				else oElem = source.element
			}            
			else
			{
				throw "Type mismatch in workspace.XML.getXMLElem"
			}    
	    
			if (oDOM && oDOM.parseError.errorCode != 0) throw new Error(oDOM.parseError.errorCode, oDOM.parseError.reason)
	    
			if (!oElem && oDOM) oElem = oDOM.documentElement
	        
			return oElem    
	}
	
	function transform(input, transform, mode, output)
	{			
		if (arguments[2] && !arguments[2].isString)
		{
			output = arguments[2]
			mode = null
		}
		
		var oProcessor = getProcessor(transform)
		
		try
		{
			if (input.input)
			{
				for (var sParamName in input)
				{
					if (sParamName != 'input' && input[sParamName] != null)
						oProcessor.addParameter(sParamName, input[sParamName])
				}
				input = input.input
			}
		}
		catch(e) {}
							
		oProcessor.input = getElem(input)
		if (workspace.config)
			oProcessor.addParameter("_config", workspace.config.getWeb().element)
		
		if (mode) oProcessor.setStartMode(mode)
		
		if (output)
		{
			var canHaveHTML
			try {canHaveHTML = output.canHaveHTML || output.isContainer;}
			catch(e)	{canHaveHTML = false;}			
			
			if (canHaveHTML)
			{
				oProcessor.transform()

				if (output.isContainer)
					output.putInnerHTML(oProcessor.output)
				else if (output.myOwner && output.myOwner.isContainer) 
					output.myOwner.putInnerHTML(oProcessor.output)
				else
					output.innerHTML = oProcessor.output
				
			}
			else
			{
				oProcessor.output = output
				oProcessor.transform()				
			}

			return "<success />"	
			
		}
		else
		{
			oProcessor.transform()
			return oProcessor.output;
		}
	}
	
	if (workspace.isIE)
		try { getDOM() } catch(e) {}
		 
	workspace.XML.get = function(URL, CallBack, CallBackOnThis) { return request("GET", URL, null, CallBack, CallBackOnThis); }
	workspace.XML.post = function(URL, Data, CallBack, CallBackOnThis) {return request("POST", URL, Data, CallBack, CallBackOnThis); }
	workspace.XML.request = request
	workspace.XML.getText = function(URL, ThrowError) { return requestText("GET", URL, null, ThrowError); }
	workspace.XML.postText = function(URL, Data, ThrowError) {return requestText("POST", URL, Data, ThrowError); }
	workspace.XML.requestText = requestText
	workspace.XML.getDOMFromRequest = getDOMFromRequest
	workspace.XML.showFriendlyError = showFriendlyError
	workspace.XML.buildParseErrorXML = buildParseErrorXML
	workspace.XML.clearRequest = clearRequest
	workspace.XML.expand = expand
	workspace.XML.getDOM = getDOM
	workspace.XML.getFreeThreadedDOM = getFreeThreadedDOM
	workspace.XML.getXSLTemplate = getXSLTemplate
	workspace.XML.getHTTP = getHTTP
	workspace.XML.getElem = getElem
	workspace.XML.transform = transform
	workspace.XML.parseDOM = parseDOM
	
	var nodeType = {
		element: 1,
		attribute: 2,
		text: 3,
		cdataSection: 4,
		processingInstruction: 7,
		comment: 8,
		document: 9}
	
	workspace.XML.nodeType = nodeType
	
	workspace.XML.readyState = {
		Unintialized: 0,
		Loading: 1,
		Loaded: 2,
		Interactive: 3,
		Completed: 4}
		
}
workspace.XML._construct()
workspace.XML.scriptEval = function(script) { window.eval(script); }