/*
 * 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 CorrLine = require("./CorrLine");
const UnitextContainer = require("./../../UnitextContainer");
const UnitextItem = require("./../../UnitextItem");
const WhitespaceType = require("./../../WhitespaceType");
const UnitextPlaintext = require("./../../UnitextPlaintext");
const UnitextFootnote = require("./../../UnitextFootnote");
const UnitextPagebreak = require("./../../UnitextPagebreak");
const UnitextCorrPdfLine = require("./UnitextCorrPdfLine");
const UnitextNewline = require("./../../UnitextNewline");

class UnitextCorrPdfPage {
    
    constructor() {
        this.num = 0;
        this.lines = new Array();
        this.pageBreak = null;
        this.footnotes = new Array();
    }
    
    toString() {
        let tmp = new StringBuilder();
        tmp.append("№").append(this.num).append(" ");
        if (this.footnotes.length > 0) 
            tmp.append("Foots:").append(this.footnotes.length).append(" ");
        tmp.append(this.lines[0].toString());
        return tmp.toString();
    }
    
    static _createPages(cnt) {
        let pages = new Array();
        let page = null;
        let line = null;
        for (let i = 0; i < cnt.children.length; i++) {
            let it = cnt.children[i];
            it.tag = i;
            if (it instanceof UnitextPlaintext) {
                let txt = it.text;
                if (Utils.isNullOrEmpty(txt)) 
                    continue;
                txt = txt.toUpperCase();
                if (txt.startsWith("КОНСУЛЬТАНТПЛЮС") || txt.includes("ПРЕДОСТАВЛЕН КОНСУЛЬТАНТПЛЮС")) {
                    let j = 0;
                    for (j = i + 1; j < cnt.children.length; j++) {
                        let it1 = cnt.children[j];
                        if (it1 instanceof UnitextPagebreak) 
                            break;
                        if (it1 instanceof UnitextNewline) 
                            continue;
                        if (!(it1 instanceof UnitextPlaintext)) 
                            break;
                        txt = it1.text;
                        if (Utils.isNullOrEmpty(txt)) 
                            continue;
                        txt = txt.toUpperCase();
                        if (txt.includes("ПРАВОВАЯ ПОДДЕРЖКА") || txt.includes("CONSULTANT.RU")) 
                            continue;
                        if (txt.includes("КОНСУЛЬТАНТПЛЮС") || txt.includes("ДАТА СОХРАНЕНИЯ")) 
                            continue;
                        break;
                    }
                    cnt.children.splice(i, j - i);
                    i--;
                    continue;
                }
                if (page === null) {
                    page = new UnitextCorrPdfPage();
                    pages.push(page);
                    page.num = pages.length;
                    line = null;
                    if (page.num === 19) {
                    }
                }
                if (line === null) {
                    line = new UnitextCorrPdfLine();
                    page.lines.push(line);
                }
                line.texts.push(Utils.as(it, UnitextPlaintext));
                continue;
            }
            if (it instanceof UnitextNewline) {
                if (line !== null) 
                    line.newlines.push(Utils.as(it, UnitextNewline));
                line = null;
                continue;
            }
            if (it instanceof UnitextPagebreak) {
                if (page !== null) 
                    page.pageBreak = Utils.as(it, UnitextPagebreak);
                page = null;
                continue;
            }
            if (it instanceof UnitextFootnote) 
                continue;
            line = null;
        }
        return pages;
    }
    
    static correct(cnt) {
        let pages = UnitextCorrPdfPage._createPages(cnt);
        if (pages.length === 0) 
            return;
        let titles = new Hashtable();
        for (const p of pages) {
            for (let k = 0; k < 2; k++) {
                let line = p.lines[(k === 0 ? 0 : (p.lines.length - 1))];
                let tit = line.headTextWithoutNumbers;
                if (tit !== null) {
                    if (!titles.containsKey(tit)) 
                        titles.put(tit, 1);
                    else 
                        titles.put(tit, titles.get(tit) + 1);
                }
                if (k === 0 && p.lines.length === 1) 
                    break;
            }
        }
        let changes = false;
        let minCou = Utils.intDiv(pages.length, 4);
        if (minCou < 2) 
            minCou = 2;
        for (const p of pages) {
            for (let k = 0; k < 2; k++) {
                if (p.lines.length === 0) 
                    break;
                let line = p.lines[(k === 0 ? 0 : (p.lines.length - 1))];
                let tit = line.headTextWithoutNumbers;
                if (tit !== null) {
                    let cou = 0;
                    let wrapcou363 = new RefOutArgWrapper();
                    titles.tryGetValue(tit, wrapcou363);
                    cou = wrapcou363.value;
                    if (cou > minCou || ((cou === minCou && pages.length === minCou))) {
                        line.removeAll();
                        Utils.removeItem(p.lines, line);
                        changes = true;
                        k--;
                        continue;
                    }
                }
                if (line.isPureNumber) {
                    line.removeAll();
                    Utils.removeItem(p.lines, line);
                    changes = true;
                    k--;
                    continue;
                }
                if (k === 0 && p.lines.length === 1) 
                    break;
            }
        }
        if (changes) {
            for (let i = cnt.children.length - 1; i >= 0; i--) {
                if (cnt.children[i].tag === null) 
                    cnt.children.splice(i, 1);
            }
            for (let i = cnt.children.length - 1; i >= 0; i--) {
                cnt.children[i].tag = i;
            }
        }
        for (const p of pages) {
            if (p.num === 57) {
            }
            p.processFootnotes();
        }
        changes = false;
        for (let i = pages.length - 1; i >= 0; i--) {
            if (i === 17) {
            }
            if (pages[i].createFootnotes(cnt)) 
                changes = true;
        }
        for (let i = 0; i < cnt.children.length; i++) {
            cnt.children[i].tag = i;
        }
        let total = 0;
        let hiphens = 0;
        for (const p of pages) {
            for (const l of p.lines) {
                if (l.textLength < 40) 
                    continue;
                total++;
                if (CorrLine.isHiphen(l.lastChar)) 
                    hiphens++;
            }
        }
        let hasHiph = false;
        if (hiphens > 0 && ((Utils.intDiv(hiphens * 100, total))) > 10) 
            hasHiph = true;
        for (let i = pages.length - 1; i >= 0; i--) {
            let page = pages[i];
            if (page.lines.length === 0) 
                continue;
            if (i === 2) {
            }
            if (((i + 1) < pages.length) && pages[i + 1].lines.length > 0) {
                let last = page.lines[page.lines.length - 1];
                if (last.canUnion(pages[i + 1].lines[0])) {
                    page.pageBreak.typ = WhitespaceType.ONESPACE;
                    if (hasHiph && last.isLastCharHiphen) {
                        page.pageBreak.typ = WhitespaceType.IGNORABLE;
                        if (((i + 1) < page.lines.length) && Utils.isLowerCase(page.lines[i + 1].firstChar)) 
                            last.removeLastHiph();
                    }
                    for (let k = last.newlines.length - 1; k >= 0; k--) {
                        cnt.children.splice(last.newlines[k].tag, 1);
                    }
                }
            }
            for (let j = page.lines.length - 2; j >= 0; j--) {
                let line = page.lines[j];
                if (line.canUnion(page.lines[j + 1])) {
                    let i0 = -1;
                    if (line.newlines.length > 0) 
                        i0 = line.newlines[0].tag;
                    for (let k = line.newlines.length - 1; k >= 0; k--) {
                        cnt.children.splice(line.newlines[k].tag, 1);
                    }
                    if (hasHiph && line.isLastCharHiphen) {
                        if (Utils.isLowerCase(page.lines[j + 1].firstChar)) 
                            line.removeLastHiph();
                    }
                    else {
                        if (i0 < 0) 
                            i0 = (line.texts[line.texts.length - 1].tag) + 1;
                        cnt.children.splice(i0, 0, UnitextPlaintext._new57(" "));
                    }
                }
            }
        }
        for (let i = 0; i < (cnt.children.length - 1); i++) {
            if ((cnt.children[i] instanceof UnitextPagebreak) && (cnt.children[i + 1] instanceof UnitextNewline)) {
                cnt.children.splice(i + 1, 1);
                i--;
                continue;
            }
            else if ((cnt.children[i + 1] instanceof UnitextPagebreak) && (cnt.children[i] instanceof UnitextNewline)) {
                cnt.children.splice(i, 1);
                i--;
                continue;
            }
        }
    }
    
    processFootnotes() {
        let foots = new Array();
        let max = 0;
        for (let i = this.lines.length - 1; i >= 0; i--) {
            let _num = this.lines[i].footnoteHeadNum;
            if (_num > 0) {
                foots.splice(0, 0, this.lines[i]);
                max = 0;
            }
            else 
                max++;
            if (max > 5) 
                break;
        }
        if (foots.length === 0) 
            return;
        for (let i = 0; i < (foots.length - 1); i++) {
            if ((foots[i].footnoteHeadNum + 1) !== foots[i + 1].footnoteHeadNum) {
                if (foots[i].footnoteHeadNum !== (i + 1)) 
                    return;
                if ((i + 2) === foots.length) {
                }
                else if ((foots[i].footnoteHeadNum + 1) === foots[i + 2].footnoteHeadNum) {
                }
                else 
                    return;
                foots.splice(i + 1, 1);
                i--;
            }
        }
        let fi = 0;
        let j = 0;
        max = this.lines.indexOf(foots[0]);
        for (; fi < foots.length; fi++) {
            let foot = foots[fi];
            for (; j < max; j++) {
                let li = this.lines[j];
                if (j === 18) {
                }
                if (li.attachFoot(foot)) 
                    break;
            }
            if (j >= max) 
                break;
        }
        if (fi < foots.length) 
            return;
        this.footnotes.splice(this.footnotes.length, 0, ...foots);
    }
    
    createFootnotes(cnt) {
        if (this.footnotes.length === 0) 
            return false;
        let i0 = 0;
        let i1 = 0;
        for (let f = this.footnotes.length - 1; f >= 0; f--) {
            let foot = this.footnotes[f];
            i0 = foot.texts[0].tag;
            i1 = i0 + 100;
            if ((f + 1) < this.footnotes.length) 
                i1 = this.footnotes[f + 1].texts[0].tag;
            let fn = new UnitextFootnote();
            fn.customMark = (String(foot.footnoteHeadNum));
            foot.resFoot = fn;
            fn.content = new UnitextContainer();
            let needSp = false;
            let needTruct = true;
            for (let i = i0; (i < i1) && (i < cnt.children.length); i++) {
                let it = cnt.children[i];
                it.parent = fn.content;
                if (it instanceof UnitextPlaintext) {
                    if (needTruct) {
                        needTruct = false;
                        let pt0 = Utils.as(it, UnitextPlaintext);
                        pt0.text = pt0.text.substring(fn.customMark.length).trim();
                    }
                    if (needSp) 
                        fn.content.children.push(UnitextPlaintext._new57(" "));
                    needSp = false;
                    fn.content.children.push(it);
                }
                else if (it instanceof UnitextNewline) 
                    needSp = true;
                else 
                    break;
            }
        }
        for (i1 = i0; i1 < cnt.children.length; i1++) {
            let it = cnt.children[i1];
            if (it instanceof UnitextPagebreak) 
                break;
        }
        cnt.children.splice(i0, i1 - i0);
        for (let f = this.footnotes.length - 1; f >= 0; f--) {
            let foot = this.footnotes[f];
            i0 = foot.refText.tag;
            if (foot.refPos === 0) {
                if (foot.refText.text.length === foot.refLen) 
                    cnt.children[i0] = foot.resFoot;
                else {
                    foot.refText.text = Utils.trimStartString(foot.refText.text.substring(foot.refLen));
                    cnt.children.splice(i0, 0, foot.resFoot);
                }
            }
            else if ((foot.refPos + foot.refLen) === foot.refText.text.length) {
                foot.refText.text = foot.refText.text.substring(0, 0 + foot.refPos);
                cnt.children.splice(i0 + 1, 0, foot.resFoot);
            }
            else {
                let txtTail = foot.refText.text.substring(foot.refPos + foot.refLen, foot.refPos + foot.refLen + foot.refText.text.length - foot.refPos - foot.refLen);
                foot.refText.text = foot.refText.text.substring(0, 0 + foot.refPos);
                cnt.children.splice(i0 + 1, 0, foot.resFoot);
                cnt.children.splice(i0 + 2, 0, UnitextPlaintext._new57(txtTail));
            }
        }
        i0 = this.lines.indexOf(this.footnotes[0]);
        if (i0 > 0) 
            this.lines.splice(i0, this.lines.length - i0);
        return true;
    }
}


module.exports = UnitextCorrPdfPage