/*
 * 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 RefOutArgWrapper = require("./../../../unisharp/RefOutArgWrapper");
const StringBuilder = require("./../../../unisharp/StringBuilder");

const MiscHelper = require("./../../../util/MiscHelper");
const UnitextItem = require("./../../UnitextItem");
const UnitextMisc = require("./../../UnitextMisc");
const UnitextContainer = require("./../../UnitextContainer");
const UnitextComment = require("./../../UnitextComment");
const UniTextGenNumType = require("./UniTextGenNumType");
const UnitextPagebreak = require("./../../UnitextPagebreak");
const UnitextList = require("./../../UnitextList");
const UnitextListitem = require("./../../UnitextListitem");
const UnitextPlaintextType = require("./../../UnitextPlaintextType");
const UnitextFootnote = require("./../../UnitextFootnote");
const WhitespaceType = require("./../../WhitespaceType");
const UnitextPlaintext = require("./../../UnitextPlaintext");
const UnitextNewline = require("./../../UnitextNewline");

class UnitextGen {
    
    constructor() {
        this.m_Text = new StringBuilder();
        this.m_Res = new UnitextContainer();
        this.m_CurStyle = null;
        this.m_NumStyle = null;
        this.m_CurSection = null;
        this.m_NewRes = false;
        this.textGenRegime = false;
        this.m_Stack = new Array();
        this.lastNotSpaceChar = String.fromCharCode(0);
        this.lastChar = String.fromCharCode(0);
    }
    
    clearAll() {
        this.m_Text.length = 0;
        this.m_Stack.splice(0, this.m_Stack.length);
        this.m_CurStyle = null;
        if (this.m_NewRes) 
            this.m_Res = new UnitextContainer();
        else 
            this.m_Res.children.splice(0, this.m_Res.children.length);
    }
    
    setStyle(st) {
        if (st === null) 
            return;
        if (this.m_CurStyle === null) {
            this.m_CurStyle = st;
            this.m_Res.m_StyledFrag = st;
        }
        else if (this.m_CurStyle !== st) {
            this.flushText();
            this.m_CurStyle = st;
        }
    }
    
    setNumStyle(st) {
        this.m_NumStyle = st;
    }
    
    finish(isContent, pars = null) {
        this.flushText();
        let res = this.m_Res;
        if (this.m_CurStyle !== null) {
            if (this.m_Res.children.length === 0) 
                return null;
        }
        else 
            res = this.m_Res.optimize(isContent, pars);
        this.m_NewRes = res === this.m_Res;
        return res;
    }
    
    get lastText() {
        return this.m_Text.toString();
    }
    
    flushText() {
        if (this.m_Text.length > 0) {
            let t = UnitextPlaintext._new57(this.m_Text.toString());
            t.m_StyledFrag = this.m_CurStyle;
            t.pageSectionId = this.m_CurSection;
            if (this.textGenRegime) {
                t.typ = UnitextPlaintextType.GENERATED;
                if (this.m_NumStyle !== null) 
                    t.m_StyledFrag = this.m_NumStyle;
            }
            this.m_Text.length = 0;
            this.append(t, null, -1, false);
        }
    }
    
    appendNewline(ifNotPrevNewline = false, isSoft = false) {
        if (ifNotPrevNewline) {
            if (this.m_Res.children.length > 0 && this.m_Text.length === 0) {
                if (this.m_Res.children[this.m_Res.children.length - 1] instanceof UnitextNewline) 
                    return;
            }
        }
        this.append(UnitextNewline._new368(this.m_CurSection, (isSoft ? WhitespaceType.SOFT : WhitespaceType.ORIGINAL)), null, -1, false);
        this.lastChar = '\r';
    }
    
    appendPagebreak() {
        this.append(UnitextPagebreak._new369(this.m_CurSection), null, -1, false);
        this.lastChar = '\f';
    }
    
    appendPagesection(s) {
        if (s !== null && s.id === this.m_CurSection) 
            return;
        if (this.m_Res.children.length > 0) {
            if (this.m_Res.children.length === 1 && (this.m_Res.children[0] instanceof UnitextNewline)) {
            }
            else if (!(this.m_Res.children[this.m_Res.children.length - 1] instanceof UnitextPagebreak)) 
                this.appendPagebreak();
            if (s !== null) {
                for (const ch of this.m_Res.children) {
                    if (ch.pageSectionId === null) 
                        ch.pageSectionId = s.id;
                }
            }
        }
        if (s !== null) 
            this.m_CurSection = s.id;
    }
    
    append(blk, numStyl = null, numLevel = -1, doNumStyleAsText = false) {
        this.flushText();
        if (blk !== null && this.m_CurStyle !== null && blk.m_StyledFrag === null) 
            blk.m_StyledFrag = this.m_CurStyle;
        if (blk !== null && blk.pageSectionId === null) 
            blk.pageSectionId = this.m_CurSection;
        if (numStyl !== null && numStyl.txt !== null) {
            let list0 = this.appendListItem(blk, numStyl.txt, null, numStyl.lvl, numStyl);
            return;
        }
        if (numStyl === null || (numLevel < 0)) {
            if (blk !== null) {
                if ((blk instanceof UnitextFootnote) && this.m_Res.children.length > 0) {
                    let txt = Utils.as(this.m_Res.children[this.m_Res.children.length - 1], UnitextPlaintext);
                    if (txt !== null && txt.typ === UnitextPlaintextType.SUP) {
                        if (txt.text === blk.customMark) 
                            this.m_Res.children.splice(this.m_Res.children.length - 1, 1);
                    }
                }
                if (numStyl !== null) 
                    this.appendNewline(true, false);
                this.m_Res.children.push(blk);
                if (numStyl !== null) 
                    this.appendNewline(false, false);
            }
            return;
        }
        let num = numStyl.process(numLevel, false);
        if (num === null) {
            if (blk !== null) 
                this.m_Res.children.push(blk);
            return;
        }
        if (doNumStyleAsText) {
            this.appendNewline(true, false);
            this.m_Res.children.push(UnitextPlaintext._new370(num + " ", UnitextPlaintextType.GENERATED, this.m_CurSection, this.m_NumStyle));
            if (blk !== null) 
                this.m_Res.children.push(blk);
            this.appendNewline(false, false);
            return;
        }
        let numlev = numStyl.getLevel(numLevel);
        let cnt = Utils.as(blk, UnitextContainer);
        if (cnt !== null) {
            for (let i = 0; i < cnt.children.length; i++) {
                if (cnt.children[i] instanceof UnitextMisc) 
                    continue;
                if (cnt.children[i] instanceof UnitextPagebreak) {
                    this.appendPagebreak();
                    cnt.children.splice(i, 1);
                }
                else if (cnt.children[i] instanceof UnitextNewline) {
                    this.appendNewline(false, false);
                    cnt.children.splice(i, 1);
                }
                break;
            }
        }
        let list = this.appendListItem(blk, num, numStyl.id, numLevel, numStyl);
        if (list !== null && numlev.type === UniTextGenNumType.BULLET) 
            list.unorderPrefix = (numlev.format != null ? numlev.format : "");
    }
    
    appendListItem(content, pref, numStyleId, numLevel, numStyl = null) {
        this.flushText();
        let list = null;
        for (let i = this.m_Res.children.length - 1; i >= 0; i--) {
            if ((this.m_Res.children[i] instanceof UnitextNewline) || (this.m_Res.children[i] instanceof UnitextComment) || (this.m_Res.children[i] instanceof UnitextMisc)) {
            }
            else {
                list = Utils.as(this.m_Res.children[i], UnitextList);
                if ((list !== null && numStyleId !== null && (Utils.asString(list.tag)) !== numStyleId) && list.items[list.items.length - 1].sublist !== null) {
                    let sub = list.items[list.items.length - 1].sublist;
                    if ((Utils.asString(sub.tag)) === numStyleId) 
                        list = sub;
                    else if ((numStyl !== null && numLevel === 0 && numStyl.getLevel(0) !== null) && numStyl.getLevel(0).type === UniTextGenNumType.BULLET) 
                        list = sub;
                }
                break;
            }
        }
        if (list !== null && (((Utils.asString(list.tag)) === numStyleId || numStyleId === null))) {
            if (numStyleId === null && numStyl === null) {
                numStyleId = Utils.asString(list.tag);
                numLevel = -1;
            }
            while (true) {
                if (list.level === numLevel) {
                    let it0 = UnitextListitem._new371(content);
                    if (this.m_CurStyle !== null) 
                        it0.m_StyledFrag = this.m_CurStyle;
                    if (pref !== null) 
                        it0.prefix = UnitextPlaintext._new372(pref, UnitextPlaintextType.GENERATED, this.m_NumStyle);
                    list.items.push(it0);
                    return list;
                }
                if ((numLevel < 0) || (list.level < numLevel)) {
                    if (list.items.length === 0) 
                        break;
                    let last = list.items[list.items.length - 1];
                    if (last.sublist !== null) {
                        list = last.sublist;
                        continue;
                    }
                    if (numLevel < 0) {
                        numLevel = list.level;
                        continue;
                    }
                    if (list.level < (numLevel - 1)) 
                        break;
                    last.sublist = UnitextList._new373(numLevel, numStyleId);
                    if (this.m_CurStyle !== null) 
                        last.sublist.m_StyledFrag = this.m_CurStyle;
                    list = last.sublist;
                    continue;
                }
                break;
            }
        }
        if (numLevel < 0) 
            numLevel = 0;
        let list0 = null;
        if ((list !== null && numStyleId !== null && (Utils.asString(list.tag)) !== numStyleId) && numLevel === 0) {
            let li00 = list.items[list.items.length - 1];
            if (li00.content === null || Utils.isNullOrEmpty(li00.content.getPlaintextString(null))) {
            }
            else {
                if (numStyl !== null && li00.sublist === null && pref === null) 
                    pref = numStyl.process(numLevel, true);
                list0 = list;
            }
        }
        list = UnitextList._new374(numLevel, numStyleId, this.m_CurSection);
        if (this.m_CurStyle !== null) 
            list.m_StyledFrag = this.m_CurStyle;
        if (numStyl !== null && numStyl.isBullet) 
            list.unorderPrefix = numStyl.txt;
        if (list0 !== null) {
            if (list0.items[list0.items.length - 1].sublist === null) 
                list0.items[list0.items.length - 1].sublist = list;
            else 
                list = list0.items[list0.items.length - 1].sublist;
        }
        else {
            this.m_Res.children.push(list);
            this.m_Res.children.push(new UnitextNewline());
        }
        let it = UnitextListitem._new371(content);
        if (this.m_CurStyle !== null) 
            it.m_StyledFrag = this.m_CurStyle;
        if (pref !== null && list.unorderPrefix === null) 
            it.prefix = UnitextPlaintext._new372(pref, UnitextPlaintextType.GENERATED, this.m_NumStyle);
        list.items.push(it);
        return list;
    }
    
    appendText(txt, checkTable = false) {
        let inTableLev = 0;
        for (let i = 0; i < txt.length; i++) {
            let ch = txt[i];
            this.lastChar = ch;
            if ((ch.charCodeAt(0)) === 0xD || (ch.charCodeAt(0)) === 0xA) {
                if ((ch.charCodeAt(0)) === 0xD && ((i + 1) < txt.length) && (txt.charCodeAt(i + 1)) === 0xA) 
                    i++;
                this.appendNewline(false, false);
                continue;
            }
            if (ch === '\f' && inTableLev === 0) {
                this.appendPagebreak();
                continue;
            }
            if ((ch.charCodeAt(0)) === 0x1E && checkTable) 
                inTableLev++;
            if ((ch.charCodeAt(0)) === 0x1F && checkTable) 
                inTableLev--;
            if ((ch.charCodeAt(0)) === 0xAD) 
                continue;
            if (((ch.charCodeAt(0)) !== 9 && (ch.charCodeAt(0)) !== 7 && ch !== '\f') && ((ch.charCodeAt(0)) < 0x1E)) 
                ch = ' ';
            this.m_Text.append(ch);
            if (!Utils.isWhitespace(ch)) 
                this.lastNotSpaceChar = ch;
        }
    }
    
    static convertToPt(val, detTyp = null) {
        let vv = UnitextGen.convertToMM(val, detTyp);
        if (vv === 0) 
            return val;
        else 
            return (String(vv) + "pt");
    }
    
    static convertToMM(val, detTyp = null) {
        if (val === null) 
            return 0;
        let f = 0;
        let i = 0;
        let typ = null;
        for (i = 0; i < val.length; i++) {
            if (Utils.isLetter(val[i]) || val[i] === ';') {
                typ = val.substring(i).toLowerCase();
                val = val.substring(0, 0 + i);
                break;
            }
        }
        if (Utils.isNullOrEmpty(typ)) 
            typ = detTyp;
        if (Utils.isNullOrEmpty(typ)) 
            return Math.floor(f);
        let wrapf377 = new RefOutArgWrapper();
        let inoutres378 = MiscHelper.tryParseFloat(val, wrapf377);
        f = wrapf377.value;
        if (inoutres378) {
        }
        else 
            return 0;
        if (typ.startsWith("pt")) {
        }
        else if (typ.startsWith("pc")) 
            f = (f * (72)) / (6);
        else if (typ.startsWith("cm")) 
            f = (f * (72)) / 2.54;
        else if (typ.startsWith("mm")) 
            f = (f * (72)) / 25.4;
        else if (typ.startsWith("px")) 
            f = f * 0.75;
        else if (typ.startsWith("in")) 
            f = f * 72;
        else 
            return 0;
        return Math.floor(f);
    }
}


module.exports = UnitextGen