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

const MorphGender = require("./../../../morph/MorphGender");
const MorphNumber = require("./../../../morph/MorphNumber");
const NounPhraseHelper = require("./../../core/NounPhraseHelper");
const TerminParseAttr = require("./../../core/TerminParseAttr");
const MorphLang = require("./../../../morph/MorphLang");
const NumberSpellingType = require("./../../NumberSpellingType");
const PersonPropertyReferent = require("./../../person/PersonPropertyReferent");
const Token = require("./../../Token");
const MetaToken = require("./../../MetaToken");
const TitleItemTokenTypes = require("./TitleItemTokenTypes");
const BracketParseAttr = require("./../../core/BracketParseAttr");
const NumberToken = require("./../../NumberToken");
const NounPhraseParseAttr = require("./../../core/NounPhraseParseAttr");
const TextToken = require("./../../TextToken");
const BracketHelper = require("./../../core/BracketHelper");
const ReferentToken = require("./../../ReferentToken");
const Termin = require("./../../core/Termin");
const TerminCollection = require("./../../core/TerminCollection");

class TitleItemToken extends MetaToken {
    
    constructor(begin, end, _typ) {
        super(begin, end, null);
        this.typ = TitleItemTokenTypes.UNDEFINED;
        this.value = null;
        this.typ = _typ;
    }
    
    toString() {
        return (this.typ.toString() + ": " + ((this.value != null ? this.value : "")));
    }
    
    static tryAttach(t) {
        let tt = Utils.as(t, TextToken);
        if (tt !== null) {
            let t1 = tt;
            if (tt.term === "ТЕМА") {
                let tit = TitleItemToken.tryAttach(tt.next);
                if (tit !== null && tit.typ === TitleItemTokenTypes.TYP) {
                    t1 = tit.endToken;
                    if (t1.next !== null && t1.next.isChar(':')) 
                        t1 = t1.next;
                    return TitleItemToken._new505(t, t1, TitleItemTokenTypes.TYPANDTHEME, tit.value);
                }
                if (tt.next !== null && tt.next.isChar(':')) 
                    t1 = tt.next;
                return new TitleItemToken(tt, t1, TitleItemTokenTypes.THEME);
            }
            if (tt.term === "ПО" || tt.term === "НА") {
                if (tt.next !== null && tt.next.isValue("ТЕМА", null)) {
                    t1 = tt.next;
                    if (t1.next !== null && t1.next.isChar(':')) 
                        t1 = t1.next;
                    return new TitleItemToken(tt, t1, TitleItemTokenTypes.THEME);
                }
            }
            if (tt.term === "ПЕРЕВОД" || tt.term === "ПЕР") {
                let tt2 = tt.next;
                if (tt2 !== null && tt2.isChar('.')) 
                    tt2 = tt2.next;
                if (tt2 instanceof TextToken) {
                    if (tt2.term === "C" || tt2.term === "С") {
                        tt2 = tt2.next;
                        if (tt2 instanceof TextToken) 
                            return new TitleItemToken(t, tt2, TitleItemTokenTypes.TRANSLATE);
                    }
                }
            }
            if (tt.term === "СЕКЦИЯ" || tt.term === "SECTION" || tt.term === "СЕКЦІЯ") {
                t1 = tt.next;
                if (t1 !== null && t1.isChar(':')) 
                    t1 = t1.next;
                let br = BracketHelper.tryParse(t1, BracketParseAttr.NO, 100);
                if (br !== null) 
                    t1 = br.endToken;
                else if (t1 !== tt.next) {
                    for (; t1 !== null; t1 = t1.next) {
                        if (t1.isNewlineAfter) 
                            break;
                    }
                    if (t1 === null) 
                        return null;
                }
                if (t1 !== tt.next) 
                    return new TitleItemToken(tt, t1, TitleItemTokenTypes.DUST);
            }
            t1 = null;
            if (tt.isValue("СПЕЦИАЛЬНОСТЬ", "СПЕЦІАЛЬНІСТЬ")) 
                t1 = tt.next;
            else if (tt.morph._class.isPreposition && tt.next !== null && tt.next.isValue("СПЕЦИАЛЬНОСТЬ", "СПЕЦІАЛЬНІСТЬ")) 
                t1 = tt.next.next;
            else if (tt.isChar('/') && tt.isNewlineBefore) 
                t1 = tt.next;
            if (t1 !== null) {
                if (t1.isCharOf(":") || t1.isHiphen) 
                    t1 = t1.next;
                let spec = TitleItemToken.tryAttachSpeciality(t1, true);
                if (spec !== null) {
                    spec.beginToken = t;
                    return spec;
                }
            }
        }
        let sss = TitleItemToken.tryAttachSpeciality(t, false);
        if (sss !== null) 
            return sss;
        if (t instanceof ReferentToken) 
            return null;
        let npt = NounPhraseHelper.tryParse(t, NounPhraseParseAttr.NO, 0, null);
        if (npt !== null) {
            let s = npt.getNormalCaseText(null, MorphNumber.UNDEFINED, MorphGender.UNDEFINED, false);
            let tok = TitleItemToken.m_Termins.tryParse(npt.endToken, TerminParseAttr.NO);
            if (tok !== null) {
                let ty = TitleItemTokenTypes.of(tok.termin.tag);
                if (ty === TitleItemTokenTypes.TYP) {
                    let tit = TitleItemToken.tryAttach(tok.endToken.next);
                    if (tit !== null && tit.typ === TitleItemTokenTypes.THEME) 
                        return TitleItemToken._new505(npt.beginToken, tit.endToken, TitleItemTokenTypes.TYPANDTHEME, s);
                    if (s === "РАБОТА" || s === "РОБОТА" || s === "ПРОЕКТ") 
                        return null;
                    let t1 = tok.endToken;
                    if (s === "ДИССЕРТАЦИЯ" || s === "ДИСЕРТАЦІЯ") {
                        let err = 0;
                        for (let ttt = t1.next; ttt !== null; ttt = ttt.next) {
                            if (ttt.morph._class.isPreposition) 
                                continue;
                            if (ttt.isValue("СОИСКАНИЕ", "")) 
                                continue;
                            let npt1 = NounPhraseHelper.tryParse(ttt, NounPhraseParseAttr.NO, 0, null);
                            if (npt1 !== null && npt1.noun.isValue("СТЕПЕНЬ", "СТУПІНЬ")) {
                                t1 = (ttt = npt1.endToken);
                                continue;
                            }
                            let rt = t1.kit.processReferent("PERSON", ttt, null);
                            if (rt !== null && (rt.referent instanceof PersonPropertyReferent)) {
                                let ppr = Utils.as(rt.referent, PersonPropertyReferent);
                                if (ppr.name === "доктор наук") {
                                    t1 = rt.endToken;
                                    s = "ДОКТОРСКАЯ ДИССЕРТАЦИЯ";
                                    break;
                                }
                                else if (ppr.name === "кандидат наук") {
                                    t1 = rt.endToken;
                                    s = "КАНДИДАТСКАЯ ДИССЕРТАЦИЯ";
                                    break;
                                }
                                else if (ppr.name === "магистр") {
                                    t1 = rt.endToken;
                                    s = "МАГИСТЕРСКАЯ ДИССЕРТАЦИЯ";
                                    break;
                                }
                            }
                            if (ttt.isValue("ДОКТОР", null) || ttt.isValue("КАНДИДАТ", null) || ttt.isValue("МАГИСТР", "МАГІСТР")) {
                                t1 = ttt;
                                npt1 = NounPhraseHelper.tryParse(ttt.next, NounPhraseParseAttr.NO, 0, null);
                                if (npt1 !== null && npt1.endToken.isValue("НАУК", null)) 
                                    t1 = npt1.endToken;
                                s = (ttt.isValue("МАГИСТР", "МАГІСТР") ? "МАГИСТЕРСКАЯ ДИССЕРТАЦИЯ" : (ttt.isValue("ДОКТОР", null) ? "ДОКТОРСКАЯ ДИССЕРТАЦИЯ" : "КАНДИДАТСКАЯ ДИССЕРТАЦИЯ"));
                                break;
                            }
                            if ((++err) > 3) 
                                break;
                        }
                    }
                    if (t1.next !== null && t1.next.isChar('.')) 
                        t1 = t1.next;
                    if (s.endsWith("ОТЧЕТ") && t1.next !== null && t1.next.isValue("О", null)) {
                        let npt1 = NounPhraseHelper.tryParse(t1.next, NounPhraseParseAttr.PARSEPREPOSITION, 0, null);
                        if (npt1 !== null && npt1.morph._case.isPrepositional) 
                            t1 = npt1.endToken;
                    }
                    return TitleItemToken._new505(npt.beginToken, t1, ty, s);
                }
            }
        }
        let tok1 = TitleItemToken.m_Termins.tryParse(t, TerminParseAttr.NO);
        if (tok1 !== null) {
            let t1 = tok1.endToken;
            let re = new TitleItemToken(tok1.beginToken, t1, TitleItemTokenTypes.of(tok1.termin.tag));
            return re;
        }
        if (BracketHelper.canBeStartOfSequence(t, false, false)) {
            tok1 = TitleItemToken.m_Termins.tryParse(t.next, TerminParseAttr.NO);
            if (tok1 !== null && BracketHelper.canBeEndOfSequence(tok1.endToken.next, false, null, false)) {
                let t1 = tok1.endToken.next;
                return new TitleItemToken(tok1.beginToken, t1, TitleItemTokenTypes.of(tok1.termin.tag));
            }
        }
        return null;
    }
    
    static tryAttachSpeciality(t, keyWordBefore) {
        if (t === null) 
            return null;
        let susp = false;
        if (!keyWordBefore) {
            if (!t.isNewlineBefore) 
                susp = true;
        }
        let val = null;
        let t0 = t;
        let digCount = 0;
        for (let i = 0; i < 3; i++) {
            let nt = Utils.as(t, NumberToken);
            if (nt === null) 
                break;
            if (nt.typ !== NumberSpellingType.DIGIT || nt.morph._class.isAdjective) 
                break;
            if (val === null) 
                val = new StringBuilder();
            if (susp && t.lengthChar !== 2) 
                return null;
            let digs = nt.getSourceText();
            digCount += digs.length;
            val.append(digs);
            if (t.next === null) 
                break;
            t = t.next;
            if (t.isCharOf(".,") || t.isHiphen) {
                if (susp && (i < 2)) {
                    if (!t.isChar('.') || t.isWhitespaceAfter || t.isWhitespaceBefore) 
                        return null;
                }
                if (t.next !== null) 
                    t = t.next;
            }
        }
        if (val === null || (digCount < 5)) 
            return null;
        if (digCount !== 6) {
            if (!keyWordBefore) 
                return null;
        }
        else {
            val.insert(4, '.');
            val.insert(2, '.');
        }
        for (let tt = t.next; tt !== null; tt = tt.next) {
            if (tt.isNewlineBefore) 
                break;
            let br = BracketHelper.tryParse(tt, BracketParseAttr.NO, 100);
            if (br !== null) {
                t = (tt = br.endToken);
                continue;
            }
            t = tt;
        }
        return TitleItemToken._new505(t0, t, TitleItemTokenTypes.SPECIALITY, val.toString());
    }
    
    static initialize() {
        if (TitleItemToken.m_Termins !== null) 
            return;
        TitleItemToken.m_Termins = new TerminCollection();
        for (const s of ["РАБОТА", "ДИССЕРТАЦИЯ", "ОТЧЕТ", "ПЛАН", "ОБЗОР", "ДИПЛОМ", "ПРОЕКТ", "СПРАВКА", "АВТОРЕФЕРАТ", "РЕФЕРАТ", "TECHNOLOGY ISSUES", "TECHNOLOGY COURSE", "УЧЕБНИК", "УЧЕБНОЕ ПОСОБИЕ"]) {
            TitleItemToken.m_Termins.add(Termin._new96(s, TitleItemTokenTypes.TYP));
        }
        for (const s of ["РОБОТА", "ДИСЕРТАЦІЯ", "ЗВІТ", "ОГЛЯД", "ДИПЛОМ", "ПРОЕКТ", "ДОВІДКА", "АВТОРЕФЕРАТ", "РЕФЕРАТ"]) {
            TitleItemToken.m_Termins.add(Termin._new510(s, MorphLang.UA, TitleItemTokenTypes.TYP));
        }
        for (const s of ["ДОПУСТИТЬ К ЗАЩИТА", "РЕКОМЕНДОВАТЬ К ЗАЩИТА", "ДОЛЖНОСТЬ", "ЦЕЛЬ РАБОТЫ", "НА ПРАВАХ РУКОПИСИ", "ПО ИЗДАНИЮ", "ПОЛУЧЕНО"]) {
            TitleItemToken.m_Termins.add(Termin._new96(s, TitleItemTokenTypes.DUST));
        }
        for (const s of ["ДОПУСТИТИ ДО ЗАХИСТУ", "РЕКОМЕНДУВАТИ ДО ЗАХИСТ", "ПОСАДА", "МЕТА РОБОТИ", "НА ПРАВАХ РУКОПИСУ", "ПО ВИДАННЮ", "ОТРИМАНО"]) {
            TitleItemToken.m_Termins.add(Termin._new510(s, MorphLang.UA, TitleItemTokenTypes.DUST));
        }
        for (const s of ["УТВЕРЖДАТЬ", "СОГЛАСЕН", "СТВЕРДЖУВАТИ", "ЗГОДЕН"]) {
            TitleItemToken.m_Termins.add(Termin._new96(s, TitleItemTokenTypes.ADOPT));
        }
        for (const s of ["НАУЧНЫЙ РУКОВОДИТЕЛЬ", "РУКОВОДИТЕЛЬ РАБОТА", "НАУКОВИЙ КЕРІВНИК", "КЕРІВНИК РОБОТА"]) {
            TitleItemToken.m_Termins.add(Termin._new96(s, TitleItemTokenTypes.BOSS));
        }
        for (const s of ["НАУЧНЫЙ КОНСУЛЬТАНТ", "КОНСУЛЬТАНТ", "НАУКОВИЙ КОНСУЛЬТАНТ"]) {
            TitleItemToken.m_Termins.add(Termin._new96(s, TitleItemTokenTypes.CONSULTANT));
        }
        for (const s of ["РЕДАКТОР", "РЕДАКТОРСКАЯ ГРУППА", "РЕЦЕНЗЕНТ", "РЕДАКТОРСЬКА ГРУПА"]) {
            TitleItemToken.m_Termins.add(Termin._new96(s, TitleItemTokenTypes.EDITOR));
        }
        for (const s of ["ОФИЦИАЛЬНЫЙ ОППОНЕНТ", "ОППОНЕНТ", "ОФІЦІЙНИЙ ОПОНЕНТ"]) {
            TitleItemToken.m_Termins.add(Termin._new96(s, TitleItemTokenTypes.OPPONENT));
        }
        for (const s of ["ИСПОЛНИТЕЛЬ", "ОТВЕТСТВЕННЫЙ ИСПОЛНИТЕЛЬ", "АВТОР", "ДИПЛОМНИК", "КОЛЛЕКТТИВ ИСПОЛНИТЕЛЕЙ", "ВЫПОЛНИТЬ", "ИСПОЛНИТЬ"]) {
            TitleItemToken.m_Termins.add(Termin._new96(s, TitleItemTokenTypes.WORKER));
        }
        for (const s of ["ВИКОНАВЕЦЬ", "ВІДПОВІДАЛЬНИЙ ВИКОНАВЕЦЬ", "АВТОР", "ДИПЛОМНИК", "КОЛЛЕКТТИВ ВИКОНАВЦІВ", "ВИКОНАТИ", "ВИКОНАТИ"]) {
            TitleItemToken.m_Termins.add(Termin._new510(s, MorphLang.UA, TitleItemTokenTypes.WORKER));
        }
        for (const s of ["КЛЮЧЕВЫЕ СЛОВА", "KEYWORDS", "КЛЮЧОВІ СЛОВА"]) {
            TitleItemToken.m_Termins.add(Termin._new96(s, TitleItemTokenTypes.KEYWORDS));
        }
    }
    
    static _new505(_arg1, _arg2, _arg3, _arg4) {
        let res = new TitleItemToken(_arg1, _arg2, _arg3);
        res.value = _arg4;
        return res;
    }
    
    static static_constructor() {
        TitleItemToken.m_Termins = null;
    }
}


TitleItemToken.static_constructor();

module.exports = TitleItemToken