/*
 * SDK Pullenti Lingvo, 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#.NET project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

const Utils = require("./../../unisharp/Utils");
const ProgressEventArgs = require("./../../unisharp/ProgressEventArgs");

const SentItemType = require("./SentItemType");
const TextToken = require("./../../ner/TextToken");
const SemDocument = require("./../SemDocument");
const SemBlock = require("./../SemBlock");
const MiscHelper = require("./../../ner/core/MiscHelper");
const Sentence = require("./Sentence");
const OptimizerHelper = require("./OptimizerHelper");

class AnalyzeHelper {
    
    static process(ar, pars) {
        let txt = new SemDocument();
        for (let t = ar.firstToken; t !== null; t = t.next) {
            t.tag = null;
        }
        if (pars.progress !== null) 
            pars.progress.call(null, new ProgressEventArgs(0, null));
        let pers0 = 0;
        for (let t = ar.firstToken; t !== null; t = t.next) {
            if (pars.progress !== null) {
                let p = t.beginChar;
                if (ar.sofa.text.length < 100000) 
                    p = Utils.intDiv(p * 100, ar.sofa.text.length);
                else 
                    p = Utils.intDiv(p, (Utils.intDiv(ar.sofa.text.length, 100)));
                if (p !== pers0) {
                    pers0 = p;
                    pars.progress.call(null, new ProgressEventArgs(p, null));
                }
            }
            let t1 = t;
            for (let tt = t.next; tt !== null; tt = tt.next) {
                if (tt.isNewlineBefore) {
                    if (MiscHelper.canBeStartOfSentence(tt)) 
                        break;
                }
                t1 = tt;
            }
            try {
                AnalyzeHelper._processBlock(txt, ar, t, t1);
            } catch (ex) {
            }
            t = t1;
            if (pars.maxChar > 0 && t.endChar > pars.maxChar) 
                break;
        }
        OptimizerHelper.optimize(txt, pars);
        if (pars.progress !== null) 
            pars.progress.call(null, new ProgressEventArgs(100, null));
        return txt;
    }
    
    static _processBlock(res, ar, t0, t1) {
        let blk = new SemBlock(res);
        for (let t = t0; t !== null && t.endChar <= t1.endChar; t = t.next) {
            let te = t;
            for (let tt = t.next; tt !== null && tt.endChar <= t1.endChar; tt = tt.next) {
                if (MiscHelper.canBeStartOfSentence(tt)) 
                    break;
                else 
                    te = tt;
            }
            AnalyzeHelper._processSentence(blk, ar, t, te);
            t = te;
        }
        if (blk.fragments.length > 0) 
            res.blocks.push(blk);
    }
    
    static _processSentence(blk, ar, t0, t1) {
        let cou = 0;
        for (let t = t0; t !== null && (t.endChar < t1.endChar); t = t.next,cou++) {
        }
        if (cou > 70) {
            let cou2 = 0;
            for (let t = t0; t !== null && (t.endChar < t1.endChar); t = t.next,cou2++) {
                if (cou2 >= 70) {
                    t1 = t;
                    break;
                }
            }
        }
        let sents = Sentence.parseVariants(t0, t1, 0, 100, SentItemType.UNDEFINED);
        if (sents === null) 
            return;
        let max = -1;
        let best = null;
        let alt = null;
        for (const s of sents) {
            if ((t1 instanceof TextToken) && !t1.chars.isLetter) 
                s.lastChar = Utils.as(t1, TextToken);
            s.calcCoef(false);
            if (s.coef > max) {
                max = s.coef;
                best = s;
                alt = null;
            }
            else if (s.coef === max && max > 0) 
                alt = s;
        }
        if (best !== null && best.resBlock !== null) {
            best.addToBlock(blk, null);
            Utils.removeItem(sents, best);
            while (sents.length > 0) {
                max = -1;
                best = null;
                for (const s of sents) {
                    if (s.coef > max) {
                        best = s;
                        max = s.coef;
                    }
                }
                if (best === null) 
                    break;
                best.addToBlockVariants(blk);
                Utils.removeItem(sents, best);
            }
        }
    }
}


module.exports = AnalyzeHelper