/*
Program:
Husky Mounted Detection System (HMDS)

Source:
EOIR Technologies
PO Box 1240
Spotsylvania, VA  22553

HMDS Development Team
USA CECOM Night Vision and Electronic Sensors Directorate (NVESD)
10221 Burbeck Rd., STE 430
Fort Belvoir, VA 22060

Conditions for Use:
This software is Copyright(C) EOIR Technologies, Inc.

EOIR Technologies has all commercial interest and rights.
NVESD has full rights, title, and interest.

This software is provided "as is", without warranty by 
EOIR Technologies, Inc and NVESD. In no event shall EOIR 
Technologies, Inc. or NVESD be liable for any loss or for
any indirect, special, punitive, exemplary, incidental, or 
consequential damages arising from the use, possession, or
performance of this software.
*/

// Relies on Sarissa


var EOIR = EOIR ? EOIR : function()
{
	var obj =
	{
};

return obj;

} ();

EOIR.XML = function ()
{
    var obj =
	{
	    createObject: function ()
	    {
	        return Sarissa.getDomDocument();
	    },

	    loadFromString: function (strXML, strNamespace)
	    {
	        //THIS DOES NOT WORK IN IE. EVEN THE ERROR CHECKING DOESN'T WORK, AS IE RETURNS AN ERROR DOCUMENT - NOT NULL - ON FAILURE. 

	        var doc = new DOMParser().parseFromString(strXML, "text/xml");
	        if (doc != null)
	        {
	            this.setXPathNamespaces(doc, strNamespace);
	        }
	        return doc;
	    },

	    // Creates and loads an XML document
	    load: function (strUrl, bAsyncLoad, fnComplete, strNamespace, param)
	    {
	        return this.loadDocument(this.createObject(), strUrl, bAsyncLoad, fnComplete, strNamespace, param);
	    },

	    _load: function (strUrl, bAsyncLoad, fnComplete, strNamespace, param)
	    {
	        if (bAsyncLoad == null)
	        {
	            bAsyncLoad = false;
	        }
	        var req = new XMLHttpRequest();

	        var bErrorThrown = false;
	        var ThrowError = function (docXML, fnComplete)
	        {
	            if (!bErrorThrown)
	            {
	                bErrorThrown = true;

	                var err = new Error();
	                err.message = err.description = Sarissa.getParseErrorText(docXML);
	                err.name = "XML Load Error";

	                if (fnComplete != null)
	                {
	                    fnComplete(null, param, err);
	                }
	                else
	                {
	                    throw err;
	                }
	            }
	        }

	        if (fnComplete != null)
	        {
	            req.onreadystatechange = function ()
	            {
	                // Sometimes this can be called synchronously to the load which
	                // means that load function has not returned yet.
	                if (req.readyState == 4 /* complete */ || req.readyState == "complete")
	                {
	                    var docXML = req.responseXML;
	                    var bError = false;
	                    if (req.status != 200)
	                    {
	                        ThrowError(docXML, fnComplete);
	                        bError = true;
	                    }

	                    EOIR.XML.setXPathNamespaces(docXML, strNamespace);

	                    if (!bError)
	                    {
	                        fnComplete(param);
	                    }

	                    // This breaks the onreadystate circular reference so that
	                    // memory can be properly garbage collected.
	                    req.onreadystatechange = new Function();
	                }
	            };
	        }

	        req.open("GET", strUrl, bAsyncLoad);

	        //var bIsIE = true;//document.all && window.ActiveXObject && navigator.userAgent.toLowerCase().indexOf("msie") > -1  && navigator.userAgent.toLowerCase().indexOf("opera") == -1;
	        var bIsIE = (navigator.userAgent.toLowerCase().indexOf("msie") > -1 || navigator.userAgent.toLowerCase().indexOf("trident") > -1) && navigator.userAgent.toLowerCase().indexOf("opera") == -1;
	        if (bIsIE)
	        {
	            try { req.responseType = 'msxml-document'; } catch (e) { }
	        }
	        req.send();

	        if (!bAsyncLoad)
	        {
	            var docXML = req.responseXML;
	            if (req.status == 200)
	            {
	                this.setXPathNamespaces(docXML, strNamespace);
	                return docXML;
	            }
	            else
	            {
	                ThrowError(docXML, fnComplete);
	            }
	        }

	        return null;
	    },

	    // Loads a XML document
	    loadDocument: function (docXML, strUrl, bAsyncLoad, fnComplete, strNamespace, param)
	    {
	        //if(!docXML || !docXML.load){
	        //    return this._load(strUrl, bAsyncLoad, fnComplete, strNamespace, param);
	        //}

	        if (bAsyncLoad == null)
	        {
	            bAsyncLoad = false;
	        }
	        docXML.async = bAsyncLoad; // this is the important part

	        if (param == null)
	        {
	            param = docXML;
	        }

	        var bErrorThrown = false;
	        var ThrowError = function (docXML, fnComplete)
	        {
	            if (!bErrorThrown)
	            {
	                bErrorThrown = true;

	                var err = new Error();
	                err.message = err.description = Sarissa.getParseErrorText(docXML);
	                err.name = "XML Load Error";

	                if (fnComplete != null)
	                {
	                    fnComplete(null, param, err);
	                }
	                else
	                {
	                    throw err;
	                }
	            }
	        }

	        if ((strUrl.substr(0, 4) == "http" && navigator.appVersion.toLowerCase().indexOf("msie") != -1) || navigator.appVersion.indexOf("Chrome") != -1)
	        {
	            var req = new XMLHttpRequest();

	            if (fnComplete != null)
	            {
	                req.onreadystatechange = function ()
	                {
	                    // Sometimes this can be called synchronously to the load which
	                    // means that load function has not returned yet.
	                    if (req.readyState == 4 /* complete */ || req.readyState == "complete")
	                    {
	                        try
	                        {
	                            docXML.loadXML(req.responseText);
	                        }
	                        catch (e)
	                        {
	                            docXML = req.responseXML/*.documentElement*/;
	                            param = docXML;
	                        }

	                        if (docXML.parseError && docXML.parseError.errorCode && docXML.parseError.errorCode != 0)
	                        {
	                            ThrowError(docXML, fnComplete);
	                        }
	                        else
	                        {
	                            try
	                            {
	                                if (docXML.documentElement == null)
	                                {
	                                    ThrowError(docXML, fnComplete);
	                                    return;
	                                }
	                            }
	                            catch (e)
	                            {
	                            }

	                            EOIR.XML.setXPathNamespaces(docXML, strNamespace);

	                            fnComplete(param);

	                            // This breaks the onreadystate circular reference so that
	                            // memory can be properly garbage collected.
	                            req.onreadystatechange = new Function();
	                        }
	                    }
	                };
	            }

	            req.open("GET", strUrl, bAsyncLoad);
	            req.send();

	            if (!bAsyncLoad)
	            {
	                if (req.status == 200)
	                {
	                    try
	                    {
	                        docXML.loadXML(req.responseText);
	                    }
	                    catch (e)
	                    {
	                        docXML = req.responseXML.documentElement;
	                    }
	                }
	                else
	                {
	                    ThrowError(docXML, fnComplete);
	                }
	            }
	        }
	        else
	        {
	            if (fnComplete != null)
	            {
	                docXML.onreadystatechange = function ()
	                {
	                    // Sometimes this can be called synchronously to the load which
	                    // means that load function has not returned yet.
	                    if (docXML.readyState == 4 /* complete */ || docXML.readyState == "complete")
	                    {
	                        if (docXML.parseError && docXML.parseError.errorCode && docXML.parseError.errorCode != 0)
	                        {
	                            ThrowError(docXML, fnComplete);
	                        }
	                        else
	                        {
	                            try
	                            {
	                                if (docXML.documentElement == null)
	                                {
	                                    ThrowError(docXML, fnComplete);
	                                    return;
	                                }
	                            }
	                            catch (e)
	                            {
	                            }

	                            EOIR.XML.setXPathNamespaces(docXML, strNamespace);

	                            fnComplete(param);

	                            // This breaks the onreadystate circular reference so that
	                            // memory can be properly garbage collected.
	                            docXML.onreadystatechange = new Function();
	                        }
	                    }
	                };
	            }

	            if (!docXML.load(strUrl))
	            {
	                ThrowError(docXML, fnComplete);
	            }
	            else
	            {
	                if (docXML.parseError && docXML.parseError.errorCode && docXML.parseError.errorCode != 0)
	                {
	                    ThrowError(docXML, fnComplete);
	                }
	            }
	        }

	        if (!bAsyncLoad)
	        {
	            this.setXPathNamespaces(docXML, strNamespace);
	            if (docXML.parseError != null && docXML.parseError.errorCode != 0)
	            {
	                //					alert("Error parsing " + strUrl + "   " + Sarissa.getParseErrorText(docXML));
	                return null;
	            }
	        }

	        return docXML;
	    },

	    setXPathNamespaces: function (docXML, strNamespace)
	    {
	        if (strNamespace != null)
	        {
	            Sarissa.setXpathNamespaces(docXML, strNamespace);
	        }
	        else
	        {
	            this.setProperty(docXML, "SelectionLanguage", "XPath");
	        }
	    },

	    setProperty: function (docXML, strPropName, strPropVal)
	    {
	        try
	        {
	            docXML.setProperty(strPropName, strPropVal);
	        }
	        catch (e)
	        {
	        }
	    },

	    serializeText: function (node, bRecurse)
	    {
	        var xmlSerializer = new XMLSerializer();

	        var str = "";
	        var nodesText = node.selectNodes(bRecurse ? "//text()" : "text()");
	        for (var i = 0; i < nodesText.length; i++)
	        {
	            try
	            {
	                str += xmlSerializer.serializeToString(nodesText[i]);
	            }
	            catch (e)
	            {
	                //ie saw fit to add the serializetostring function, but did not see fit to implement it. so it throws an exception every time.

	                //we do this instead, which is equivalent. which makes you wonder, why didn't they just do this inside the function themselves?

	                if ('xml' in nodesText[i])
	                    str += nodesText[i].xml;
	            }
	        }

	        return str;
	    },

	    serialize: function (node)
	    {
	    	return new XMLSerializer().serializeToString(node);
	    },

	    serializeChildren: function (node)
	    {
	        var xmlSerializer = new XMLSerializer();

	        var str = "";
	        var nodesText = node.selectNodes("node()");
	        for (var i = 0; i < nodesText.length; i++)
	        {
	            try
	            {
	                str += xmlSerializer.serializeToString(nodesText[i]);
	            }
	            catch (e)
	            {
	                //ie saw fit to add the serializetostring function, but did not see fit to implement it. so it throws an exception every time.

	                //we do this instead, which is equivalent. which makes you wonder, why didn't they just do this inside the function themselves?

	                if ('xml' in nodesText[i])
	                    str += nodesText[i].xml;
	            }
	        }
	        return str;
	    },

	    selectSingleNodeAndGetAttribute: function (node, xpath, attrName, defVal)
	    {
	        var nodeSel = node.selectSingleNode(xpath);
	        if (nodeSel == null)
	        {
	            return defVal;
	        }
	        else
	        {
	            var attrVal = nodeSel.getAttribute(attrName);
	            return (attrVal == null) ? defVal : attrVal;
	        }
	    }

	};

    return obj;
} ();


/*
try
{
	EOIR.addComponent("sarissa");
	EOIR.componentAvailable("xml");
}
catch(e)
{
}
*/
