/*
 * 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 CorrLine = require("./CorrLine");
const UnitextItem = require("./../../UnitextItem");
const UnitextComment = require("./../../UnitextComment");
const UnitextFootnote = require("./../../UnitextFootnote");
const UnitextList = require("./../../UnitextList");
const UnitextTable = require("./../../UnitextTable");
const UnitextPlaintextType = require("./../../UnitextPlaintextType");
const UnitextPlaintext = require("./../../UnitextPlaintext");
const CorrFootnoteTyps = require("./CorrFootnoteTyps");
const CorrFootnoteTag = require("./CorrFootnoteTag");
const UnitextContainer = require("./../../UnitextContainer");
const UnitextHyperlink = require("./../../UnitextHyperlink");
const UnitextNewline = require("./../../UnitextNewline");
const UnitextPagebreak = require("./../../UnitextPagebreak");

class CorrFootnoteContainer {
    
    constructor() {
        this.typ = CorrFootnoteTyps.DIGIT;
        this.startNumber = 1;
        this.beginInd = 0;
        this.endInd = 0;
        this.items = new Array();
    }
    
    toString() {
        let res = new StringBuilder();
        for (let i = 0; i < this.items.length; i++) {
            res.append("<").append((this.typ === CorrFootnoteTyps.DIGIT || this.typ === CorrFootnoteTyps.SUPDIGIT ? (this.startNumber + i).toString() : "*")).append(">").append(this.items[i]).append(" \r\n");
        }
        return res.toString();
    }
    
    static tryParse1(it) {
        if (it instanceof UnitextPlaintext) {
            let pl = Utils.as(it, UnitextPlaintext);
            let i = 0;
            let wrapi309 = new RefOutArgWrapper(i);
            let tag = CorrFootnoteTag.tryParse(pl.text, wrapi309, true, false);
            i = wrapi309.value;
            if (tag === null || tag.number !== 1) 
                return null;
            let res = CorrFootnoteContainer._new307(tag.typ);
            let txt = pl.text.substring(i + 1).trim();
            for (i = 0; i < txt.length; i++) {
                let j = i;
                let wrapj308 = new RefOutArgWrapper(j);
                let tag1 = CorrFootnoteTag.tryParse(txt, wrapj308, true, false);
                j = wrapj308.value;
                if (tag1 === null) 
                    continue;
                if (tag1.typ !== tag.typ) 
                    continue;
                if (tag1.number !== (res.items.length + 2)) 
                    continue;
                if (i > 0) 
                    res.items.push(txt.substring(0, 0 + i).trim());
                txt = txt.substring(j + 1).trim();
                i = -1;
            }
            if (!Utils.isNullOrEmpty(txt)) 
                res.items.push(txt);
            return res;
        }
        if (it instanceof UnitextContainer) {
            let cnt = Utils.as(it, UnitextContainer);
            let res = CorrFootnoteContainer.tryParse(cnt.children, 0, -1);
            if (res === null) 
                return null;
            if (res.endInd !== (cnt.children.length - 1)) 
                return null;
            return res;
        }
        return null;
    }
    
    static tryParse(_items, ind, numStart) {
        if ((ind < 1) || (ind + 1) > _items.length) 
            return null;
        if (!(_items[ind - 1] instanceof UnitextNewline) && !(_items[ind - 1] instanceof UnitextPagebreak)) 
            return null;
        let ind0 = ind;
        let it = Utils.as(_items[ind], UnitextPlaintext);
        if (it === null || Utils.isNullOrEmpty(it.text)) 
            return null;
        if (Utils.isNullOrEmpty(it.text.trim()) && ((ind + 1) < _items.length) && (_items[ind + 1] instanceof UnitextPlaintext)) {
            ind++;
            it = Utils.as(_items[ind], UnitextPlaintext);
        }
        let i = 0;
        let wrapi323 = new RefOutArgWrapper(i);
        let tag = CorrFootnoteTag.tryParse(it.text, wrapi323, true, false);
        i = wrapi323.value;
        if (tag === null) {
            let nn = 0;
            let wrapnn311 = new RefOutArgWrapper();
            let inoutres312 = Utils.tryParseInt(it.text.trim(), wrapnn311);
            nn = wrapnn311.value;
            if (it.typ === UnitextPlaintextType.SUP && inoutres312) {
                tag = CorrFootnoteTag._new310(nn, CorrFootnoteTyps.SUPDIGIT);
                if (ind !== ind0) {
                    _items.splice(ind0, 1);
                    ind = ind0;
                }
            }
            else 
                return null;
        }
        else if (tag.typ === CorrFootnoteTyps.VERYDOUBT) {
            if (tag.number === 24) {
            }
            let ok = false;
            let hasLines = false;
            for (let j = ind - 1; j >= 0 && (j > (ind - 10)); j--) {
                let itt = _items[j];
                if (itt.isWhitespaces) 
                    continue;
                let ttt = itt.getPlaintextString(null);
                if (Utils.isNullOrEmpty(ttt)) 
                    continue;
                if (ttt.startsWith("-----")) {
                    hasLines = true;
                    continue;
                }
                if (!hasLines) 
                    break;
                for (let ii = 0; ii < ttt.length; ii++) {
                    let wrapii313 = new RefOutArgWrapper(ii);
                    let tag0 = CorrFootnoteTag.tryParse(ttt, wrapii313, false, false);
                    ii = wrapii313.value;
                    if (tag0 !== null) {
                        if (tag0.number === tag.number && tag0.typ === CorrFootnoteTyps.DIGIT) {
                            ok = true;
                            break;
                        }
                    }
                }
            }
            if (!ok) 
                return null;
            tag.typ = CorrFootnoteTyps.DIGIT;
        }
        let res = CorrFootnoteContainer._new307(tag.typ);
        res.beginInd = ind0;
        res.endInd = ind;
        if (tag.typ === CorrFootnoteTyps.DIGIT || tag.typ === CorrFootnoteTyps.SUPDIGIT) 
            res.startNumber = tag.number;
        else if (tag.typ === CorrFootnoteTyps.STARS && tag.number > 1) 
            res.startNumber = tag.number;
        for (--ind; ind < _items.length; ind++) {
            if ((_items[ind] instanceof UnitextNewline) || (_items[ind] instanceof UnitextPagebreak)) 
                continue;
            if (!(_items[ind - 1] instanceof UnitextNewline) && !(_items[ind - 1] instanceof UnitextPagebreak)) 
                break;
            it = Utils.as(_items[ind], UnitextPlaintext);
            if (it === null) 
                break;
            i = 0;
            let wrapi322 = new RefOutArgWrapper(i);
            let tag1 = CorrFootnoteTag.tryParse(it.text, wrapi322, true, false);
            i = wrapi322.value;
            if (tag1 === null) {
                let nn = 0;
                let wrapnn316 = new RefOutArgWrapper();
                let inoutres317 = Utils.tryParseInt(it.text.trim(), wrapnn316);
                nn = wrapnn316.value;
                if (it.typ === UnitextPlaintextType.SUP && inoutres317) 
                    tag1 = CorrFootnoteTag._new310(nn, CorrFootnoteTyps.SUPDIGIT);
            }
            if (tag1 === null) 
                break;
            if (tag1.typ === CorrFootnoteTyps.VERYDOUBT) {
                if (ind === res.endInd) 
                    tag1.typ = CorrFootnoteTyps.DIGIT;
                else 
                    break;
            }
            if (tag.typ !== tag1.typ) 
                break;
            if ((tag1.number - res.startNumber) !== res.items.length) 
                break;
            res.endInd = ind;
            let txt = (tag.typ === CorrFootnoteTyps.SUPDIGIT ? "" : it.text.substring(i + 1).trim());
            for (let jj = ind + 1; jj < _items.length; jj++) {
                if (_items[jj] instanceof UnitextNewline) {
                    if (_items[jj].count > 1) 
                        break;
                    continue;
                }
                if (_items[jj] instanceof UnitextComment) 
                    continue;
                let txt1 = null;
                let pl = Utils.as(_items[jj], UnitextPlaintext);
                if (pl !== null) 
                    txt1 = pl.text;
                else if (_items[jj] instanceof UnitextHyperlink) 
                    txt1 = _items[jj].getPlaintextString(null);
                if (txt1 === null) 
                    break;
                if (Utils.startsWithString(txt1, "Текст ", true)) 
                    break;
                i = 0;
                let wrapi320 = new RefOutArgWrapper(i);
                let inoutres321 = CorrFootnoteTag.tryParse(txt1, wrapi320, true, false);
                i = wrapi320.value;
                if (inoutres321 !== null) 
                    break;
                let wrapi318 = new RefOutArgWrapper();
                let inoutres319 = Utils.tryParseInt(txt1.trim(), wrapi318);
                i = wrapi318.value;
                if (it.typ === UnitextPlaintextType.SUP && inoutres319) 
                    break;
                if (((tag.typ === CorrFootnoteTyps.SUPDIGIT || tag.typ === CorrFootnoteTyps.DIGIT)) && jj === (ind + 1)) {
                }
                else if (txt.length > (Math.floor((1.2 * (it.text.length))))) {
                    if (jj > 0 && (_items[jj - 1] instanceof UnitextComment)) {
                    }
                    else 
                        break;
                }
                let chs = 0;
                let hiphs = 0;
                for (const ch of txt1) {
                    if (Utils.isLetterOrDigit(ch)) 
                        chs++;
                }
                if (txt1.length > 1 && chs === 0) {
                    res.endInd = (ind = jj);
                    break;
                }
                for (const ch of txt1) {
                    if (Utils.isLetterOrDigit(ch)) 
                        break;
                    else if (ch === '_' || ch === '-') 
                        hiphs++;
                }
                if (hiphs > 10) {
                    res.endInd = (ind = jj);
                    break;
                }
                if (txt.length === 0) 
                    txt = txt1.trim();
                else 
                    txt = (txt + " " + txt1.trim());
                res.endInd = (ind = jj);
            }
            res.items.push(txt);
        }
        let delimLine = false;
        ind = res.beginInd;
        if (ind >= 2 && (_items[ind - 1] instanceof UnitextNewline)) {
            it = Utils.as(_items[ind - 2], UnitextPlaintext);
            if (it !== null) {
                let cou = 0;
                i = 0;
                for (i = 0; i < it.text.length; i++) {
                    if (CorrLine.isHiphen(it.text[i]) || it.text[i] === '_') 
                        cou++;
                    else if (!Utils.isWhitespace(it.text[i])) 
                        break;
                }
                if (cou > 0 && i >= it.text.length) {
                    res.beginInd -= 2;
                    delimLine = true;
                }
            }
        }
        if (res.startNumber !== 1 && res.startNumber !== numStart) {
            if (!delimLine && (res.items.length < 2)) {
                if (res.typ !== CorrFootnoteTyps.SUPDIGIT) 
                    return null;
            }
        }
        return res;
    }
    
    correctItem(it, robust) {
        let pl = Utils.as(it, UnitextPlaintext);
        if (pl !== null) {
            if (this.typ === CorrFootnoteTyps.SUPDIGIT && pl.typ === UnitextPlaintextType.SUP) {
                let num = 0;
                let wrapnum325 = new RefOutArgWrapper();
                let inoutres326 = Utils.tryParseInt(pl.text.trim(), wrapnum325);
                num = wrapnum325.value;
                if (inoutres326) {
                    let ii = num - this.startNumber;
                    if ((ii < 0) || ii >= this.items.length) 
                        return pl;
                    let fn = new UnitextFootnote();
                    fn.content = UnitextPlaintext._new57(this.items[ii]);
                    fn.customMark = num.toString();
                    return fn;
                }
            }
            let cnt = null;
            let txt = pl.text;
            for (let i = 0; i < txt.length; i++) {
                if (Utils.isWhitespace(txt[i])) 
                    continue;
                let j = i;
                let wrapj330 = new RefOutArgWrapper(j);
                let tag = CorrFootnoteTag.tryParse(txt, wrapj330, false, robust);
                j = wrapj330.value;
                if (tag === null) 
                    continue;
                if (tag.typ !== this.typ) 
                    continue;
                let ii = tag.number - this.startNumber;
                if ((ii < 0) || ii >= this.items.length) 
                    continue;
                if (cnt === null) 
                    cnt = new UnitextContainer();
                if (i > 0) 
                    cnt.children.push(UnitextPlaintext._new57(txt.substring(0, 0 + i)));
                cnt.children.push(UnitextFootnote._new329(UnitextPlaintext._new57(this.items[ii]), tag.number.toString()));
                j++;
                if (j >= txt.length) {
                    txt = "";
                    break;
                }
                txt = txt.substring(j);
                i = -1;
            }
            if (!Utils.isNullOrEmpty(txt) && cnt !== null) 
                cnt.children.push(UnitextPlaintext._new57(txt));
            return cnt;
        }
        if (it instanceof UnitextContainer) {
            let cnt = Utils.as(it, UnitextContainer);
            let isCh = false;
            for (let i = 0; i < cnt.children.length; i++) {
                let ch = this.correctItem(cnt.children[i], robust);
                if (ch === null) 
                    continue;
                cnt.children[i] = ch;
                isCh = true;
            }
            return (isCh ? cnt : null);
        }
        if (it instanceof UnitextTable) {
            let tab = Utils.as(it, UnitextTable);
            let isCh = false;
            for (let r = 0; r < tab.rowsCount; r++) {
                for (let c = 0; c < tab.colsCount; c++) {
                    let cel = tab.getCell(r, c);
                    if (cel === null) 
                        continue;
                    if (cel.rowBegin !== r || cel.colBegin !== c || cel.content === null) 
                        continue;
                    let cnt = this.correctItem(cel.content, robust);
                    if (cnt !== null) {
                        cel.content = cnt;
                        isCh = true;
                    }
                }
            }
            return (isCh ? tab : null);
        }
        if (it instanceof UnitextList) {
            let li = Utils.as(it, UnitextList);
            let isCh = false;
            for (const ii of li.items) {
                let cnt = this.correctItem(ii.content, robust);
                if (cnt !== null) {
                    isCh = true;
                    ii.content = cnt;
                }
                let sub = Utils.as(this.correctItem(ii.sublist, robust), UnitextList);
                if (sub !== null) {
                    ii.sublist = sub;
                    isCh = true;
                }
            }
            return (isCh ? li : null);
        }
        return null;
    }
    
    static _new307(_arg1) {
        let res = new CorrFootnoteContainer();
        res.typ = _arg1;
        return res;
    }
}


module.exports = CorrFootnoteContainer