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

const UnitextPlaintextType = require("./../../UnitextPlaintextType");
const CorrLine = require("./CorrLine");

class UnitextCorrPdfLine {
    
    constructor() {
        this.texts = new Array();
        this.newlines = new Array();
        this.refLine = null;
        this.refText = null;
        this.refPos = 0;
        this.refLen = 0;
        this.resFoot = null;
    }
    
    removeAll() {
        for (const txt of this.texts) {
            txt.tag = null;
        }
        for (const nl of this.newlines) {
            nl.tag = null;
        }
    }
    
    get isPureNumber() {
        if (this.texts.length > 1) 
            return false;
        let num = 0;
        for (const ch of this.texts[0].text) {
            if (Utils.isDigit(ch)) 
                num++;
            else if (ch !== ' ' && ch !== '.') 
                return false;
        }
        return num > 0;
    }
    
    get headTextWithoutNumbers() {
        let tmp = new StringBuilder();
        for (const t of this.texts) {
            tmp.append(t.text.trim());
        }
        for (let i = 0; i < tmp.length; i++) {
            if (!Utils.isDigit(tmp.charAt(i))) {
                if (i > 0) 
                    tmp.remove(0, i);
                break;
            }
        }
        for (let i = tmp.length - 1; i >= 0; i--) {
            if (!Utils.isDigit(tmp.charAt(i))) {
                tmp.length = i + 1;
                break;
            }
        }
        if (tmp.length === 0) 
            return null;
        if (Utils.isDigit(tmp.charAt(0))) 
            return null;
        return tmp.toString().trim();
    }
    
    get lastChar() {
        for (let i = this.texts.length - 1; i >= 0; i--) {
            for (let j = this.texts[i].text.length - 1; j >= 0; j--) {
                let ch = this.texts[i].text[j];
                if (!Utils.isWhitespace(ch)) 
                    return ch;
            }
        }
        return ' ';
    }
    
    get isLastCharHiphen() {
        return CorrLine.isHiphen(this.lastChar);
    }
    
    removeLastHiph() {
        for (let i = this.texts.length - 1; i >= 0; i--) {
            for (let j = this.texts[i].text.length - 1; j >= 0; j--) {
                let ch = this.texts[i].text[j];
                if (CorrLine.isHiphen(ch)) {
                    this.texts[i].text = this.texts[i].text.substring(0, 0 + j);
                    return;
                }
                if (!Utils.isWhitespace(ch)) 
                    return;
            }
        }
    }
    
    get firstChar() {
        for (let i = 0; i < this.texts.length; i++) {
            for (const ch of this.texts[i].text) {
                if (!Utils.isWhitespace(ch)) 
                    return ch;
            }
        }
        return ' ';
    }
    
    get secondChar() {
        let cou = 0;
        for (let i = 0; i < this.texts.length; i++) {
            for (const ch of this.texts[i].text) {
                if (!Utils.isWhitespace(ch)) {
                    cou++;
                    if (cou > 1) 
                        return ch;
                }
            }
        }
        return ' ';
    }
    
    get textLength() {
        let len = 0;
        for (const t of this.texts) {
            for (const ch of t.text) {
                if (!Utils.isWhitespace(ch)) 
                    len += 1;
            }
        }
        return len;
    }
    
    get newlinesCount() {
        let cou = 0;
        for (const nl of this.newlines) {
            cou += nl.count;
        }
        return cou;
    }
    
    static _isOpenBracket(ch) {
        return "\"'`’<{([«“„”".indexOf(ch) >= 0;
    }
    
    static _isCloseBracket(ch) {
        return "\"'`’>})]»”“".indexOf(ch) >= 0;
    }
    
    get footnoteHeadNum() {
        let txt = this.texts[0].text;
        for (let i = 0; i < txt.length; i++) {
            if (!Utils.isWhitespace(txt[i])) {
                if (!Utils.isDigit(txt[i])) 
                    return 0;
                let num = ((txt.charCodeAt(i)) - ('0'.charCodeAt(0)));
                for (i = i + 1; i < txt.length; i++) {
                    if (Utils.isDigit(txt[i])) 
                        num = (num * 10) + (((txt.charCodeAt(i)) - ('0'.charCodeAt(0))));
                    else 
                        break;
                }
                if (num > 900) 
                    return 0;
                if (i < txt.length) {
                    for (; i < txt.length; i++) {
                        if (!Utils.isWhitespace(txt[i])) 
                            break;
                    }
                    if (i >= txt.length) {
                        if (this.texts.length > 1 && this.texts[0].typ !== UnitextPlaintextType.SIMPLE) 
                            return num;
                        return 0;
                    }
                    if (Utils.isLetter(txt[i])) {
                        if (!Utils.isUpperCase(txt[i])) 
                            return 0;
                    }
                    else if (!UnitextCorrPdfLine._isOpenBracket(txt[i])) 
                        return 0;
                    if (this.textLength < 8) 
                        return 0;
                    return num;
                }
                if (this.texts[0].typ !== UnitextPlaintextType.SIMPLE && this.texts.length > 1) {
                    if (this.textLength < 8) 
                        return 0;
                    return num;
                }
                break;
            }
        }
        return 0;
    }
    
    canUnion(next) {
        if (this.textLength < 30) 
            return false;
        let last = this.lastChar;
        let first = next.firstChar;
        if (CorrLine.isHiphen(last) || last === ',') 
            return true;
        if (last === '.' || last === ';' || last === ':') 
            return false;
        if (Utils.isLetter(first) && Utils.isLowerCase(first)) {
            if (Utils.isLetter(last) && Utils.isUpperCase(last)) 
                return false;
            let ch1 = next.secondChar;
            if (ch1 === ')' || ch1 === '.') 
                return false;
            return true;
        }
        if (UnitextCorrPdfLine._isOpenBracket(first)) {
            if (first === '(') 
                return true;
            let sec = next.secondChar;
            if (Utils.isLetter(sec) && Utils.isLowerCase(sec)) 
                return true;
        }
        return false;
    }
    
    attachFoot(foot) {
        let num = foot.footnoteHeadNum.toString();
        if (num === "17") {
        }
        for (let i = 0; i < this.texts.length; i++) {
            let txt = this.texts[i].text;
            for (let j = 0; j < txt.length; j++) {
                if (txt[j] === num[0]) {
                    let k = 0;
                    for (k = 0; (k < num.length) && ((k + j) < txt.length); k++) {
                        if (num[k] !== txt[j + k]) 
                            break;
                    }
                    if (k < num.length) 
                        continue;
                    let j1 = (j + k) - 1;
                    let ch0 = ' ';
                    let ch00 = ' ';
                    let doubt = false;
                    if (j === 0) {
                        if (i === 0) 
                            continue;
                        let txt0 = this.texts[i - 1].text;
                        ch0 = txt0[txt0.length - 1];
                        if (txt0.length > 1) 
                            ch00 = txt0[txt0.length - 2];
                    }
                    else {
                        ch0 = txt[j - 1];
                        if (j > 1) 
                            ch00 = txt[j - 2];
                    }
                    if (Utils.isWhitespace(ch0) || Utils.isDigit(ch0)) 
                        continue;
                    if (Utils.isLetter(ch0)) {
                    }
                    else if (ch0 === '.' || ch0 === ';' || UnitextCorrPdfLine._isCloseBracket(ch0)) {
                        if (!Utils.isLetter(ch00)) 
                            continue;
                    }
                    else if (ch0 === ',') 
                        doubt = true;
                    else 
                        continue;
                    ch0 = ' ';
                    if (j1 === (txt.length - 1)) {
                        if (i === (this.texts.length - 1)) 
                            ch0 = ' ';
                        else 
                            ch0 = this.texts[i + 1].text[0];
                    }
                    else 
                        ch0 = txt[j1 + 1];
                    if (Utils.isLetterOrDigit(ch0)) 
                        continue;
                    if (doubt && ch0 !== ' ' && this.texts[i].typ === UnitextPlaintextType.SIMPLE) 
                        continue;
                    foot.refLine = this;
                    foot.refText = this.texts[i];
                    foot.refPos = j;
                    foot.refLen = (j1 + 1) - j;
                    return true;
                }
            }
        }
        return false;
    }
    
    toString() {
        let tmp = new StringBuilder();
        let num = this.footnoteHeadNum;
        if (num > 0) 
            tmp.append("[").append(num).append("] ");
        if (this.refText !== null) 
            tmp.append(" -> (").append(this.refText.text).append(")[").append(this.refPos).append("] ");
        for (const t of this.texts) {
            tmp.append(t.text);
        }
        return tmp.toString();
    }
}


module.exports = UnitextCorrPdfLine