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

const Termin = require("./../core/Termin");
const DecreeReferent = require("./../decree/DecreeReferent");
const DecreeToken = require("./../decree/internal/DecreeToken");
const InstrumentKind = require("./InstrumentKind");
const DecreeKind = require("./../decree/DecreeKind");
const ProcessorService = require("./../ProcessorService");
const Analyzer = require("./../Analyzer");
const InstrumentArtefactMeta = require("./internal/InstrumentArtefactMeta");
const InstrToken = require("./internal/InstrToken");
const InstrumentBlockReferent = require("./InstrumentBlockReferent");
const PullentiNerCoreInternalResourceHelper = require("./../core/internal/PullentiNerCoreInternalResourceHelper");
const MetaInstrumentBlock = require("./internal/MetaInstrumentBlock");
const InstrumentParticipantMeta = require("./internal/InstrumentParticipantMeta");
const InstrumentArtefactReferent = require("./InstrumentArtefactReferent");
const InstrumentReferent = require("./InstrumentReferent");
const MetaInstrument = require("./internal/MetaInstrument");
const InstrumentParticipantReferent = require("./InstrumentParticipantReferent");

/**
 * Анализатор структуры нормативных актов и договоров: восстановление иерархической структуры фрагментов, 
 * выделение фигурантов (для договоров и судебных документов), артефактов. 
 * Специфический анализатор, то есть нужно явно создавать процессор через функцию CreateSpecificProcessor, 
 * указав имя анализатора.
 */
class InstrumentAnalyzer extends Analyzer {
    
    get name() {
        return InstrumentAnalyzer.ANALYZER_NAME;
    }
    
    get caption() {
        return "Структура нормативно-правовых документов (НПА)";
    }
    
    get description() {
        return "Разбор структуры НПА на разделы и подразделы";
    }
    
    clone() {
        return new InstrumentAnalyzer();
    }
    
    get isSpecific() {
        return true;
    }
    
    get progressWeight() {
        return 1;
    }
    
    get typeSystem() {
        return [MetaInstrument.GLOBAL_META, MetaInstrumentBlock.GLOBAL_META, InstrumentParticipantMeta.GLOBAL_META, InstrumentArtefactMeta.GLOBAL_META];
    }
    
    get images() {
        let res = new Hashtable();
        res.put(MetaInstrument.DOC_IMAGE_ID, PullentiNerCoreInternalResourceHelper.getBytes("decree.png"));
        res.put(MetaInstrumentBlock.PART_IMAGE_ID, PullentiNerCoreInternalResourceHelper.getBytes("part.png"));
        res.put(InstrumentParticipantMeta.IMAGE_ID, PullentiNerCoreInternalResourceHelper.getBytes("participant.png"));
        res.put(InstrumentArtefactMeta.IMAGE_ID, PullentiNerCoreInternalResourceHelper.getBytes("artefact.png"));
        return res;
    }
    
    createReferent(type) {
        if (type === InstrumentReferent.OBJ_TYPENAME) 
            return new InstrumentReferent();
        if (type === InstrumentBlockReferent.OBJ_TYPENAME) 
            return new InstrumentBlockReferent();
        if (type === InstrumentParticipantReferent.OBJ_TYPENAME) 
            return new InstrumentParticipantReferent();
        if (type === InstrumentArtefactReferent.OBJ_TYPENAME) 
            return new InstrumentArtefactReferent();
        return null;
    }
    
    process(kit) {
        const FragToken = require("./internal/FragToken");
        let aa = kit.processor.findAnalyzer("DOCUMENT");
        if (aa === null) {
            for (const a of ProcessorService.getAnalyzers()) {
                if (a.name === "DOCUMENT") {
                    aa = a;
                    break;
                }
            }
        }
        let dfr = null;
        let needTestNewDoc = true;
        if (aa !== null) {
            let rt = aa.processReferent(kit.firstToken, "TEST");
            if (rt === null) 
                dfr = FragToken.createDocument(kit.firstToken, 0, InstrumentKind.UNDEFINED);
        }
        else 
            dfr = FragToken.createDocument(kit.firstToken, 0, InstrumentKind.UNDEFINED);
        if (dfr !== null && dfr.m_Doc !== null) {
            let ki = DecreeToken.getKind(dfr.m_Doc.typ, null);
            if ((((ki === DecreeKind.CONTRACT || ki === DecreeKind.KODEX || ki === DecreeKind.KONVENTION) || ki === DecreeKind.LAW || ki === DecreeKind.STANDARD) || ki === DecreeKind.ORDER || ki === DecreeKind.PUBLISHER) || ki === DecreeKind.USTAV) 
                needTestNewDoc = false;
            else if (DecreeToken.isJustice(dfr.m_Doc.typ)) 
                needTestNewDoc = false;
            else if (dfr.m_Doc.typ === "ИЗМЕНЕНИЕ" || dfr.m_Doc.typ === "ИЗМЕНЕНИЯ" || dfr.m_Doc.typ === "ПОЛОЖЕНИЕ") 
                needTestNewDoc = false;
            else if (dfr.children.length > 0 && dfr.children[0].kind === InstrumentKind.HEAD) {
                for (const ch of dfr.children[0].children) {
                    if (ch.kind === InstrumentKind.APPROVED && ch.referents !== null) {
                        for (const r of ch.referents) {
                            if (r.typeName === "DECREE") {
                                ki = r.kind;
                                if (((ki === DecreeKind.CONTRACT || ki === DecreeKind.KODEX || ki === DecreeKind.KONVENTION) || ki === DecreeKind.LAW || ki === DecreeKind.ORDER) || ki === DecreeKind.PUBLISHER || ki === DecreeKind.USTAV) 
                                    needTestNewDoc = false;
                            }
                        }
                    }
                }
            }
        }
        if (needTestNewDoc) {
            if (aa !== null) {
                let rt = aa.processReferent(kit.firstToken, "INSTRUMENT");
                if (rt !== null) 
                    return;
            }
        }
        if (dfr === null) 
            return;
        let ad = kit.getAnalyzerData(this);
        let res = dfr.createReferent(ad);
    }
    
    static initialize() {
        const ParticipantToken = require("./internal/ParticipantToken");
        if (InstrumentAnalyzer.m_Inited) 
            return;
        InstrumentAnalyzer.m_Inited = true;
        InstrumentArtefactMeta.initialize();
        MetaInstrumentBlock.initialize();
        MetaInstrument.initialize();
        InstrumentParticipantMeta.initialize();
        try {
            Termin.ASSIGN_ALL_TEXTS_AS_NORMAL = true;
            InstrToken.initialize();
            ParticipantToken.initialize();
            Termin.ASSIGN_ALL_TEXTS_AS_NORMAL = false;
        } catch (ex) {
            throw new Error(ex.message);
        }
        ProcessorService.registerAnalyzer(new InstrumentAnalyzer());
    }
    
    static static_constructor() {
        InstrumentAnalyzer.ANALYZER_NAME = "INSTRUMENT";
        InstrumentAnalyzer.m_Inited = false;
    }
}


InstrumentAnalyzer.static_constructor();

module.exports = InstrumentAnalyzer