﻿XmlHelper = function() {}

XmlHelper.prototype = {
    getDOMParser: function() {
        if (typeof DOMParser != "undefined") return new DOMParser();
        var domParser = new Object;
        domParser.parseFromString = function (str, contentType) {
            if (typeof XMLHttpRequest != "undefined") {
                try {
                    var req = new XMLHttpRequest;
                    req.open("GET", "data:" + (contentType || "application/xml") + ";charset=utf-8," + encodeURIComponent(str), false);
                    if (req.overrideMimeType) req.overrideMimeType(contentType);
                    req.send(null);
                    return req.responseXML;
                } catch(e){}
            }
            if (typeof ActiveXObject != "undefined") {
                var doc = null;
                try { doc = new ActiveXObject("MSXML2.DomDocument"); } 
                catch(e) {
                    try { doc = new ActiveXObject("MSXML.DomDocument"); } catch(e){}
                }
                if (doc) { doc.loadXML(str); return doc; }
            }
            return null;
            alert("Your browser doesn't support XML DOM.");
        }
        return domParser;
    },
    
    LoadXmlByHttpRequest: function(url, async, cbFunc)
    {
        var req = null;
        if (async && !cbFunc)
            throw new Error(msnevs_XmlListViewErrors.settingErr);
        if (!async) async = false;

        if (typeof XMLHttpRequest != "undefined") {
            try { var req = new XMLHttpRequest; }
            catch(e){}
        }
        else if (typeof ActiveXObject != "undefined") {
   	        try {
    	        req = new ActiveXObject("Msxml2.XMLHTTP");
  	        } catch(e) {
    	        try {
      		        req = new ActiveXObject("Microsoft.XMLHTTP");
    	        } catch(e) {
      		        req = null;
    	        }
	        }
        }
        
        getXmlDocByHttpRequest = function(request) {
            if (request.responseXML.documentElement)
                return request.responseXML;
            else if (request.responseText) {
                var parser = msnevs_GetDOMParser();
                if (parser)
                    return parser.parseFromString(request.responseText, "text/xml");
            }
            else
                return null;
        }
        
        if (req) {
            try {
                if (async) {
                    req.onreadystatechange = function() {
                        if (req.readyState == 4)
                            if (req.status == 200)
                                cbFunc(getXmlDocByHttpRequest(req));
                            else
                                alert("Failed in retrieving the XML data:\n" + req.statusText);
                    }
                }
                
                req.open("GET", url, async);
                req.send(null);
                if (!async)
                    return getXmlDocByHttpRequest(req);
                else
                    return true;
            }
            catch(e)
            {}
        }

        alert("Failed in retrieving the XML data.");
        return null;
    },

    LoadXml: function(url, async, cbFunc)
    {
        var xmlDoc = null;
        
        if (document.implementation && document.implementation.createDocument)
        {
            xmlDoc = document.implementation.createDocument("", "", null);
            if (xmlDoc == null) 
                return null;
            
            xmlDoc.async = async;
            if (async)
            {
                xmlDoc.onload = function() {
                    cbFunc(xmlDoc);
                }
            }
        }
        else if (typeof ActiveXObject != "undefined")
        {
            try
            {
                xmlDoc = new ActiveXObject("MSXML2.DOMDocument");
            }
            catch(e)
            {
                xmlDoc = new ActiveXObject("MSXML.DOMDocument");
            }
            if (xmlDoc == null)
                return null;
            
            xmlDoc.async = async;
            if (async)
            {
                xmlDoc.onreadystatechange = function( ) {
                    if (xmlDoc.readyState == 4) cbFunc(xmlDoc);
                };
            }
        }
        xmlDoc.load(url);
        return xmlDoc;
    },

    getXmlDoc: function(type, data) {
        switch(type.toLowerCase()) {
            case "string":
                var parser = this.getDOMParser();
                if (parser) {
                    var xmlDoc = parser.parseFromString(data, "text/xml");
                    if (!xmlDoc) return null;
                    return xmlDoc;
                }
                else { return null; }
                break;
            case "url":
                var xmlDoc = this.LoadXmlByHttpRequest(data);
                return xmlDoc;
            default:
                return data;
        }
    },

    getXmlNodeValue: function(element) {
        if (element && element.childNodes && element.childNodes.length > 0)
            return element.childNodes[0].nodeValue;
        else
            return null;
    },
    
    selectNodes: function(element, xpath, namespaceURLMapper) {
        if (!element || !xpath) return null;

        if (typeof(element.selectNodes) != "undefined") {
            return element.selectNodes(xpath);
        }
        else if (typeof(XPathEvaluator) != "undefined") { // && namespaceURLMapper == null) {
            var xEvaluator = new XPathEvaluator();
            if (!xEvaluator) return null;
            var xIterator = xEvaluator.evaluate(xpath, element, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
            var nodes = new Array;
            if (xIterator != null) {
                var newNode = xIterator.iterateNext();
                while(newNode) {
                    nodes.push(newNode);
                    newNode = xIterator.iterateNext();
                }
            }
            return nodes;
        }
        else if (typeof(document.createExpression) != "undefined") {
            var xpathExpr = document.createExpression(xpath, namespaceURLMapper);
            var xEvaluator = xpathExpr.evaluate(element, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
            if (xEvaluator) {
                var nodes = new Array(xEvaluator.snapshotLength);
                for (var i = 0; i < xEvaluator.snapshotLength; i++)
                    nodes[i] = xEvaluator.snapshotItem(i);
                return nodes; 
            }        
        }
        else
            return this.selectNodesInSafari(element, xpath);

        return null;
    },

    selectSingleNode: function(element, xpath) {
        if (!element || !xpath) return null;

        if (typeof(element.selectSingleNode) != "undefined") {
            return element.selectSingleNode(xpath);
        }
        else if (typeof(XPathEvaluator) != "undefined") {
            var xEvaluator = new XPathEvaluator();
            var xIterator = xEvaluator.evaluate(xpath, element, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
            if (xIterator)
                return xIterator.iterateNext();
            else
                return null;
       }
       else
           return this.selectSingleNodeInSafari(element, xpath);
    },

    parserXPathInSafari: function(xpath) {
        var nodes = xpath.split("/");
        if (!nodes || nodes.length < 1) return null;

        var result = new Array();
        for (var i = 0; i < nodes.length; i++) {
            if (nodes[i] != "") {
                var nodeObj = this.parserXpathNodeInSafari(nodes[i]);
                if (nodeObj) result.push(nodeObj);
            }
        }
        if (result.length > 0)
            return result;
        else
            return null;
    },

    parserXpathNodeInSafari: function(node) {
        var nodeStr = node;
        var r = new Object();
        r.nodeName = null;
        r.filterName = null;
        r.filterValue = null;
        
        var pos = nodeStr.indexOf("[");
        if (pos < 0) {
            r.nodeName = nodeStr;
            return r;
        }
        else
            r.nodeName = nodeStr.substr(0, pos);
        
        nodeStr = nodeStr.substr(pos + 1);
        pos = nodeStr.indexOf("=");
        if (pos < 0) return r;
        r.filterName = nodeStr.substr(0, pos);
        
        pos = nodeStr.indexOf("'");
        var pos2 = nodeStr.lastIndexOf("'");
        if (pos < 0 || pos2 < 0 || pos == pos2) {
            r.filterName = null;
            return;
        }
        r.filterValue = nodeStr.substr(pos + 1, pos2 - pos - 1);
        return r;
    },

    selectNodesInSafari: function(element, xpath) {
        _filterNodes = function(nodes, filterName, filterValue) {
            if (!nodes || nodes.length < 0) return null;
            if (!filterName || !filterValue) return nodes;
            for (var i = 0; i < nodes.length; i++) {
                var snodes = nodes[i].getElementsByTagName(filterName);
                if (snodes && snodes.length > 0)
                    if (msnevs_getXmlNodeValue(snodes[0]) == filterValue)
                        continue;
                snodes = null;           
                nodes.splice(i, 1);
                i--;
            }
            return nodes;
        }
            
        _getNodes = function(nodes, xpObject) {
            if (!nodes || nodes.length < 1) return null;
            var result = new Array();
            for (var i = 0; i < nodes.length; i++) {
                var tempNodes = nodes[i].getElementsByTagName(xpObject.nodeName);
                if (tempNodes && tempNodes.length > 0)
                    for (var j = 0; j < tempNodes.length; j++)
                        result.push(tempNodes[j]);
            }
            if (result && xpObject.filterName && xpObject.filterValue)
                result = _filterNodes(result, xpObject.filterName, xpObject.filterValue);
            return result;
        }

        var xpList = this.parserXPathInSafari(xpath);
        if (!xpList || xpList.length < 1)
            return null;
        
        var nodes = new Array();
        nodes.push(element);
        for (var i = 0; i < xpList.length; i++) {
            nodes = _getNodes(nodes, xpList[i]);
        }
        return nodes;
    },

    selectSingleNodeInSafari: function(element, xpath) {
        var nodes = this.selectNodesInSafari(element, xpath);
        if (nodes && nodes.length > 0)
            return nodes[0];
        else
            return null;
    },
    
    getJsonField: function(data, tags, index) {
        _getFilter = function(tag) {
            var pos = tag.indexOf('[');
            if(pos < 0) return null;
            var field = tag.substr(0, pos);
            var temp = tag.substr(pos + 1);
            pos = temp.indexOf(']');
            if (pos > -1) temp = temp.substr(0, pos);
            pos = temp.indexOf('=');
            var result = new Object();
            if (pos < -1) {
                result.type = "attr";
                result.field = field;
                result.filter = temp.substr(0, pos);
                result.fvalue = temp.substr(pos+1);
                return result;
            }
            else {
                try {
                    var index = parseInt(temp);
                    result.type = "index";
                    result.field = field;
                    result.index = index;
                    return result;
                }
                catch(e) {
                    result.type = "normal";
                    result.field = field;
                    return result;
                }
            }
        }
                
        _getField = function(data, tag) {
            if (!data) return null;
            if (!tag) return data;
            var filter = _getFilter(tag);
            if (!filter) {
                if (tag != "$")
                    return data[tag];
                else {
                    if (data.$)
                        return data.$;
                    else
                        return null;
                }
            }
            else {
                switch(filter.type) {
                    case "normal":
                        if (filter.field != "$")
                            return data[filter.field];
                        else {
                            if (data.$)
                                return data.$;
                            else
                                return null;
                        }
                    case "index":
                        var list = data[filter.field];
                        if (list.length && list.length > filter.index)
                            return list[filter.index];
                        else
                            return null;
                    case "attr":
                        var list = data[filter.field];
                        if (list && list.length && list.length > 0) {
                            for (var i = 0; i < list.length; i++)
                                if (list[i][filter.filter] && list[i][filter.filter] == filter.fvalue)
                                    return list[i];
                        }
                        return null;
                }
            }
            return null;
        }
        
        if (!data) return null;
        if (!tags) return data;
        var taglist = tags.split('/');
        if (!taglist && taglist.length <= 0) return null;
        var r = data;
        for (var i = 0; i < taglist.length; i++)
            r = _getField(r, taglist[i]);
        if (index != null && index >= 0) {
            if (r.length && r.length >index)
                return r[index];
        }
        return r;
    }
}

