/*** Supridatta Teleinformática Ltda. Copyright(2000) ***
* Classe...: SpdtXML
* Proposito: Parse e editor de XML em Strings
* Data.....: 01/11/2001
* Autor....: Clóvis Wichoski
***/
var uidControlSpdtXML = -1; //Gerador de ids unicos para tags
var MAX_VALUE = 2147483647;

function addElementSpdtXML(name) {
    var element = new ElementSpdtXML(name);
    element.parent = this;
    element.pos = this.elements.length;
    this.elements[element.pos] = element;
    return element;
}
function addElementElementSpdtXML(element) {
    element.parent = this;
    element.pos = this.elements.length;
    this.elements[element.pos] = element;
    return element;
}
function addAttributeElementSpdtXML(name,value) {
    var attribute = new attributeSpdtXML(name,value);
    this.attributes[this.attributes.length] = attribute;
}
function getElementSpdtXML(xpath) {
    var rtno = null;
    var tokenBase = toTokenBase(xpath,"/");
    var element = null;
    var elements = null;
    if (tokenBase[0].indexOf('[') == -1) {
        elements = this.getElementsByName(tokenBase[0]);
        element = (elements.length == 1) ? elements[0] : null;
    } else {
        element = this.getElementByExpr(tokenBase[0]);
    }
    if (element) {
        if (tokenBase[1] != "") {
            element = element.getElement(tokenBase[1]);
        }
    } else if (elements) {
        if (elements.length > 1) {
            if (tokenBase[1] != "") {
                for(var n=0; n < elements.length; n++) {
                    element = elements[n];
                    element = element.getElement(tokenBase[1]);
                    if (element) {
                        break;
                    }
                }
            }
        }
    }
    return element;
}
function rmElementSpdtXML(xpath) {
    var element = this.getElement(xpath);
    if (element != null) element.parent.elements[element.pos] = null;
}
function setElementElementSpdtXML(xpath,newElement) {
    var element = this.getElement(xpath);
    if (element) {
        element.parent.elements[element.pos] = newElement;
    } else {
        this.addElement(newElement);
    }
}
function getElementByNameSpdtXML(name) {
    var rtno = null;
    var element = null;
    for (var n=0; n < this.elements.length; n++) {
        element = this.elements[n];
        if (element) {
            if (element.name == name) {
                rtno = element;
                break;
            }
        }
    }
    return rtno;
}
function getElementsByNameSpdtXML(name) {
    var rtno = new Array();
    var element = null;
    for (var n=0; n < this.elements.length; n++) {
        element = this.elements[n];
        if (element) {
            if (element.name == name) {
                rtno[rtno.length] = element;
            }
        }
    }
    return rtno;
}
function Comparable(type,name,oper,value) {
    this.type = type;
    this.name = name;
    this.oper = oper;
    this.value = value;
}
function getElementByExprSpdtXML(xexpr) {
    var pos = xexpr.indexOf('[');
    var name = xexpr.substring(0,pos);
    var expr = xexpr.substring(pos+1,xexpr.length-1);
    var veri = getExprArray(expr);
    var element = null;
    var elements = null;
    var found = false;
    elements = this.getElementsByName(name);
    for(var n = 0; n < veri.length; n++) {
        comparable = veri[n];
        if (comparable.type == "E") {
            for(var x=0; x < elements.length; x++) {
                element = elements[x];
                childElement = element.getElementByName(comparable.name);
                if (childElement.value == comparable.value) {
                    found=true;
                    break;
                }
            }
        }
        if (found) {
            break;
        }
    }
    if (!found) {
        element = null;
    }
    return element;
}
function getExprArray(expr) {
    var rtno = new Array();
    var inName=true;
    var inValue=false;
    endedExpr = false;
    var ch = "";
    var name = "";
    var value = "";
    var comasCount = 0;
    for(var n=0; n < expr.length; n++) {
        ch = expr.charAt(n);
        if (inName) {
            if (ch == "=") {
                inName=false;
                inValue=true;
            } else {
                name+=ch;
            }
        }
        if (inValue) {
            if (ch == "'") {
                comasCount++;
            }
            if ((comasCount == 2)) {
                inValue=false;
                endedExpr=true;
            } else if (ch != "'") {
                if (comasCount > 0) {
                    value+=ch;
                }
            }
        }
        if (endedExpr) {
            rtno[rtno.length] = new Comparable("E",name,"=",value);
            inName=true;
            inValue=false;
            endedExpr = false;
            name = "";
            value = "";
            comasCount = 0;
        }
    }
    return rtno;
}
function toTokenBase(str,token) {
    var aTokens = str.split(token)
    var rtno = new Array();
    rtno[0] = aTokens[0];
    rtno[1] = "";
    for(var n=1; n < aTokens.length; n++) {
        rtno[1]+=aTokens[n];
        if (n < aTokens.length -1) {
            rtno[1]+=token;
        }
    }
    return rtno;
}
function setValueElementSpdtXML(xpath,value) {
    var element = this.getElement(xpath);
    if (!element) {
        element = this.createPath(xpath);
    }
    if (element) {
        element.value = value;
    }
}
function createPathElementSpdtXML(xpath) {
    var tokenBase = toTokenBase(xpath,"/");
    var element = this.getElement(tokenBase[0]);
    if (!element) {
        element = this.add(tokenBase[0]);
    }
    if (tokenBase[1] != "") {
        element = element.createPath(tokenBase[1]);
    }
    return element;
}
function getValueElementSpdtXML(xpath) {
    var element = this.getElement(xpath);
    if (element) {
        return element.value;
    }
}
function dropElementsElementSpdtXML() {
    this.elements = new Array();
}
function getXMLElementSpdtXML() {
    var str = "";
    var childNode = null;
    for(var x=0; x < this.elements.length; x++) {
        childNode = this.elements[x];
        if (childNode) {
            str+="<"+childNode.name;
            if(childNode.attributes.length > 0) {
                for(var a=0; a < childNode.attributes.length; a++) {
                    atr = childNode.attributes[a];
                    str+=" "+atr.name+'="'+atr.value+'"'
                }
            }
            str+=">";
            if (childNode.value) {
                str+=childNode.value;
            }
            str+=childNode.getXML();
            str+="</"+childNode.name+">";
        }
    }
    return str;
}
function ElementSpdtXML(name) {
    this.type = "element";
    this.name = name;
    this.parent = null;
    this.attributes = new Array();
    this.elements = new Array();
    this.value = null;
    this.uid = uidControlSpdtXML++;
    this.pos = -1;
    //Funcoes
    this.add = addElementSpdtXML;
    this.addElement = addElementElementSpdtXML;
    this.addAttribute = addAttributeElementSpdtXML;
    this.getElement = getElementSpdtXML;
    this.getElementByName = getElementByNameSpdtXML;
    this.getElementByExpr = getElementByExprSpdtXML;
    this.getElementsByName = getElementsByNameSpdtXML;
    this.getValue = getValueElementSpdtXML;
    this.setValue = setValueElementSpdtXML;
    this.dropElements = dropElementsElementSpdtXML;
    this.getXML = getXMLElementSpdtXML;
    this.createPath = createPathElementSpdtXML;
    this.rm = rmElementSpdtXML;
    this.setElement = setElementElementSpdtXML;
}

function attributeSpdtXML(name,value) {
    this.name = name;
    this.value = value;
}
function parseSpdtXML() {
    var ch = "";
    var lstCh = "";
    var element = this.base;
    var inTagName = false;
    var inTagAtrName = false;
    var inTagAtrValue = false;
    var endedTagName = false;
    var endedTagAtr = false;
    var endedTag = false;
    var inTagHead = false;
    var inTagBody = false;
    var tagName="";
    var tagAtrName = "";
    var tagAtrName="";
    var tagAtrValue="";
    var tagBody="";
    tagAtrValueComasCount=0;
    for(var n=0; n < this.xml.length; n++) {
        ch = this.xml.charAt(n);
        if ((ch == "/") && (lstCh == "<")) {
            //if (lstCh == "<") endedTag;
            inTagName = false;
            inTagBody = false;
            element.value = tagBody;
            element = element.parent;
            tagBody="";
        }
        if (inTagName) {
            if ((ch == " ") || (ch == ">")) {
                inTagName=false;
                endedTagName=true;
                if (ch == " ") inTagAtrName=true;
            } else {
                tagName+=ch;
            }
        }
        if (inTagHead) {
            if (ch == ">") {
                inTagHead=false;
                inTagBody=true;
            }
            if ((ch == " ") && (!inTagAtrValue)) {
                inTagAtrName = true;
            }
        }
        if (endedTagName) {
            element = element.add(tagName);
            tagName="";
            endedTagName=false;
        }
        if (inTagAtrName) {
            if (ch == "=") {
                inTagAtrName=false;
                inTagAtrValue=true;
            } else {
                tagAtrName+=ch;
            }
        }

        if (inTagAtrValue) {
            if (ch == '"') {
                tagAtrValueComasCount++;
            }
            if ((tagAtrValueComasCount == 2)) {
                inTagAtrValue=false;
                endedTagAtr=true;
            } else if (ch != '"') {
                if (tagAtrValueComasCount > 0) {
                    tagAtrValue+=ch;
                }
            }
        }
        if (endedTagAtr) {
            element.addAttribute(tagAtrName,tagAtrValue);
            tagAtrName="";
            tagAtrValue="";
            tagAtrValueComasCount=0;
            endedTagAtr=false;
        }
        if (ch == "<") {
            inTagHead = true;
            inTagName = true;
            inTagBody = false;
            inTagAtrName = false;
            inTagAtrValue = false;
        }
        if (inTagBody) {
            if (tagBody.length == 0) {
                if (ch != ">") {
                    tagBody+=ch;
                }
            } else {
                tagBody+=ch;
            }
        }
        lstCh = ch;
    }
}
function setValueSpdtXML(xpath,value) {
    var element = this.base.getElement(xpath);
    if (element) {
        element.value = value;
    }
}
function getValueSpdtXML(xpath) {
    var element = this.base.getElement(xpath);
    if (element) {
        return element.value;
    }
}
function getElementFromBaseSpdtXML(xpath) {
    return this.base.getElement(xpath);
}
function SpdtXML(strXML) {
    this.xml = strXML;
    this.base = new ElementSpdtXML("base");
    //Funcoes
    this.parse = parseSpdtXML;
    this.setValue = setValueSpdtXML;
    this.getValue = getValueSpdtXML;
    this.getElement = getElementFromBaseSpdtXML;
}


