# 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# project.
# The latest version of the code is available on the site www.pullenti.ru

import io
import typing
from pullenti.unisharp.Utils import Utils

from pullenti.morph.MorphGender import MorphGender
from pullenti.morph.LanguageHelper import LanguageHelper
from pullenti.ner.core.BracketHelper import BracketHelper
from pullenti.ner.person.internal.PersonNormalItemType import PersonNormalItemType

class PersonNormalItem:
    
    def __init__(self) -> None:
        self.typ = PersonNormalItemType.LAST
        self.ind0 = 0
        self.ind1 = 0
        self.src = None;
        self.gender = 0
        self.rnd0 = 0
        self.rnd1 = 0
        self.render = 0
        self.result_alt = None;
    
    def __str__(self) -> str:
        if ((self.rnd0 < 0) or (self.rnd1 < self.rnd0) or self.src is None): 
            return "?"
        if (self.rnd0 == self.rnd1): 
            return "{0}: {1}".format(Utils.enumToString(self.typ), self.src[self.rnd0].value)
        res = io.StringIO()
        print("{0}: ".format(Utils.enumToString(self.typ)), end="", file=res, flush=True)
        i = self.rnd0
        while i <= self.rnd1: 
            print("{0}{1}".format(("-" if i > self.rnd0 else ""), self.src[i].value), end="", file=res, flush=True)
            i += 1
        return Utils.toStringStringIO(res)
    
    @property
    def result(self) -> str:
        self.result_alt = (None)
        if ((self.rnd0 < 0) or (self.rnd1 < self.rnd0) or self.src is None): 
            return None
        if ((self.rnd0 + 1) == self.rnd1 and self.typ != PersonNormalItemType.LAST): 
            if (len(self.src[self.rnd0].value) == 1 and len(self.src[self.rnd1].value) > 1): 
                if (not self.src[self.rnd0].end_token.next0_.is_hiphen): 
                    return self.src[self.rnd1].value
            if (len(self.src[self.rnd0].value) > 1 and len(self.src[self.rnd1].value) == 1): 
                return self.src[self.rnd0].value
        res = self.src[self.rnd0].value
        i = self.rnd0 + 1
        first_pass4402 = True
        while True:
            if first_pass4402: first_pass4402 = False
            else: i += 1
            if (not (i <= self.rnd1)): break
            if (self.typ == PersonNormalItemType.LAST and (self.rnd0 + 1) == self.rnd1 and len(res) == 1): 
                if (res == "Д" or res == "О"): 
                    res = "{0}'{1}".format(res, self.src[i].value)
                    continue
                if (not LanguageHelper.is_cyrillic_vowel(res[0])): 
                    res = "{0}{1}".format(res, self.src[i].value)
                    continue
            if (i == self.rnd1 and not self.src[i].end_token.previous.is_hiphen): 
                ii = 0
                v = self.src[i].value
                ii = 1
                while ii < len(v): 
                    if (v[ii] != v[0]): 
                        break
                    ii += 1
                if (ii >= len(v)): 
                    continue
            res = "{0}-{1}".format(res, self.src[i].value)
        if (self.typ == PersonNormalItemType.FIRST and self.rnd0 == self.rnd1): 
            pit = self.src[self.rnd0]
            if (pit.firstname is not None and pit.firstname.is_in_dictionary and len(pit.firstname.vars0_) > 0): 
                for v in pit.firstname.vars0_: 
                    if (v.gender == MorphGender.MASCULINE and self.render == 1): 
                        exi = False
                        for vv in pit.firstname.vars0_: 
                            if (vv.gender == MorphGender.MASCULINE and self.render == 1 and vv.value == pit.value): 
                                exi = True
                        if ((not exi and v.value != pit.value and pit.value != "ВЛАД") and pit.value != "АЛЕКС"): 
                            self.result_alt = pit.value
                            return v.value
                    elif (v.gender == MorphGender.FEMINIE and self.render == 2): 
                        exi = False
                        for vv in pit.firstname.vars0_: 
                            if (vv.gender == MorphGender.FEMINIE and self.render == 2 and vv.value == pit.value): 
                                exi = True
                        if ((not exi and v.value != pit.value and pit.value != "КАТЕРИНА") and pit.value != "МАРЬЯ" and pit.value != "МАРИЯ"): 
                            self.result_alt = pit.value
                            if (pit.value == "ЛЕНА"): 
                                return "ЕЛЕНА"
                            return v.value
        if ((self.typ == PersonNormalItemType.LAST and self.rnd0 == self.rnd1 and ((res[0] == 'О' or res[0] == 'Д'))) and len(res) > 3): 
            pit = self.src[self.rnd0]
            txt = pit.get_source_text()
            i = 0
            while (i < len(txt)) and (i < 3): 
                if (BracketHelper.is_bracket_char(txt[i], False)): 
                    res = "{0}'{1}".format(res[0], res[1:])
                    break
                i += 1
        return res
    
    def init(self, src_ : typing.List['PersonItemToken']) -> None:
        self.ind0 = 0
        self.ind1 = -1
        self.rnd1 = -1
        self.rnd0 = self.rnd1
        self.src = src_
        self.render = 0
        self.gender = 0
    
    def fix(self) -> None:
        self.rnd0 = self.ind0
        self.rnd1 = self.ind1
        self.render = self.gender
    
    def calc_coef(self) -> float:
        if (self.ind1 < self.ind0): 
            if (self.typ == PersonNormalItemType.MIDDLE): 
                return 1
            return 0
        if (self.ind1 > self.ind0): 
            i = self.ind0
            while i < self.ind1: 
                if (self.src[i].whitespaces_after_count >= 4): 
                    return 0
                i += 1
        if (self.ind0 > 0 and self.src[self.ind0].begin_token.previous.is_hiphen): 
            if (self.src[self.ind0].whitespaces_before_count < 4): 
                return 0
        if (((self.ind1 + 1) < len(self.src)) and self.src[self.ind1].end_token.next0_.is_hiphen): 
            if (self.src[self.ind1].end_token.next0_.whitespaces_after_count < 4): 
                return 0
        co = 1
        i = self.ind0
        while i <= self.ind1: 
            pit = self.src[i]
            if (self.typ == PersonNormalItemType.FIRST): 
                if (self.ind0 == self.ind1 and len(pit.value) == 1): 
                    pass
                elif (pit.firstname is not None): 
                    if (self.gender == 2 and pit.firstname.morph.gender == MorphGender.FEMINIE): 
                        pass
                    elif (self.gender == 1 and pit.firstname.morph.gender == MorphGender.MASCULINE): 
                        pass
                    else: 
                        co *= 0.98
                elif (pit.middlename is not None): 
                    co *= 0.8
                elif (pit.lastname is not None and ((pit.lastname.is_in_dictionary or pit.lastname.is_lastname_has_std_tail))): 
                    co *= 0.8
                elif (pit.lastname is not None and pit.lastname.is_lastname_has_std_tail): 
                    co *= 0.9
                elif (self.gender == 2 and pit.morph.gender == MorphGender.FEMINIE): 
                    co *= 0.98
                elif (self.gender == 1 and pit.morph.gender == MorphGender.MASCULINE): 
                    co *= 0.98
                else: 
                    co *= 0.7
            elif (self.typ == PersonNormalItemType.MIDDLE): 
                if (self.ind0 == self.ind1 and len(pit.value) == 1): 
                    pass
                elif (pit.middlename is not None): 
                    if (self.gender == 2 and pit.middlename.morph.gender == MorphGender.FEMINIE): 
                        pass
                    elif (self.gender == 1 and pit.middlename.morph.gender == MorphGender.MASCULINE): 
                        pass
                    else: 
                        co *= 0.7
                elif (((pit.value.endswith("ВНА") or pit.value.endswith("ЧНА") or pit.value.endswith("КЫЗЫ"))) and self.gender == 2): 
                    pass
                elif (((pit.value.endswith("ИЧ") or pit.value.endswith("ОГЛЫ"))) and self.gender == 1): 
                    co *= 0.99
                elif (pit.firstname is not None): 
                    co *= 0.98
                elif (((self.gender == 2 and pit.value.endswith("ВА") and self.ind0 == self.ind1) and self.ind0 == (len(self.src) - 1) and self.src[0].lastname is not None) and len(self.src[0].value) > 2): 
                    co *= 0.99
                elif (pit.lastname is not None and pit.lastname.is_in_dictionary): 
                    co *= 0.8
                else: 
                    co *= 0.7
            elif (self.typ == PersonNormalItemType.LAST): 
                if (pit.value.endswith("КЫЗЫ")): 
                    return 0
                if (self.ind0 == self.ind1 and len(pit.value) == 1): 
                    if (LanguageHelper.is_cyrillic_vowel(pit.value[0])): 
                        co *= 0.5
                    else: 
                        return 0
                if (pit.value.endswith("ВНА") or pit.value.endswith("ЧНА")): 
                    if (self.gender == 2): 
                        if (self.ind0 == 0): 
                            co *= 0.7
                        else: 
                            co *= 0.2
                    else: 
                        co *= 0.3
                elif ((self.gender == 2 and pit.value.endswith("ВА") and self.ind0 == self.ind1) and self.ind0 == 2 and self.src[0].lastname is not None): 
                    co *= 0.3
                elif (pit.value.endswith("ИЧ")): 
                    if ((i + 1) >= len(self.src)): 
                        co *= 0.3
                    elif (self.ind0 == 0 or self.gender == 2): 
                        pass
                    else: 
                        co *= 0.85
                elif (pit.value.endswith("ОГЛЫ")): 
                    co *= 0.3
                elif (pit.lastname is not None and ((pit.lastname.is_in_dictionary or pit.lastname.is_lastname_has_std_tail))): 
                    if (self.gender == 2 and pit.lastname.morph.gender == MorphGender.FEMINIE): 
                        pass
                    elif (self.gender == 1 and pit.lastname.morph.gender == MorphGender.MASCULINE): 
                        pass
                    else: 
                        co *= 0.98
                elif (pit.firstname is not None or pit.middlename is not None): 
                    co *= 0.8
                else: 
                    co *= 0.98
            i += 1
        if ((self.typ == PersonNormalItemType.LAST and self.ind0 == 0 and self.ind1 > (self.ind0 + 1)) and (co < 0.6)): 
            co *= 1.5
        return co
    
    @staticmethod
    def _new3450(_arg1 : 'PersonNormalItemType') -> 'PersonNormalItem':
        res = PersonNormalItem()
        res.typ = _arg1
        return res