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

const ReferentsEqualType = require("./../core/ReferentsEqualType");
const Referent = require("./../Referent");
const InstrumentKind = require("./InstrumentKind");
const ReferentClass = require("./../metadata/ReferentClass");
const MetaInstrumentBlock = require("./internal/MetaInstrumentBlock");
const DecreeReferent = require("./../decree/DecreeReferent");

/**
 * Представление фрагмента документа. Фрагменты образуют дерево с вершиной в InstrumentReferent.
 * 
 */
class InstrumentBlockReferent extends Referent {
    
    constructor(typename = null) {
        super((typename != null ? typename : InstrumentBlockReferent.OBJ_TYPENAME));
        this.m_Children = null;
        this.instanceOf = MetaInstrumentBlock.GLOBAL_META;
    }
    
    toStringEx(shortVariant, lang, lev = 0) {
        let res = new StringBuilder();
        let ki = this.kind;
        let str = null;
        str = Utils.asString(MetaInstrumentBlock.GLOBAL_META.kindFeature.convertInnerValueToOuterValue(ki.toString(), lang));
        if (str !== null) {
            res.append(str);
            if (this.kind2 !== InstrumentKind.UNDEFINED) {
                str = Utils.asString(MetaInstrumentBlock.GLOBAL_META.kindFeature.convertInnerValueToOuterValue(this.kind2.toString(), lang));
                if (str !== null) 
                    res.append(" (").append(str).append(")");
            }
        }
        if (this.number > 0) {
            res.append(" №").append(this.number);
            if (this.subNumber > 0) {
                res.append(".").append(this.subNumber);
                if (this.subNumber2 > 0) {
                    res.append(".").append(this.subNumber2);
                    if (this.subNumber3 > 0) 
                        res.append(".").append(this.subNumber3);
                }
            }
            if (this.minNumber > 0) {
                for (let i = res.length - 1; i >= 0; i--) {
                    if (res.charAt(i) === ' ' || res.charAt(i) === '.' || res.charAt(i) === '№') {
                        res.insert(i + 1, (String(this.minNumber) + "-"));
                        break;
                    }
                }
            }
        }
        if (ki === InstrumentKind.TABLE) {
            let cou = 0;
            for (const ch of this.children) {
                if (ch.kind === InstrumentKind.TABLEROW) 
                    cou++;
            }
            res.append(" ").append(cou).append(" строк, ").append(this.tableColumns).append(" столбцов");
        }
        let ignoreRef = false;
        if (this.isExpired && ki !== InstrumentKind.EDITIONS) {
            res.append(" (утратить силу)");
            ignoreRef = true;
        }
        else if (ki !== InstrumentKind.EDITIONS && ki !== InstrumentKind.APPROVED && (this.ref instanceof DecreeReferent)) {
            res.append(" (*)");
            ignoreRef = true;
        }
        if (this.isError) 
            res.append(" (ошибка в нумерации)");
        if ((((str = this.getStringValue(InstrumentBlockReferent.ATTR_NAME)))) === null) 
            str = this.getStringValue(InstrumentBlockReferent.ATTR_VALUE);
        if (str !== null) {
            if (str.length > 100) 
                str = str.substring(0, 0 + 100) + "...";
            res.append(" \"").append(str).append("\"");
        }
        else if (!ignoreRef && (this.ref instanceof Referent) && (lev < 30)) 
            res.append(" \"").append(this.ref.toStringEx(shortVariant, lang, lev + 1)).append("\"");
        return res.toString().trim();
    }
    
    get kind() {
        let s = this.getStringValue(InstrumentBlockReferent.ATTR_KIND);
        if (s === null) 
            return InstrumentKind.UNDEFINED;
        try {
            if (s === "Part" || s === "Base" || s === "Special") 
                return InstrumentKind.UNDEFINED;
            let res = InstrumentKind.of(s);
            if (res instanceof InstrumentKind) 
                return InstrumentKind.of(res);
        } catch (ex2273) {
        }
        return InstrumentKind.UNDEFINED;
    }
    set kind(_value) {
        if (_value !== InstrumentKind.UNDEFINED) 
            this.addSlot(InstrumentBlockReferent.ATTR_KIND, _value.toString().toUpperCase(), true, 0);
        return _value;
    }
    
    get kind2() {
        let s = this.getStringValue(InstrumentBlockReferent.ATTR_KIND2);
        if (s === null) 
            return InstrumentKind.UNDEFINED;
        try {
            let res = InstrumentKind.of(s);
            if (res instanceof InstrumentKind) 
                return InstrumentKind.of(res);
        } catch (ex2274) {
        }
        return InstrumentKind.UNDEFINED;
    }
    set kind2(_value) {
        if (_value !== InstrumentKind.UNDEFINED) 
            this.addSlot(InstrumentBlockReferent.ATTR_KIND2, _value.toString().toUpperCase(), true, 0);
        return _value;
    }
    
    get value() {
        return this.getStringValue(InstrumentBlockReferent.ATTR_VALUE);
    }
    set value(_value) {
        this.addSlot(InstrumentBlockReferent.ATTR_VALUE, _value, true, 0);
        return _value;
    }
    
    get ref() {
        return Utils.as(this.getSlotValue(InstrumentBlockReferent.ATTR_REF), Referent);
    }
    
    get isExpired() {
        return this.getStringValue(InstrumentBlockReferent.ATTR_EXPIRED) === "true";
    }
    set isExpired(_value) {
        this.addSlot(InstrumentBlockReferent.ATTR_EXPIRED, (_value ? "true" : null), true, 0);
        return _value;
    }
    
    get isError() {
        return this.getStringValue(InstrumentBlockReferent.ATTR_ERROR) === "true";
    }
    set isError(_value) {
        this.addSlot(InstrumentBlockReferent.ATTR_ERROR, (_value ? "true" : null), true, 0);
        return _value;
    }
    
    get number() {
        let str = this.getStringValue(InstrumentBlockReferent.ATTR_NUMBER);
        if (str === null) 
            return 0;
        let i = 0;
        let wrapi2275 = new RefOutArgWrapper();
        let inoutres2276 = Utils.tryParseInt(str, wrapi2275);
        i = wrapi2275.value;
        if (inoutres2276) 
            return i;
        return 0;
    }
    set number(_value) {
        if (_value >= 0) 
            this.addSlot(InstrumentBlockReferent.ATTR_NUMBER, _value.toString(), true, 0);
        return _value;
    }
    
    get subNumber() {
        let str = this.getStringValue(InstrumentBlockReferent.ATTR_SUBNUMBER);
        if (str === null) 
            return 0;
        let i = 0;
        let wrapi2277 = new RefOutArgWrapper();
        let inoutres2278 = Utils.tryParseInt(str, wrapi2277);
        i = wrapi2277.value;
        if (inoutres2278) 
            return i;
        return 0;
    }
    set subNumber(_value) {
        if (_value > 0) 
            this.addSlot(InstrumentBlockReferent.ATTR_SUBNUMBER, _value.toString(), true, 0);
        return _value;
    }
    
    get subNumber2() {
        let str = this.getStringValue(InstrumentBlockReferent.ATTR_SUB2NUMBER);
        if (str === null) 
            return 0;
        let i = 0;
        let wrapi2279 = new RefOutArgWrapper();
        let inoutres2280 = Utils.tryParseInt(str, wrapi2279);
        i = wrapi2279.value;
        if (inoutres2280) 
            return i;
        return 0;
    }
    set subNumber2(_value) {
        if (_value > 0) 
            this.addSlot(InstrumentBlockReferent.ATTR_SUB2NUMBER, _value.toString(), true, 0);
        return _value;
    }
    
    get subNumber3() {
        let str = this.getStringValue(InstrumentBlockReferent.ATTR_SUB3NUMBER);
        if (str === null) 
            return 0;
        let i = 0;
        let wrapi2281 = new RefOutArgWrapper();
        let inoutres2282 = Utils.tryParseInt(str, wrapi2281);
        i = wrapi2281.value;
        if (inoutres2282) 
            return i;
        return 0;
    }
    set subNumber3(_value) {
        if (_value > 0) 
            this.addSlot(InstrumentBlockReferent.ATTR_SUB3NUMBER, _value.toString(), true, 0);
        return _value;
    }
    
    get minNumber() {
        let str = this.getStringValue(InstrumentBlockReferent.ATTR_MINNUMBER);
        if (str === null) 
            return 0;
        let i = 0;
        let wrapi2283 = new RefOutArgWrapper();
        let inoutres2284 = Utils.tryParseInt(str, wrapi2283);
        i = wrapi2283.value;
        if (inoutres2284) 
            return i;
        return 0;
    }
    set minNumber(_value) {
        this.addSlot(InstrumentBlockReferent.ATTR_MINNUMBER, _value.toString(), true, 0);
        return _value;
    }
    
    get tableColumns() {
        let str = this.getStringValue(InstrumentBlockReferent.ATTR_TABLECOLUMNS);
        if (str === null) 
            return 0;
        let i = 0;
        let wrapi2285 = new RefOutArgWrapper();
        let inoutres2286 = Utils.tryParseInt(str, wrapi2285);
        i = wrapi2285.value;
        if (inoutres2286) 
            return i;
        return 0;
    }
    set tableColumns(_value) {
        this.addSlot(InstrumentBlockReferent.ATTR_TABLECOLUMNS, _value.toString(), true, 0);
        return _value;
    }
    
    get name() {
        return this.getStringValue(InstrumentBlockReferent.ATTR_NAME);
    }
    set name(_value) {
        this.addSlot(InstrumentBlockReferent.ATTR_NAME, _value, true, 0);
        return _value;
    }
    
    get children() {
        if (this.m_Children === null) {
            this.m_Children = new Array();
            for (const s of this.slots) {
                if (s.typeName === InstrumentBlockReferent.ATTR_CHILD) {
                    if (s.value instanceof InstrumentBlockReferent) 
                        this.m_Children.push(Utils.as(s.value, InstrumentBlockReferent));
                }
            }
        }
        return this.m_Children;
    }
    
    addSlot(attrName, attrValue, clearOldValue, statCount = 0) {
        this.m_Children = null;
        return super.addSlot(attrName, attrValue, clearOldValue, statCount);
    }
    
    canBeEquals(obj, typ = ReferentsEqualType.WITHINONETEXT) {
        return obj === this;
    }
    
    /**
     * Представить тип строкой русского языка.
     * @param typ тип
     * @param shortVal сокращённый или полный (например, ст. или статья)
     * @return слово
     */
    static kindToRusString(typ, shortVal) {
        if (typ === InstrumentKind.APPENDIX) 
            return (shortVal ? "прил." : "Приложение");
        if (typ === InstrumentKind.CLAUSE) 
            return (shortVal ? "ст." : "Статья");
        if (typ === InstrumentKind.CHAPTER) 
            return (shortVal ? "гл." : "Глава");
        if (typ === InstrumentKind.ITEM) 
            return (shortVal ? "п." : "Пункт");
        if (typ === InstrumentKind.PARAGRAPH) 
            return (shortVal ? "§" : "Параграф");
        if (typ === InstrumentKind.SUBPARAGRAPH) 
            return (shortVal ? "подпарагр." : "Подпараграф");
        if (typ === InstrumentKind.DOCPART) 
            return (shortVal ? "ч." : "Часть");
        if (typ === InstrumentKind.SECTION) 
            return (shortVal ? "раздел" : "Раздел");
        if (typ === InstrumentKind.INTERNALDOCUMENT) 
            return "Документ";
        if (typ === InstrumentKind.SUBITEM) 
            return (shortVal ? "пп." : "Подпункт");
        if (typ === InstrumentKind.SUBSECTION) 
            return (shortVal ? "подразд." : "Подраздел");
        if (typ === InstrumentKind.CLAUSEPART) 
            return (shortVal ? "ч." : "Часть");
        if (typ === InstrumentKind.INDENTION) 
            return (shortVal ? "абз." : "Абзац");
        if (typ === InstrumentKind.PREAMBLE) 
            return (shortVal ? "преамб." : "Преамбула");
        return null;
    }
    
    static static_constructor() {
        InstrumentBlockReferent.OBJ_TYPENAME = "INSTRBLOCK";
        InstrumentBlockReferent.ATTR_KIND = "KIND";
        InstrumentBlockReferent.ATTR_KIND2 = "KIND_SEC";
        InstrumentBlockReferent.ATTR_CHILD = "CHILD";
        InstrumentBlockReferent.ATTR_VALUE = "VALUE";
        InstrumentBlockReferent.ATTR_REF = "REF";
        InstrumentBlockReferent.ATTR_EXPIRED = "EXPIRED";
        InstrumentBlockReferent.ATTR_ERROR = "ERROR";
        InstrumentBlockReferent.ATTR_NAME = "NAME";
        InstrumentBlockReferent.ATTR_NUMBER = "NUMBER";
        InstrumentBlockReferent.ATTR_MINNUMBER = "MINNUMBER";
        InstrumentBlockReferent.ATTR_SUBNUMBER = "ADDNUMBER";
        InstrumentBlockReferent.ATTR_SUB2NUMBER = "ADDSECNUMBER";
        InstrumentBlockReferent.ATTR_SUB3NUMBER = "ADDTHIRDNUMBER";
        InstrumentBlockReferent.ATTR_TABLECOLUMNS = "TABLECOLUMNS";
        InstrumentBlockReferent.ATTR_TAILNUMBER = "TAILNUMBER";
    }
}


InstrumentBlockReferent.static_constructor();

module.exports = InstrumentBlockReferent