/*
 * 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 MorphNumber = require("./../morph/MorphNumber");
const DerivateGroup = require("./utils/DerivateGroup");
const SemLinkType = require("./SemLinkType");
const MorphWordForm = require("./../morph/MorphWordForm");
const SemObjectType = require("./SemObjectType");
const MeasureKind = require("./../ner/measure/MeasureKind");

/**
 * Семантический объект
 */
class SemObject {
    
    constructor(_graph) {
        this.graph = null;
        this.morph = new MorphWordForm();
        this.typ = SemObjectType.UNDEFINED;
        this.quantity = null;
        this.concept = null;
        this.attrs = new Array();
        this.measure = MeasureKind.UNDEFINED;
        this.not = false;
        this.tokens = new Array();
        this.linksFrom = new Array();
        this.linksTo = new Array();
        this.tag = null;
        this.graph = _graph;
    }
    
    get beginChar() {
        return (this.tokens.length > 0 ? this.tokens[0].beginChar : 0);
    }
    
    get endChar() {
        return (this.tokens.length > 0 ? this.tokens[this.tokens.length - 1].endChar : 0);
    }
    
    toString() {
        let res = new StringBuilder();
        if (this.not) 
            res.append("НЕ ");
        for (const a of this.attrs) {
            res.append(a.toString().toLowerCase()).append(" ");
        }
        if (this.quantity !== null) 
            res.append(this.quantity).append(" ");
        else if (this.morph.number === MorphNumber.PLURAL && this.typ === SemObjectType.NOUN) 
            res.append("* ");
        res.append((this.morph.normalCase != null ? this.morph.normalCase : "?"));
        return res.toString();
    }
    
    compareTo(other) {
        if (this.tokens.length === 0 || other.tokens.length === 0) 
            return 0;
        if (this.tokens[0].beginChar < other.tokens[0].beginChar) 
            return -1;
        if (this.tokens[0].beginChar > other.tokens[0].beginChar) 
            return 1;
        if (this.tokens[this.tokens.length - 1].endChar < other.tokens[other.tokens.length - 1].endChar) 
            return -1;
        if (this.tokens[this.tokens.length - 1].endChar > other.tokens[other.tokens.length - 1].endChar) 
            return 1;
        return 0;
    }
    
    /**
     * Проверка значения
     * @param word 
     * @param _typ 
     * @return 
     */
    isValue(word, _typ = SemObjectType.UNDEFINED) {
        if (_typ !== SemObjectType.UNDEFINED) {
            if (_typ !== this.typ) 
                return false;
        }
        if (this.morph.normalFull === word || this.morph.normalCase === word) 
            return true;
        let gr = Utils.as(this.concept, DerivateGroup);
        if (gr !== null) {
            if (gr.words[0].spelling === word) 
                return true;
        }
        return false;
    }
    
    /**
     * Найти объект, кторый связан с текущим исходящий связью (Source = this)
     * @param word 
     * @param _typ 
     * @param otyp 
     * @return 
     */
    findFromObject(word, _typ = SemLinkType.UNDEFINED, otyp = SemObjectType.UNDEFINED) {
        for (const li of this.linksFrom) {
            if (_typ !== SemLinkType.UNDEFINED && _typ !== li.typ) 
                continue;
            if (li.target.isValue(word, otyp)) 
                return li.target;
        }
        return null;
    }
    
    /**
     * Найти атрибут указанного типа
     * @param _typ 
     * @return 
     */
    findAttr(_typ) {
        for (const a of this.attrs) {
            if (a.typ === _typ) 
                return a;
        }
        return null;
    }
    
    static _new3820(_arg1, _arg2) {
        let res = new SemObject(_arg1);
        res.typ = _arg2;
        return res;
    }
}


module.exports = SemObject