/*
 * SDK Pullenti Unitext, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software. 
 * This class is generated using the converter UniSharping (www.unisharping.ru) from Pullenti C# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

const Utils = require("./../../../unisharp/Utils");
const Hashtable = require("./../../../unisharp/Hashtable");
const RefOutArgWrapper = require("./../../../unisharp/RefOutArgWrapper");
const StringBuilder = require("./../../../unisharp/StringBuilder");

const MiscHelper = require("./../../../util/MiscHelper");
const UnitextItem = require("./../../UnitextItem");
const UnitextGenTable = require("./../uni/UnitextGenTable");
const UniTextGenCell = require("./../uni/UniTextGenCell");
const IUnitextGenNumStyle = require("./../uni/IUnitextGenNumStyle");
const SymbolHelper = require("./SymbolHelper");
const WingdingsHelper = require("./WingdingsHelper");
const UnitextContainerType = require("./../../UnitextContainerType");
const UnitextPlaintextType = require("./../../UnitextPlaintextType");
const UnitextPlaintext = require("./../../UnitextPlaintext");
const UnitextList = require("./../../UnitextList");
const FileFormat = require("./../../FileFormat");
const UnitextImage = require("./../../UnitextImage");
const UnitextContainer = require("./../../UnitextContainer");
const UnitextDocument = require("./../../UnitextDocument");
const UnitextComment = require("./../../UnitextComment");
const UniTextGenNumType = require("./../uni/UniTextGenNumType");
const UnitextGenNumStyle = require("./../uni/UnitextGenNumStyle");
const UnitextHyperlink = require("./../../UnitextHyperlink");
const UniTextGenNumLevel = require("./../uni/UniTextGenNumLevel");
const UnitextFootnote = require("./../../UnitextFootnote");
const UnitextGen = require("./../uni/UnitextGen");
const UnitextPagesectionItem = require("./../../UnitextPagesectionItem");
const UnitextPagesection = require("./../../UnitextPagesection");

class OdtHelper {
    
    constructor() {
        this.m_Styles = new Hashtable();
        this.m_Nums = new Hashtable();
        this.m_OutlineNum = null;
    }
    
    createUni(xml, styles) {
        if (xml.local_name !== "document-content") 
            return null;
        let doc = UnitextDocument._new47(FileFormat.ODT);
        let sect = new UnitextPagesection();
        if (styles !== null) {
            for (const x of styles.child_nodes) {
                if (x.local_name === "master-styles") {
                    for (const xx of x.child_nodes) {
                        if (xx.local_name === "master-page") {
                            for (const xxx of xx.child_nodes) {
                                if (xxx.local_name === "header") {
                                    let gg = new UnitextGen();
                                    this._readGen0(xxx, gg, true, null, 0);
                                    sect.items.push(UnitextPagesectionItem._new48(gg.finish(true, null)));
                                }
                                else if (xxx.local_name === "footer") {
                                    let gg = new UnitextGen();
                                    this._readGen0(xxx, gg, true, null, 0);
                                    sect.items.push(UnitextPagesectionItem._new49(true, gg.finish(true, null)));
                                }
                            }
                            break;
                        }
                    }
                }
                else if (x.local_name === "styles") {
                    for (const xx of x.child_nodes) {
                        if (xx.local_name === "style") 
                            this._readStyle(xx);
                        else if (xx.local_name === "list-style") 
                            this._readListStyle(xx);
                    }
                }
            }
        }
        if (sect.items.length > 0) 
            doc.sections.push(sect);
        for (const x of xml.child_nodes) {
            if (x.local_name === "automatic-styles") {
                for (const xx of x.child_nodes) {
                    if (xx.local_name === "style") 
                        this._readStyle(xx);
                    else if (xx.local_name === "list-style") 
                        this._readListStyle(xx);
                }
            }
            else if (x.local_name === "body") {
                let gen = new UnitextGen();
                this._readGen0(x, gen, false, null, 0);
                doc.content = gen.finish(true, null);
            }
        }
        doc.optimize(false, null);
        if (doc.content === null) 
            return null;
        return doc;
    }
    
    _readStyle(xx) {
        let sty = new OdtHelper.OdtStyle();
        if (xx.attributes !== null) {
            for (const a of xx.attributes) {
                if (a.local_name === "name") 
                    sty.name = a.value;
                else if (a.local_name === "family") 
                    sty.fontFamily = a.value;
                else if (a.local_name === "parent-style-name") 
                    sty.parentName = a.value;
                else if (a.local_name === "list-style-name") 
                    sty.numStyleId = a.value;
            }
        }
        if (sty.name === null || this.m_Styles.containsKey(sty.name)) 
            return;
        this.m_Styles.put(sty.name, sty);
        for (const p of xx.child_nodes) {
            if (p.local_name === "text-properties") {
                if (p.attributes !== null) {
                    for (const a of p.attributes) {
                        if (a.local_name === "text-position") {
                            if (a.value.startsWith("super")) 
                                sty.isSuper = true;
                            else if (a.value.startsWith("sub")) 
                                sty.isSub = true;
                        }
                        else if (a.local_name === "font-name") {
                            if (a.value === "Wingdings") 
                                sty.isWingdings = true;
                            else if (a.value === "Symbol") 
                                sty.isSymbol = true;
                        }
                    }
                }
            }
            else if (p.local_name === "table-column-properties") {
                if (p.attributes !== null) {
                    for (const a of p.attributes) {
                        if (a.local_name === "column-width") {
                            let dd = UnitextGen.convertToMM(a.value, null);
                            if (dd > 0) {
                                sty.tableColumnWidth = dd;
                                continue;
                            }
                            let vv = a.value;
                            if (vv.endsWith("in")) 
                                vv = vv.substring(0, 0 + vv.length - 2);
                            let d = 0;
                            let wrapd108 = new RefOutArgWrapper();
                            let inoutres109 = MiscHelper.tryParseDouble(vv, wrapd108);
                            d = wrapd108.value;
                            if (inoutres109) 
                                sty.tableColumnWidth = d;
                        }
                    }
                }
            }
            else if (p.local_name === "table-properties") {
                if (p.attributes !== null) {
                    for (const a of p.attributes) {
                        if (a.local_name === "width") 
                            sty.tableWidth = a.value;
                    }
                }
            }
        }
    }
    
    _readListStyle(xx) {
        let nam = null;
        if (xx.attributes !== null) {
            for (const a of xx.attributes) {
                if (a.local_name === "name") 
                    nam = a.value;
            }
        }
        if (nam === null) 
            return;
        let num = UnitextGenNumStyle._new110(nam);
        this._readOdtNumStyle(num, xx);
        if (!this.m_Nums.containsKey(nam)) 
            this.m_Nums.put(nam, num);
    }
    
    _readOdtNumStyle(num, xml) {
        for (const x of xml.child_nodes) {
            if (x.local_name === "list-level-style-number") {
                let lev = new UniTextGenNumLevel();
                num.levels.push(lev);
                let pref = null;
                let suf = null;
                let frm = "1";
                let cou = 1;
                if (x.attributes !== null) {
                    for (const a of x.attributes) {
                        if (a.local_name === "num-suffix") 
                            suf = a.value;
                        else if (a.local_name === "num-prefix") 
                            pref = a.value;
                        else if (a.local_name === "num-format") 
                            frm = a.value;
                        else if (a.local_name === "display-levels") {
                            let wrapcou111 = new RefOutArgWrapper();
                            Utils.tryParseInt(a.value, wrapcou111);
                            cou = wrapcou111.value;
                        }
                        else if (a.local_name === "start-value") {
                            let nn = 0;
                            let wrapnn112 = new RefOutArgWrapper();
                            let inoutres113 = Utils.tryParseInt(a.value, wrapnn112);
                            nn = wrapnn112.value;
                            if (inoutres113) 
                                lev.start = nn;
                        }
                    }
                }
                if (frm === "1") 
                    lev.type = UniTextGenNumType.DECIMAL;
                else if (frm === "a") 
                    lev.type = UniTextGenNumType.LOWERLETTER;
                else if (frm === "A") 
                    lev.type = UniTextGenNumType.UPPERLETTER;
                else if (frm === "i") 
                    lev.type = UniTextGenNumType.LOWERROMAN;
                else if (frm === "I") 
                    lev.type = UniTextGenNumType.UPPERROMAN;
                else if (frm.startsWith("А")) 
                    lev.type = UniTextGenNumType.UPPERCYRLETTER;
                else if (frm.startsWith("а")) 
                    lev.type = UniTextGenNumType.LOWERCYRLETTER;
                let tmp = new StringBuilder();
                if (pref !== null) 
                    tmp.append(pref);
                for (let i = (num.levels.length + 1) - cou; i <= num.levels.length; i++) {
                    let prevFrm = null;
                    if (i < num.levels.length) 
                        prevFrm = num.levels[i - 1].format;
                    if (!Utils.isNullOrEmpty(prevFrm) && prevFrm[0] !== '%') 
                        tmp.append(prevFrm[0]);
                    tmp.append("%").append(i);
                    if (!Utils.isNullOrEmpty(prevFrm) && !Utils.isDigit(prevFrm[prevFrm.length - 1])) 
                        tmp.append(prevFrm[prevFrm.length - 1]);
                }
                if (suf !== null) 
                    tmp.append(suf);
                lev.format = tmp.toString();
            }
            else if (x.local_name === "list-level-style-bullet") {
                let lev = UniTextGenNumLevel._new114(UniTextGenNumType.BULLET);
                if (x.attributes !== null) {
                    for (const a of x.attributes) {
                        if (a.local_name === "bullet-char") 
                            lev.format = a.value;
                    }
                }
                num.levels.push(lev);
            }
        }
    }
    
    _readGen0(xml, gen, pure = false, numStyle = null, numLevel = 0) {
        if (xml === null) 
            return;
        let li = new Array();
        li.push(xml);
        this._readGen(li, gen, pure, numStyle, numLevel);
    }
    
    _readGen(xmlStack, gen, pure = false, numStyle = null, numLevel = 0) {
        let xml = xmlStack[xmlStack.length - 1];
        if (!pure && xml.local_name !== "#text") {
            if (xml.local_name === "s") {
                gen.appendText(" ", false);
                if (xml.attributes !== null) {
                    for (const a of xml.attributes) {
                        if (a.local_name === "c") {
                            let cou = 0;
                            let wrapcou115 = new RefOutArgWrapper();
                            let inoutres116 = Utils.tryParseInt(Utils.notNull(a.value, ""), wrapcou115);
                            cou = wrapcou115.value;
                            if (inoutres116) {
                                for (; cou > 1; cou--) {
                                    gen.appendText(" ", false);
                                }
                            }
                        }
                    }
                }
                return;
            }
            if (xml.local_name === "soft-page-break") {
                gen.appendPagebreak();
                return;
            }
            if (xml.local_name === "line-break") {
                gen.appendNewline(false, false);
                return;
            }
            if (xml.local_name === "table") {
                let gt = new UnitextGenTable();
                let colwi = new Array();
                for (const r of xml.child_nodes) {
                    if (r.local_name === "table-row") {
                        let row = new Array();
                        gt.cells.push(row);
                        for (const c of r.child_nodes) {
                            if (c.local_name === "table-cell") {
                                let cel = new UniTextGenCell();
                                row.push(cel);
                                if (c.attributes !== null) {
                                    for (const a of c.attributes) {
                                        if (a.local_name === "number-rows-spanned") {
                                            let nn = 0;
                                            let wrapnn117 = new RefOutArgWrapper();
                                            let inoutres118 = Utils.tryParseInt(a.value, wrapnn117);
                                            nn = wrapnn117.value;
                                            if (inoutres118) 
                                                cel.rowSpan = nn;
                                        }
                                        else if (a.local_name === "number-columns-spanned") {
                                            let nn = 0;
                                            let wrapnn119 = new RefOutArgWrapper();
                                            let inoutres120 = Utils.tryParseInt(a.value, wrapnn119);
                                            nn = wrapnn119.value;
                                            if (inoutres120) 
                                                cel.colSpan = nn;
                                        }
                                    }
                                }
                                let gg = new UnitextGen();
                                xmlStack.push(c);
                                this._readGen(xmlStack, gg, true, numStyle, numLevel);
                                xmlStack.splice(xmlStack.length - 1, 1);
                                cel.content = gg.finish(true, null);
                            }
                        }
                    }
                    else if (r.local_name === "table-columns") {
                        for (const x of r.child_nodes) {
                            if (x.local_name === "table-column") {
                                if (xml.attributes !== null) {
                                    for (const a of x.attributes) {
                                        if (a.local_name === "style-name") {
                                            let sty1 = null;
                                            let wrapsty1121 = new RefOutArgWrapper();
                                            let inoutres122 = this.m_Styles.tryGetValue(a.value, wrapsty1121);
                                            sty1 = wrapsty1121.value;
                                            if (inoutres122) {
                                                if (sty1.tableColumnWidth > 0) 
                                                    colwi.push(sty1.tableColumnWidth);
                                            }
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else if (r.local_name === "table-column") {
                        if (r.attributes !== null) {
                            for (const a of r.attributes) {
                                if (a.local_name === "style-name") {
                                    let sty1 = null;
                                    let wrapsty1123 = new RefOutArgWrapper();
                                    let inoutres124 = this.m_Styles.tryGetValue(a.value, wrapsty1123);
                                    sty1 = wrapsty1123.value;
                                    if (inoutres124) {
                                        if (sty1.tableColumnWidth > 0) 
                                            colwi.push(sty1.tableColumnWidth);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
                let sum = 0;
                for (const w of colwi) {
                    sum += w;
                }
                if (sum > 0) {
                    for (const w of colwi) {
                        gt.m_ColWidth.push(((String(Math.floor(((w * (100)) / sum)))) + "%"));
                    }
                }
                let tab = gt.convert();
                if (tab !== null) {
                    gen.append(tab, null, -1, false);
                    return;
                }
            }
            if (xml.local_name === "a") {
                let uri = null;
                if (xml.attributes !== null) {
                    for (const a of xml.attributes) {
                        if (a.local_name === "href") {
                            uri = a.value;
                            break;
                        }
                    }
                }
                if (uri !== null) {
                    let gg = new UnitextGen();
                    xmlStack.push(xml);
                    this._readGen(xmlStack, gg, true, null, 0);
                    xmlStack.splice(xmlStack.length - 1, 1);
                    let it = gg.finish(true, null);
                    if (it !== null) {
                        let hr = UnitextHyperlink._new59(uri);
                        hr.content = it;
                        gen.append(hr, null, -1, false);
                        return;
                    }
                }
            }
            if (xml.local_name === "note") {
                let fn = new UnitextFootnote();
                if (xml.attributes !== null) {
                    for (const a of xml.attributes) {
                        if (a.local_name === "note-class" && a.value === "endnote") 
                            fn.isEndnote = true;
                    }
                }
                for (const x of xml.child_nodes) {
                    if (x.local_name === "note-body") {
                        let gg = new UnitextGen();
                        xmlStack.push(x);
                        this._readGen(xmlStack, gg, true, null, 0);
                        xmlStack.splice(xmlStack.length - 1, 1);
                        fn.content = gg.finish(true, null);
                        break;
                    }
                }
                if (fn.content !== null) 
                    gen.append(fn, null, -1, false);
                return;
            }
            if (xml.local_name === "bookmark-ref") {
                let gg = new UnitextGen();
                xmlStack.push(xml);
                this._readGen(xmlStack, gg, true, null, 0);
                xmlStack.splice(xmlStack.length - 1, 1);
                let pl = Utils.as(gg.finish(true, null), UnitextPlaintext);
                if (pl !== null) {
                    if (!gen.lastText.endsWith(pl.text)) 
                        gen.appendText(pl.text, false);
                    return;
                }
            }
            if (xml.local_name === "annotation") {
                let cmt = new UnitextComment();
                let gg = new UnitextGen();
                for (const x of xml.child_nodes) {
                    if (x.local_name === "creator") 
                        cmt.author = x.inner_text;
                    else if (x.local_name === "date") {
                    }
                    else {
                        xmlStack.push(x);
                        this._readGen(xmlStack, gg, false, null, 0);
                        xmlStack.splice(xmlStack.length - 1, 1);
                    }
                }
                let it = gg.finish(true, null);
                if (it !== null) {
                    let tmp = new StringBuilder();
                    it.getPlaintext(tmp, null);
                    if (tmp.length > 0) {
                        cmt.text = tmp.toString();
                        gen.append(cmt, null, -1, false);
                    }
                }
                return;
            }
            let outLineLevel = 0;
            let numSty = null;
            if (xml.local_name === "p" || xml.local_name === "h") {
                if (xml.attributes !== null) {
                    for (const a of xml.attributes) {
                        if (a.local_name === "outline-level") {
                            let wrapoutLineLevel126 = new RefOutArgWrapper();
                            Utils.tryParseInt(Utils.notNull(a.value, ""), wrapoutLineLevel126);
                            outLineLevel = wrapoutLineLevel126.value;
                        }
                        else if (a.local_name === "style-name") {
                            let sty1 = null;
                            let num0 = null;
                            if (a.value === "P5") {
                            }
                            let wrapsty1130 = new RefOutArgWrapper();
                            let inoutres131 = this.m_Styles.tryGetValue(a.value, wrapsty1130);
                            sty1 = wrapsty1130.value;
                            if (!inoutres131) 
                                continue;
                            for (let kk = 0; kk < 10; kk++) {
                                if (sty1.numStyleId !== null) {
                                    let wrapnum0127 = new RefOutArgWrapper();
                                    this.m_Nums.tryGetValue(sty1.numStyleId, wrapnum0127);
                                    num0 = wrapnum0127.value;
                                    break;
                                }
                                if (sty1.parentName === null) 
                                    break;
                                let wrapsty1128 = new RefOutArgWrapper();
                                let inoutres129 = this.m_Styles.tryGetValue(sty1.parentName, wrapsty1128);
                                sty1 = wrapsty1128.value;
                                if (!inoutres129) 
                                    break;
                            }
                            if (num0 === null) 
                                continue;
                            numSty = num0;
                        }
                    }
                }
            }
            if (outLineLevel > 0 || numSty !== null) {
                if (this.m_OutlineNum === null && numSty === null) {
                    this.m_OutlineNum = new UnitextGenNumStyle();
                    this.m_OutlineNum.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1."));
                    this.m_OutlineNum.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1.%2."));
                    this.m_OutlineNum.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1.%2.%3."));
                    this.m_OutlineNum.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1.%2.%3.%4."));
                    this.m_OutlineNum.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1.%2.%3.%4.%5."));
                    this.m_OutlineNum.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1.%2.%3.%4.%5.%6."));
                }
                let li = UnitextList._new63(outLineLevel - 1);
                let gg = new UnitextGen();
                for (const x of xml.child_nodes) {
                    xmlStack.push(x);
                    this._readGen(xmlStack, gg, false, (numSty === null ? this.m_OutlineNum : numStyle), numLevel);
                    xmlStack.splice(xmlStack.length - 1, 1);
                }
                gen.appendNewline(true, false);
                gen.append(gg.finish(true, null), (numSty === null ? this.m_OutlineNum : numSty), outLineLevel - 1, false);
                gen.appendNewline(false, false);
                gen.append(li, null, -1, false);
                return;
            }
            if (xml.local_name === "list") {
                let li = UnitextList._new63(numLevel);
                let num0 = null;
                let contNum = false;
                let styleName = null;
                if (xml.attributes !== null) {
                    for (const a of xml.attributes) {
                        if (a.local_name === "style-name") {
                            let sty1 = null;
                            let wrapsty1145 = new RefOutArgWrapper();
                            let inoutres146 = this.m_Styles.tryGetValue(a.value, wrapsty1145);
                            sty1 = wrapsty1145.value;
                            if (inoutres146) {
                                if (sty1.numStyleId !== null) {
                                    let wrapnum0140 = new RefOutArgWrapper();
                                    this.m_Nums.tryGetValue((styleName = sty1.numStyleId), wrapnum0140);
                                    num0 = wrapnum0140.value;
                                }
                                else if (sty1.parentName !== null) {
                                    let sty2 = null;
                                    let wrapsty2142 = new RefOutArgWrapper();
                                    let inoutres143 = this.m_Styles.tryGetValue(sty1.parentName, wrapsty2142);
                                    sty2 = wrapsty2142.value;
                                    if (inoutres143) {
                                        if (sty2.numStyleId !== null) {
                                            let wrapnum0141 = new RefOutArgWrapper();
                                            this.m_Nums.tryGetValue((styleName = sty2.numStyleId), wrapnum0141);
                                            num0 = wrapnum0141.value;
                                        }
                                    }
                                }
                            }
                            else {
                                let wrapnum0144 = new RefOutArgWrapper();
                                this.m_Nums.tryGetValue((styleName = a.value), wrapnum0144);
                                num0 = wrapnum0144.value;
                                if (styleName === "L9") {
                                }
                            }
                        }
                        else if (a.local_name === "continue-numbering") 
                            contNum = true;
                    }
                }
                if (numStyle === null || num0 !== null) {
                    numStyle = num0;
                    numLevel = 0;
                }
                if (numStyle === null) {
                    numStyle = new UnitextGenNumStyle();
                    numStyle.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1."));
                    numStyle.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1.%2."));
                    numStyle.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1.%2.%3."));
                    numStyle.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1.%2.%3.%4."));
                    numStyle.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1.%2.%3.%4.%5."));
                    numStyle.levels.push(UniTextGenNumLevel._new132(UniTextGenNumType.DECIMAL, "%1.%2.%3.%4.%5.%6."));
                    numLevel = 0;
                    if (styleName !== null && !this.m_Nums.containsKey(styleName)) 
                        this.m_Nums.put(styleName, numStyle);
                }
                for (const x of xml.child_nodes) {
                    if (x.local_name === "list-item") {
                        let n0 = 0;
                        if (x.attributes !== null) {
                            for (const a of x.attributes) {
                                if (a.local_name === "start-value") {
                                    let wrapn0153 = new RefOutArgWrapper();
                                    Utils.tryParseInt(a.value, wrapn0153);
                                    n0 = wrapn0153.value;
                                }
                            }
                        }
                        let startSubList = false;
                        for (const xx of x.child_nodes) {
                            if (xx.local_name === "list") 
                                startSubList = true;
                            break;
                        }
                        if (n0 > 0 && (numLevel < numStyle.levels.length)) 
                            numStyle.levels[numLevel].current = n0;
                        let gg = new UnitextGen();
                        xmlStack.push(x);
                        this._readGen(xmlStack, gg, true, numStyle, numLevel + 1);
                        xmlStack.splice(xmlStack.length - 1, 1);
                        gen.appendNewline(true, false);
                        if (startSubList) 
                            gen.append(gg.finish(true, null), null, 0, false);
                        else 
                            gen.append(gg.finish(true, null), numStyle, numLevel, false);
                    }
                    else if (x.local_name === "list-header") {
                        let gg = new UnitextGen();
                        xmlStack.push(x);
                        this._readGen(xmlStack, gg, true, numStyle, numLevel + 1);
                        xmlStack.splice(xmlStack.length - 1, 1);
                        gen.appendNewline(true, false);
                        gen.append(gg.finish(true, null), null, 0, false);
                    }
                }
                gen.append(li, null, -1, false);
                return;
            }
            if (xml.local_name === "custom-shape") {
                let gg = new UnitextGen();
                xmlStack.push(xml);
                this._readGen(xmlStack, gg, true, null, 0);
                xmlStack.splice(xmlStack.length - 1, 1);
                let it = gg.finish(true, null);
                if (it === null) 
                    return;
                if (it instanceof UnitextContainer) 
                    it.typ = UnitextContainerType.SHAPE;
                else {
                    let cnt = UnitextContainer._new94(UnitextContainerType.SHAPE);
                    cnt.children.push(it);
                    it = cnt.optimize(false, null);
                }
                if (it !== null) 
                    gen.append(it, null, -1, false);
                return;
            }
            if (xml.local_name === "image") {
                let img = new UnitextImage();
                if (xml.attributes !== null) {
                    for (const a of xml.attributes) {
                        if (a.local_name === "href") {
                            img.id = a.value;
                            break;
                        }
                    }
                }
                if (img.id !== null) {
                    gen.append(img, null, -1, false);
                    xmlStack.push(xml);
                    for (let jj = xmlStack.length - 1; jj >= 0; jj--) {
                        let pp = xmlStack[jj];
                        if (pp.attributes === null) 
                            continue;
                        for (const a of pp.attributes) {
                            if (a.local_name === "width" && img.width === null) 
                                img.width = UnitextGen.convertToPt(a.value, null);
                            else if (a.local_name === "height" && img.height === null && a.value !== null) 
                                img.height = UnitextGen.convertToPt(a.value, null);
                        }
                        if (img.width !== null || img.height !== null) 
                            break;
                    }
                    xmlStack.splice(xmlStack.length - 1, 1);
                }
                return;
            }
            let sty = null;
            if (xml.attributes !== null) {
                for (const a of xml.attributes) {
                    if (a.local_name === "style-name") {
                        let wrapsty156 = new RefOutArgWrapper();
                        this.m_Styles.tryGetValue(a.value, wrapsty156);
                        sty = wrapsty156.value;
                        if (a.value === "T53") {
                        }
                        if (sty !== null && ((sty.isSuper || sty.isSub))) {
                            let gg = new UnitextGen();
                            xmlStack.push(xml);
                            this._readGen(xmlStack, gg, true, null, 0);
                            xmlStack.splice(xmlStack.length - 1, 1);
                            let it = gg.finish(true, null);
                            if (it === null) 
                                continue;
                            let tmp = new StringBuilder();
                            it.getPlaintext(tmp, null);
                            let tt = tmp.toString().trim();
                            if (tt.length > 0 && (tt.length < 100)) {
                                gen.append(UnitextPlaintext._new58(tt, (sty.isSuper ? UnitextPlaintextType.SUB : UnitextPlaintextType.SUP)), null, -1, false);
                                return;
                            }
                        }
                        if (sty !== null && ((sty.isWingdings || sty.isSymbol))) {
                            let gg = new UnitextGen();
                            xmlStack.push(xml);
                            this._readGen(xmlStack, gg, true, null, 0);
                            xmlStack.splice(xmlStack.length - 1, 1);
                            let it = gg.finish(true, null);
                            if (it === null) 
                                continue;
                            let tmp = new StringBuilder();
                            it.getPlaintext(tmp, null);
                            let tt = (sty.isSymbol ? SymbolHelper.getUnicodeString(tmp.toString().trim()) : WingdingsHelper.getUnicodeString(tmp.toString().trim()));
                            if (tt.length > 0) 
                                gen.appendText(tt, false);
                            return;
                        }
                    }
                }
            }
        }
        if (xml.local_name === "p") 
            gen.appendNewline(true, false);
        else if (xml.local_name === "h") 
            gen.appendNewline(false, false);
        if (xml.child_nodes.length === 0 && xml.inner_text !== null) {
            let txt = xml.inner_text;
            if (txt.indexOf(String.fromCharCode(0xAD)) >= 0) 
                txt = Utils.replaceString(txt, ((String.fromCharCode(0xAD))), "");
            if (txt.length === 1 && (txt.charCodeAt(0)) >= 0xF000) 
                gen.appendText(((String.fromCharCode(((txt.charCodeAt(0)) - 0xF000)))), false);
            else 
                gen.appendText(txt, false);
        }
        else 
            for (const x of xml.child_nodes) {
                xmlStack.push(x);
                this._readGen(xmlStack, gen, false, numStyle, numLevel);
                xmlStack.splice(xmlStack.length - 1, 1);
            }
        if (xml.local_name === "p" || xml.local_name === "h") {
            gen.appendNewline(false, false);
            if (xml.local_name === "h") 
                gen.appendNewline(false, false);
        }
    }
}


OdtHelper.OdtStyle = class  {
    
    constructor() {
        this.name = null;
        this.parentName = null;
        this.fontFamily = null;
        this.isSuper = false;
        this.isSub = false;
        this.isWingdings = false;
        this.isSymbol = false;
        this.numStyleId = null;
        this.tableWidth = null;
        this.tableColumnWidth = 0;
    }
}


module.exports = OdtHelper