from cltk.core.data_types import Language

Language(
    name="Classical Mongolian",
    glottolog_id="",
    latitude=0.0,
    longitude=0.0,
    dates=[],
    family_id="",
    parent_id="",
    level="",
    iso_639_3_code="cmg",
    type="h",
)

from cltk.languages.glottolog import LANGUAGES

print(LANGUAGES["gmh"])

"""
Explanation: Language
Doc
Process
Pipeline
MorphosyntacticFeature
MorphosyntacticFeatureBundle
Form
DecisionTree

Language <a name="language"></a>
Language are used to identify each language and keep track of their attributes (lat-long, 3-letter ISO code, etc.). Users do not normally need to create these themselves, though this type could be extended to distinguish dialects.
End of explanation
"""


from pprint import pprint
pprint([(l.name, l.iso_639_3_code) for _, l in LANGUAGES.items()])

"""
Explanation: The following records all pre-modern languages as identified by the Glottolog project.
End of explanation
"""


from cltk.core.data_types import Word

Word(index_char_start=0, index_char_stop=6, index_token=0, string="Gallia", pos="nom")

"""
Explanation: Word <a name="word"></a>
Word is one of the most important objects. It contains all token-level information generated by a Process.
End of explanation
"""


from cltk.core.data_types import Doc

Doc(raw="Gallia est omnis divisa in partes tres")

"""
Explanation: Doc <a name="doc"></a>
Doc is the other of the two most important types. It too is build up each time a Process runs.
Token-level information is stored at Doc.words, while larger units of information (e.g., an original input string) are kept elsewhere here.
End of explanation
"""


from cltk import NLP
cltk_nlp = NLP(language="lat")
cltk_doc = cltk_nlp.analyze(text="Gallia est omnis divisa in partes tres")

cltk_doc.tokens  # List[str]

"""
Explanation: It contains a number of helper methods, too, which read (usually) from .word and return convenient data structures.
End of explanation
"""


from dataclasses import dataclass, field
from typing import List, Type
from boltons.cacheutils import cachedproperty
from cltk.core.data_types import Process

@dataclass
class StopsProcess(Process):
    """

    >>> from cltk.core.data_types import Doc, Word
    >>> from cltk.stops.processes import StopsProcess
    >>> from cltk.languages.example_texts import get_example_text
    >>> lang = "lat"
    >>> words = [Word(string=token) for token in split_punct_ws(get_example_text(lang))]
    >>> stops_process = StopsProcess(language=lang)
    >>> output_doc = stops_process.run(Doc(raw=get_example_text(lang), words=words))
    >>> output_doc.words[1].string
    'est'
    >>> output_doc.words[1].stop
    True
    """

    @cachedproperty
    def algorithm(self):
        return Stops(iso_code=self.language).get_stopwords()

    def run(self, input_doc: Doc) -> Doc:
        """Note this marks a word a stop if there is a match on
        either the inflected form (``Word.string``) or the
        lemma (``Word.lemma``).
        """
        output_doc = deepcopy(input_doc)
        stops_list = self.algorithm

        for index, word_obj in enumerate(output_doc.words):
            if (word_obj.string in stops_list) or (word_obj.lemma in stops_list):
                word_obj.stop = True
            else:
                word_obj.stop = False
            output_doc.words[index] = word_obj

        return output_doc

"""
Explanation: Process <a name="process"></a>
A Process is a Python class that wraps a particular algorithm type for a particular language (e.g., Sanskrit tokenization). It is designed to invoked by the Pipeline, though a user may call it directly, too.
See notebook Make custom Process and add to Pipeline for a demonstration.
End of explanation
"""


from cltk.core.data_types import Pipeline
from cltk.languages.utils import get_lang

@dataclass
class AkkadianPipeline(Pipeline):
    """Default ``Pipeline`` for Akkadian.

    >>> from cltk.languages.pipelines import AkkadianPipeline
    >>> a_pipeline = AkkadianPipeline()
    >>> a_pipeline.description
    'Pipeline for the Akkadian language.'
    >>> a_pipeline.language
    Language(name='Akkadian', glottolog_id='akka1240', latitude=33.1, longitude=44.1, dates=[], family_id='afro1255', parent_id='east2678', level='language', iso_639_3_code='akk', type='a')
    >>> a_pipeline.language.name
    'Akkadian'
    >>> a_pipeline.processes[0]
    <class 'cltk.tokenizers.processes.AkkadianTokenizationProcess'>
    """

    description: str = "Pipeline for the Akkadian language."
    language: Language = get_lang("akk")
    processes: List[Type[Process]] = field(
        default_factory=lambda: [AkkadianTokenizationProcess, StopsProcess]
    )

"""
Explanation: Pipeline <a name="pipeline"></a>
A Pipeline is a list containing the algorithms, in order, as they are to be invoked by NLP().
See notebook Make custom Process and add to Pipeline for a demonstration.
End of explanation
"""


from enum import auto
from cltk.morphology.universal_dependencies_features import Case, Gender, MorphosyntacticFeature, Number

# 'hercule' ('by Hercules, assuredly, indeed')
# http://www.perseus.tufts.edu/hopper/text?doc=Perseus:text:1999.04.0060:entry=hercule
gender = Gender.masculine
print("Gender:", gender)
case = Case.vocative
print("Case:", case)
number = Number.singular
print("Number", number)

type(case)

print("`MorphosyntacticFeature.name`:", case.name)
print("`MorphosyntacticFeature.value`", case.value)

# Example declaration
class Case(MorphosyntacticFeature):
    """The case of a noun phrase.
    see https://universaldependencies.org/u/feat/Case.html
    """

    # structural cases
    nominative = auto()
    accusative = auto()
    ergative = auto()
    absolutive = auto()

    # oblique cases
    abessive = auto()
    befefactive = auto()
    causative = auto()
    comparative = auto()
    considerative = auto()
    comitative = auto()
    dative = auto()
    distributive = auto()
    equative = auto()
    genitive = auto()
    instrumental = auto()
    partitive = auto()
    vocative = auto()

    # spatiotemporal cases
    ablative = auto()
    additive = auto()
    adessive = auto()
    allative = auto()
    delative = auto()
    elative = auto()
    essive = auto()
    illative = auto()
    inessive = auto()
    lative = auto()
    locative = auto()
    perlative = auto()
    sublative = auto()
    superessive = auto()
    terminative = auto()
    temporal = auto()
    translative = auto()

# Users can learn a bit about these features, too
#help(case)

"""
Explanation: MorphosyntacticFeature <a name="morpho"></a>
This model inherits from the Python builtin IntEnum. A MorphosyntacticFeature (at cltk/morphology/universal_dependencies_features.py) has been made for each morphsyntactic tag defined by v2 of the Universal Dependencies project.
End of explanation
"""


from cltk.morphology.universal_dependencies_features import POS

# so the Latin word 'hercule' would be
pos = POS.interjection
print(pos)

"""
Explanation: Note there is a distinction between POS and a word's features. POS tags are more general categories for general classes of words, like noun, verb, etc.
End of explanation
"""


from cltk.morphology.morphosyntax import MorphosyntacticFeatureBundle

bundle = MorphosyntacticFeatureBundle(case, gender, number)

print(type(bundle))

print(bundle)

# How to access features within a bundle
print("Gender", bundle["Gender"])
print("Case", bundle["Case"])
print("Number", bundle["Number"])

"""
Explanation: MorphosyntacticFeatureBundle <a name="morpho-bundle"></a>
MorphosyntacticFeatures are brought together to describe a word with MorphosyntacticFeatureBundle.
End of explanation
"""


Word(string="hercule", pos=pos, features=bundle)

"""
Explanation: POS and MorphosyntacticFeatureBundle are intended to be placed within a Wordinstance.
End of explanation
"""


from cltk.dependency.tree import Form

"""
Explanation: Form <a name="form"></a>
Since the Doc.words is a flat list of Word objects, it can be difficult to model hierearchical data, such as dependency trees. To help such modeling, the Form and DependencyTree types were created.
Form inherits from the builtin xml package's Element and DependencyTree from ElementTree.
See Modeling syntax with Form and DependencyTree for a full example.
End of explanation
"""


from cltk.dependency.tree import DependencyTree

"""
Explanation: DecisionTree <a name="dt"></a>
See Modeling syntax with Form and DependencyTree for a full example.
End of explanation
"""


