function XmlParser(){

    var requestor;

    function getTitle(xmlDoc, object){
        var title = xmlDoc.getElementsByTagName("title");
        if(title !== null && title.length > 0){
            var titleObject = title[0];
            if(titleObject.childNodes.length > 0){
                var textObject = titleObject.firstChild;
                var text = textObject.nodeValue;
                document.title = text;
            }
        }
    }

    function getStyleSheets(xmlDoc, object){
        var styleSheets = xmlDoc.getElementsByTagName("style");
        if(styleSheets !== null && styleSheets.length > 0){
            var urls = styleSheets[0].getElementsByTagName("url");
            for(var x = 0; x < urls.length; x++){
                if(urls[x].childNodes.length === 1){
                    System.windowmanager.appendStyleSheet(urls[x].childNodes[0].nodeValue);
                }
            }
        }
    }

    function getPostProcessScripts(xmlDoc,object){
        var scriptList = xmlDoc.getElementsByTagName("postProcess");
        if(scriptList !== null && scriptList.length > 0){
            var scripts = scriptList[0].getElementsByTagName("script");
            var script;
            for(var x = 0; x < scripts.length; x++){
                if(scripts[x].childNodes.length === 1){
                    script = scripts[x].childNodes[0].nodeValue;
                    object.addSubscriber("onpostprocess",new Function("self",script));
                }
            }
        }
    }

    function getDocumentScripts(xmlDoc, object){
        var styleSheets = xmlDoc.getElementsByTagName("script");
        if(styleSheets !== null && styleSheets.length > 0){
            for(var y = 0; y < styleSheets.length; y++){
                var urls = styleSheets[y].getElementsByTagName("url");
                for(var x = 0; x < urls.length; x++){
                    if(urls[x].childNodes.length === 1){
                        System.windowmanager.appendJavaScript(urls[x].childNodes[0].nodeValue);
                    }
                }
            }
        }
    }

    function getMessages(xmlDoc, object){
        var messages = xmlDoc.getElementsByTagName("message");
        var message;
        for(var x = 0; x < messages.length; x++){
            message = messages[x];
            if (message !== undefined){
                var mType = message.getAttribute("type");
                var mId = message.getElementsByTagName("id")[0].childNodes[0].nodeValue;
                var mText = message.getElementsByTagName("text")[0].childNodes[0].nodeValue;
                var popout;
                switch(mType){
                    case "Error":
                        popout = System.notifications.dialog();
                        popout.setTitle(null,"System Error - " + mId);
                        popout.setContent(document.createTextNode(mText));
                        break;
                    case "Warning":
                        popout = System.notifications.dialog();
                        popout.setTitle(null,"System Warning");
                        popout.setContent(document.createTextNode(mText));
                        break;
                    case "Notification":
                        popout = System.notifications.dialog();
                        popout.setTitle(null,"System Alert");
                        popout.setContent(document.createTextNode(mText));
                        break;
                }
            }
        }
    }

    function preparePopout(htmlCodeNode,disposition,owner,config){
        var node;
        var parent = document.getElementById(owner);
        switch(disposition){
            case "new":
                node = (config.id !== undefined) ? document.getElementById(config.id) : null;
                if(node === null || node.isContainer === undefined){
                    try{
                        node = parent.createFrame(config);
                        node.id = (config.id === undefined || node.isContainer === undefined) ? "window_"+parent.getWindowCount() : config.id;
                    }catch(e){
                        throw "Invalid parent object.  Not a valid container. ["+e+"]";
                    }
                }else{
                    parent.sendToFront(node);
                    //node.setContent(document.createTextNode(""));
                }
                break;
            case "appenditure":
                node = parent;
                break;
            case "replacement":
                node = parent;
                break;
        }
        var replaced;
        for(var id = htmlCodeNode.childNodes.length; id > 0 ; id--){
            replaced = false;
            if(htmlCodeNode.childNodes[0].id != ""){
                for(var iter = 0; iter < parent.childNodes.length; iter++){
                    if(parent.childNodes[iter].id == htmlCodeNode.childNodes[0].id){
                        parent.replaceChild(htmlCodeNode.childNodes[0],parent.childNodes[iter]);
                        replaced = true;
                    }
                }
            }
            if(!replaced){
                node.addContent(htmlCodeNode.childNodes[0]);
            }
        }
        return node;
    }

    function prepareSection(htmlCodeNode,disposition,ownerId){
        var parent = document.getElementById(ownerId);
        if(parent === null){
            throw "Invalid Parent Object ["+ownerId+"] ["+document.getElementById(ownerId)+"]";
        }
        var node;
        switch(disposition){
            case "new":
                node = parent;
                break;
            case "appenditure":
                node = parent;
                break;
            case "replacement":
                try{
                    parent.empty();
                }catch(e){
                    for(var i = parent.childNodes.length; i > 0; i--){
                        parent.removeChild(parent.childNodes[0]);
                    }
                }
                node = parent;
                break;
        }
        var replaced;
        for(var id = htmlCodeNode.childNodes.length; id > 0 ; id--){
            replaced = false;
            if(htmlCodeNode.childNodes[0].id != ""){
                for(var iter = 0; iter < parent.childNodes.length; iter++){
                    if(parent.childNodes[iter].id == htmlCodeNode.childNodes[0].id){
                        parent.replaceChild(htmlCodeNode.childNodes[0],parent.childNodes[iter]);
                        replaced = true;
                    }
                }
            }
            if(!replaced){
                node.appendChild(htmlCodeNode.childNodes[0]);
            }
        }
        return node;
    }

    function prepareResponse(htmlCodeNode,disposition,owner){
        var parent = document.getElementById(owner);
        if(disposition != "appenditure"){
            try{
                parent.empty();
            }catch(e){
                for(var i = parent.childNodes.length; i > 0; i--){
                    parent.removeChild(parent.childNodes[0]);
                }
            }
        }
        var node = parent;
        var replaced;
        for(var id = htmlCodeNode.childNodes.length; id > 0 ; id--){
            replaced = false;
            if(htmlCodeNode.childNodes[0].id != ""){
                for(var iter = 0; iter < parent.childNodes.length; iter++){
                    if(parent.childNodes[iter].id == htmlCodeNode.childNodes[0].id){
                        parent.replaceChild(htmlCodeNode.childNodes[0],parent.childNodes[iter]);
                        replaced = true;
                    }
                }
            }
            if(!replaced){
                node.appendChild(htmlCodeNode.childNodes[0]);
            }
        }
        return node;
    }

    function getContent(xmlDoc,object){

        var xmlSectionType;
        var xmlSectionDisposition;
        var xmlSectionOwner;
        var xmlSectionNode;
        var xmlContentNode;
        var htmlContentNode;
        var config;
        var node;

        var xmlSectionNodeList = xmlDoc.getElementsByTagName("section");

        for(var x = (xmlSectionNodeList.length - 1); x >= 0; x--){
            xmlSectionNode = xmlSectionNodeList.item(x);
            xmlSectionType = xmlSectionNode.getAttribute("type");
            xmlSectionDisposition = xmlSectionNode.getAttribute("disposition");
            xmlSectionOwner = xmlSectionNode.getAttribute("owner");

            xmlContentNode = getHTMLasXML(getHTMLText(xmlSectionNode));
            htmlContentNode = System.htmlparser.parse(xmlContentNode,object);
            config = prepareConfiguration(xmlSectionNode);
            switch(xmlSectionType){
                case "frame":
                    node = preparePopout(htmlContentNode,xmlSectionDisposition,xmlSectionOwner,config);
                    break;
                case "anchoredFrame":
                    node = prepareSection(htmlContentNode,xmlSectionDisposition,xmlSectionOwner);
                    break;
                case "response":
                    node = prepareResponse(htmlContentNode,xmlSectionDisposition,xmlSectionOwner);
                    break;
                default:
                    //node = preparePopout(htmlContentNode,xmlSectionDisposition,xmlSectionOwner,config);
                    break;
            }
        }
        System.windowmanager.refocus();
    }

    function getUpdates(xmlDoc,object){
        var xmlUpdateList = xmlDoc.getElementsByTagName("update");
        if(xmlUpdateList.length <= 0){
            //throw "Lassie";
            return;
        }
        var xmlUpdateNode = xmlUpdateList[0];
        if(xmlUpdateNode.childNodes.length > 0){
            var xmlIdList = xmlUpdateNode.getElementsByTagName("id");
            var xmlIdNode;
            for(var x = 0; x < xmlIdList.length; x++){
                xmlIdNode = xmlIdList.item(x);
                System.windowmanager.updateView(xmlIdNode.firstChild.nodeValue);
            }
        }
    }

    function getDetails(xmlDoc,object){
        var xmlDetailsList = xmlDoc.getElementsByTagName("details");
        if(xmlDetailsList.length <= 0){
            //throw "Lassie";
            return;
        }
        var xmlDetailsNode = xmlDetailsList[0];
        var statusCodeList = xmlDetailsNode.getElementsByTagName("status");
        var requestorList = xmlDetailsNode.getElementsByTagName("requestor");
        var processTimeList = xmlDetailsNode.getElementsByTagName("processTime");
        if (statusCodeList.length <= 0 || requestorList.length <= 0 || processTimeList.length <= 0){
            //throw "Lassie";
        }else{
            var statusCodeNode = statusCodeList[0];
            var statusCode = statusCodeNode.firstChild.nodeValue;
            var requestorNode = requestorList[0];
            var requestorId = requestorNode.firstChild.nodeValue;
            var requestor = document.getElementById(requestorId);
            var processTimeNode = processTimeList[0];
            var processTime = processTimeNode.firstChild.nodeValue;
            var window;
            switch(statusCode){
                case "10":
                    window = findCloseableObject(requestor);
                    window.close();
                    break;
                case "20":
                    break;
                case "30":
                    break;
                case "40":
                    break;
                case "50":
                    window = findCloseableObject(requestor);
                    System.windowmanager.updateView(window);
                    break;
            }
        }
    }

    function retrieveAsXML(collectionOfTextNodes){
        var text = "";
        for(var x = 0; x < collectionOfTextNodes.length; x++){
            text += collectionOfTextNodes[x].nodeValue;
        }
        var xmlObject;
        var xmlParser;
        if(System.browser.isIE()){
            xmlObject = new ActiveXObject("Microsoft.XMLDOM");
            xmlObject.async = "false";
            xmlObject.loadXML(text);
        }else{
            xmlParser = new DOMParser();
            xmlObject = xmlParser.parseFromString(text,"text/xml");
            if (xmlObject.documentElement.nodeName=="parsererror"){
                //Error Object
                //  xmlObject.documentElement.childNodes[0].nodeValue
            }
        }
        return xmlObject;
    }

    function getHTMLText(contentNode){
        var xmlCodeNodeList = contentNode.getElementsByTagName("content");
        if(xmlCodeNodeList.length != 1){
            throw "Invalid HTML Passed.";
        }
        var xmlCodeNode = xmlCodeNodeList.item(0);
        if(xmlCodeNode.childNodes === undefined || xmlCodeNode.childNodes.length < 1){
            throw "No HTML Passed.";
        }
        return xmlCodeNode;
    }

    function getHTMLasXML(xmlCodeNode){
        var xmlCodeDocument = retrieveAsXML(xmlCodeNode.childNodes);
        var xmlCodeNodeList = xmlCodeDocument.getElementsByTagName("code");
        return xmlCodeNodeList[0];
    }

    function prepareConfiguration(xmlContentNode){
        var tagList;
        var tagNode;
        var value;
        var config = {};
        var configOptions = [ "id", "center", "theme", "width", "height", "left", "top", "right", "bottom", "titleAlign", "contentAlign", "closeable", "maximizeable", "minimizeable", "moveable", "size", "resizeable", "overlay", "title", "icon", "content", "maximized" ];
        for(var x = 0; x < configOptions.length; x++){
            tagList = xmlContentNode.getElementsByTagName(configOptions[x]);
            if (tagList.length > 0){
                tagNode = tagList[0];
                value = (tagNode.childNodes.length > 0) ? tagNode.childNodes[0].nodeValue : undefined;
                value = (value === "false") ? false : value;
                value = (value === "true") ? true : value;
                config[configOptions[x]] = value;
            }
        }
        return config;
    }

    function findCloseableObject(obj){
        if(obj.isCloseable !== undefined){
            return obj;
        }else{
            return findCloseableObject(obj.parentNode);
        }
    }

    var xmlparser = {
        parse : function(xmlDocument){
            try{
                if(xmlDocument !== null){
                    var object = {};
                    System.publish(object);
                    object.addSubscriber("onpostprocess",function(){});
                    getDocumentScripts(xmlDocument,object);
                    getTitle(xmlDocument,object);
                    getStyleSheets(xmlDocument,object);
                    getMessages(xmlDocument,object);
                    getContent(xmlDocument,object);
                    getDetails(xmlDocument,object);
                    getUpdates(xmlDocument,object);
                    object.addSubscriber("onpostprocess",System.windowmanager.resize);
                    getPostProcessScripts(xmlDocument,object);
                    object.creator = requestor;
                    object.onpostprocess();
                }
            }catch(e){
                alert("Post Processing Error: " + e.toString());
            }
        }

    };

    System.xmlparser = xmlparser;

}

