// morphology-got.el - Gothic morphology for the NLG engine.
//
// Implements Gothic verb conjugation and noun declension using standard
// Gothic Latin romanisation.  Designed as a companion to morphology.el and
// called by the engine when the language profile code is "got".
//
// Language profile: code=got, name=Gothic, morph_type=fusional,
//   word_order=SOV, question_strategy=intonation, script=gothic-latin,
//   family=germanic.
//
// Historical note: Gothic is attested primarily in the 4th-century Bible
// translation by Bishop Wulfila (Ulfilas).  It is the earliest substantially
// attested Germanic language and preserves many archaic features lost in later
// branches (e.g. distinct dual, mediopassive voice, four-case system).
//
// Romanisation conventions used in this file:
//   þ  — thorn (voiced/voiceless dental fricative; like "th" in "the/thin")
//   ƕ  — hwair  (Gothic hw-, like "wh" in older English "what")
//   q  — Gothic q (labiovelar stop, like "qu")
//   ei — long /iː/ (Gothic digraph)
//   ai — short /ɛ/ (Gothic digraph, not a diphthong)
//   au — short /ɔ/ (Gothic digraph, not a diphthong)
//   Standard vowels: a e i u (short)
//
// Verb conjugation covered:
//   Tenses:   present indicative active, past indicative active
//   Persons:  first/second/third × singular/plural
//   Classes:  weak class 1 (-jan verbs), weak class 2 (-on verbs) as
//             the regular productive paths
//   Irregulars: wisan (be), haban (have), gaggan (go), saihwan (see),
//               qiþan (say), niman (take)
//   Canonical map: "be" -> "wisan"
//
// Noun declension covered:
//   Cases:      nominative, accusative, genitive, dative  (all 4 Gothic cases)
//   Stem types: a-stem masc (paradigm: dags — day),
//               o-stem fem  (paradigm: gibo — gift),
//               n-stem masc (paradigm: guma — man)
//   Numbers:    singular, plural
//
// Demonstrative / article:
//   Gothic has no definite article proper.  The demonstrative pronoun
//   sa (masc) / so (fem) / þata (neut) functions as a near-definite
//   determiner.  got_noun_phrase prepends "sa" (masc) or "þo" (fem) when
//   definite=true.  Gender must be inferred from stem class: a-stem → masc,
//   o-stem → fem, n-stem → masc.
//
// Depends on: morphology.el (str_eq, str_len, str_slice, str_ends_with)

// ── String helpers ─────────────────────────────────────────────────────────────

import "morphology.el"
fn got_str_ends(s: String, suf: String) -> Bool {
    return str_ends_with(s, suf)
}

fn got_str_drop_last(s: String, n: Int) -> String {
    let len: Int = str_len(s)
    if n >= len {
        return ""
    }
    return str_slice(s, 0, len - n)
}

// ── Person/number slot ─────────────────────────────────────────────────────────
//
// Gothic has singular, dual, and plural.  The dual is historically attested
// for first and second person only (e.g. 1du wit, 2du jut) but is quite rare
// even in the Gothic corpus.  For NLG simplicity the dual is treated as plural.
//
//   0 = 1st singular
//   1 = 2nd singular
//   2 = 3rd singular
//   3 = 1st plural
//   4 = 2nd plural
//   5 = 3rd plural

fn got_slot(person: String, number: String) -> Int {
    if str_eq(person, "first") {
        if str_eq(number, "singular") { return 0 }
        return 3
    }
    if str_eq(person, "second") {
        if str_eq(number, "singular") { return 1 }
        return 4
    }
    // third person
    if str_eq(number, "singular") { return 2 }
    return 5
}

// ── Canonical verb mapping ─────────────────────────────────────────────────────
//
// English semantic-layer labels are mapped to Gothic dictionary forms before
// conjugation.  Dictionary forms are the infinitive.

fn got_map_canonical(verb: String) -> String {
    if str_eq(verb, "be")   { return "wisan" }
    if str_eq(verb, "have") { return "haban" }
    if str_eq(verb, "go")   { return "gaggan" }
    if str_eq(verb, "see")  { return "saihwan" }
    if str_eq(verb, "say")  { return "qiþan" }
    if str_eq(verb, "take") { return "niman" }
    if str_eq(verb, "come") { return "qiman" }
    if str_eq(verb, "give") { return "giban" }
    if str_eq(verb, "know") { return "kunnan" }
    if str_eq(verb, "want") { return "wiljan" }
    return verb
}

// ── Irregular verb: wisan (to be) ─────────────────────────────────────────────
//
// wisan is suppletive — the present is formed from im / is / ist / sijum…
// and the past from was / wast / was / wesum…
//
// Present indicative active:
//   1sg im     2sg is     3sg ist
//   1pl sijum  2pl sijuþ  3pl sind
//
// Past indicative active:
//   1sg was    2sg wast   3sg was
//   1pl wesum  2pl wesuþ  3pl wesun

fn got_wisan_present(slot: Int) -> String {
    if slot == 0 { return "im" }
    if slot == 1 { return "is" }
    if slot == 2 { return "ist" }
    if slot == 3 { return "sijum" }
    if slot == 4 { return "sijuþ" }
    return "sind"
}

fn got_wisan_past(slot: Int) -> String {
    if slot == 0 { return "was" }
    if slot == 1 { return "wast" }
    if slot == 2 { return "was" }
    if slot == 3 { return "wesum" }
    if slot == 4 { return "wesuþ" }
    return "wesun"
}

// ── Irregular verb: haban (to have) ───────────────────────────────────────────
//
// Weak class 3 (-an preterite-present type).
//
// Present:
//   1sg haba    2sg habais   3sg habaiþ
//   1pl habam   2pl habaiþ   3pl haband
//
// Past (habida series — weak past in -ida):
//   1sg habida  2sg habides  3sg habida
//   1pl habidum 2pl habideþ  3pl habidedun

fn got_haban_present(slot: Int) -> String {
    if slot == 0 { return "haba" }
    if slot == 1 { return "habais" }
    if slot == 2 { return "habaiþ" }
    if slot == 3 { return "habam" }
    if slot == 4 { return "habaiþ" }
    return "haband"
}

fn got_haban_past(slot: Int) -> String {
    if slot == 0 { return "habida" }
    if slot == 1 { return "habides" }
    if slot == 2 { return "habida" }
    if slot == 3 { return "habidum" }
    if slot == 4 { return "habideþ" }
    return "habidedun"
}

// ── Irregular verb: gaggan (to go) ────────────────────────────────────────────
//
// Strong class 7 (reduplicating); suppletive in past with iddja- forms.
//
// Present:
//   1sg gagga   2sg gaggis   3sg gaggiþ
//   1pl gagam   2pl gagiþ    3pl gaggand
//
// Past (iddja series — suppletive):
//   1sg iddja   2sg iddjēs   3sg iddja
//   1pl iddjēdum 2pl iddjēduþ 3pl iddjēdun

fn got_gaggan_present(slot: Int) -> String {
    if slot == 0 { return "gagga" }
    if slot == 1 { return "gaggis" }
    if slot == 2 { return "gaggiþ" }
    if slot == 3 { return "gagam" }
    if slot == 4 { return "gagiþ" }
    return "gaggand"
}

fn got_gaggan_past(slot: Int) -> String {
    if slot == 0 { return "iddja" }
    if slot == 1 { return "iddjēs" }
    if slot == 2 { return "iddja" }
    if slot == 3 { return "iddjēdum" }
    if slot == 4 { return "iddjēduþ" }
    return "iddjēdun"
}

// ── Irregular verb: saihwan (to see) ──────────────────────────────────────────
//
// Strong class 5 (saiƕan / saihwan).  Present stem saihw-; past stem sahw-.
//
// Present:
//   1sg saihwa   2sg saihwis   3sg saihwiþ
//   1pl saihwam  2pl saihwiþ   3pl saihwand
//
// Past (ablaut: ai→a, strong past):
//   1sg sahw     2sg sahwt     3sg sahw
//   1pl sehwum   2pl sehwuþ   3pl sehwun

fn got_saihwan_present(slot: Int) -> String {
    if slot == 0 { return "saihwa" }
    if slot == 1 { return "saihwis" }
    if slot == 2 { return "saihwiþ" }
    if slot == 3 { return "saihwam" }
    if slot == 4 { return "saihwiþ" }
    return "saihwand"
}

fn got_saihwan_past(slot: Int) -> String {
    if slot == 0 { return "sahw" }
    if slot == 1 { return "sahwt" }
    if slot == 2 { return "sahw" }
    if slot == 3 { return "sehwum" }
    if slot == 4 { return "sehwuþ" }
    return "sehwun"
}

// ── Irregular verb: qiþan (to say) ────────────────────────────────────────────
//
// Strong class 5 (i-ablaut).  Present stem qiþ-; past stem qaþ-.
//
// Present:
//   1sg qiþa    2sg qiþis    3sg qiþiþ
//   1pl qiþam   2pl qiþiþ    3pl qiþand
//
// Past (ablaut: i→a):
//   1sg qaþ     2sg qast     3sg qaþ
//   1pl qēþum   2pl qēþuþ    3pl qēþun

fn got_qithan_present(slot: Int) -> String {
    if slot == 0 { return "qiþa" }
    if slot == 1 { return "qiþis" }
    if slot == 2 { return "qiþiþ" }
    if slot == 3 { return "qiþam" }
    if slot == 4 { return "qiþiþ" }
    return "qiþand"
}

fn got_qithan_past(slot: Int) -> String {
    if slot == 0 { return "qaþ" }
    if slot == 1 { return "qast" }
    if slot == 2 { return "qaþ" }
    if slot == 3 { return "qēþum" }
    if slot == 4 { return "qēþuþ" }
    return "qēþun"
}

// ── Irregular verb: niman (to take) ───────────────────────────────────────────
//
// Strong class 4 (sonorant stem; i-ablaut in present, a-ablaut in past).
//
// Present:
//   1sg nima    2sg nimis    3sg nimiþ
//   1pl nimam   2pl nimiþ    3pl nimand
//
// Past (ablaut: i→a):
//   1sg nam     2sg namt     3sg nam
//   1pl nēmum   2pl nēmuþ    3pl nēmun

fn got_niman_present(slot: Int) -> String {
    if slot == 0 { return "nima" }
    if slot == 1 { return "nimis" }
    if slot == 2 { return "nimiþ" }
    if slot == 3 { return "nimam" }
    if slot == 4 { return "nimiþ" }
    return "nimand"
}

fn got_niman_past(slot: Int) -> String {
    if slot == 0 { return "nam" }
    if slot == 1 { return "namt" }
    if slot == 2 { return "nam" }
    if slot == 3 { return "nēmum" }
    if slot == 4 { return "nēmuþ" }
    return "nēmun"
}

// ── Weak class 1 (-jan verbs): regular conjugation ────────────────────────────
//
// Class 1 weak verbs are the most productive Gothic verb class.  The
// infinitive ends in -jan; the stem is obtained by stripping -jan.
//
// Present indicative active:
//   1sg  stem + -a      (nasjan  -> nasja)
//   2sg  stem + -is     (nasjis)
//   3sg  stem + -iþ     (nasjiþ)
//   1pl  stem + -jam    (nasjam)
//   2pl  stem + -jiþ    (nasjiþ)
//   3pl  stem + -jand   (nasjand)
//
// Past indicative active (weak past -ida):
//   1sg  stem + -ida    (nasjida)
//   2sg  stem + -ides   (nasjides)
//   3sg  stem + -ida    (nasjida)
//   1pl  stem + -idum   (nasjidum)
//   2pl  stem + -ideþ   (nasjideþ)
//   3pl  stem + -idedun (nasjidedun)

fn got_wk1_present_ending(slot: Int) -> String {
    if slot == 0 { return "a" }
    if slot == 1 { return "is" }
    if slot == 2 { return "iþ" }
    if slot == 3 { return "jam" }
    if slot == 4 { return "jiþ" }
    return "jand"
}

fn got_wk1_past_ending(slot: Int) -> String {
    if slot == 0 { return "ida" }
    if slot == 1 { return "ides" }
    if slot == 2 { return "ida" }
    if slot == 3 { return "idum" }
    if slot == 4 { return "ideþ" }
    return "idedun"
}

fn got_wk1_conjugate(stem: String, tense: String, slot: Int) -> String {
    if str_eq(tense, "present") {
        return stem + got_wk1_present_ending(slot)
    }
    if str_eq(tense, "past") {
        return stem + got_wk1_past_ending(slot)
    }
    return stem
}

// ── Weak class 2 (-on verbs): regular conjugation ─────────────────────────────
//
// Class 2 weak verbs.  Infinitive ends in -on; stem = drop -on.
// This class corresponds roughly to OE -ian / OHG -on denominatives.
//
// Present indicative active:
//   1sg  stem + -o      (salbon  -> salbo)
//   2sg  stem + -os     (salbos)
//   3sg  stem + -oþ     (salboþ)
//   1pl  stem + -om     (salbom)
//   2pl  stem + -oþ     (salboþ)
//   3pl  stem + -ond    (salbond)
//
// Past indicative active (weak past -oda):
//   1sg  stem + -oda    (salboda)
//   2sg  stem + -odes   (salbodes)
//   3sg  stem + -oda    (salboda)
//   1pl  stem + -odum   (salbodum)
//   2pl  stem + -odeþ   (salbodeþ)
//   3pl  stem + -odedun (salbodedun)

fn got_wk2_present_ending(slot: Int) -> String {
    if slot == 0 { return "o" }
    if slot == 1 { return "os" }
    if slot == 2 { return "oþ" }
    if slot == 3 { return "om" }
    if slot == 4 { return "oþ" }
    return "ond"
}

fn got_wk2_past_ending(slot: Int) -> String {
    if slot == 0 { return "oda" }
    if slot == 1 { return "odes" }
    if slot == 2 { return "oda" }
    if slot == 3 { return "odum" }
    if slot == 4 { return "odeþ" }
    return "odedun"
}

fn got_wk2_conjugate(stem: String, tense: String, slot: Int) -> String {
    if str_eq(tense, "present") {
        return stem + got_wk2_present_ending(slot)
    }
    if str_eq(tense, "past") {
        return stem + got_wk2_past_ending(slot)
    }
    return stem
}

// ── Infinitive class detection ─────────────────────────────────────────────────
//
// Identifies the verb class from the infinitive ending so that the correct
// regular paradigm can be applied for verbs not in the irregular table.
//
//   ends in -jan  -> weak class 1  ("wk1")
//   ends in -on   -> weak class 2  ("wk2")
//   otherwise     -> default to weak class 1 (most productive class)

fn got_verb_class(verb: String) -> String {
    if got_str_ends(verb, "jan") { return "wk1" }
    if got_str_ends(verb, "on")  { return "wk2" }
    return "wk1"
}

// got_verb_stem: strip the infinitive suffix to expose the productive stem.
//
// wk1: strip -jan (3 bytes — all ASCII)
// wk2: strip -on  (2 bytes)

fn got_verb_stem(verb: String, vclass: String) -> String {
    if str_eq(vclass, "wk1") { return got_str_drop_last(verb, 3) }
    if str_eq(vclass, "wk2") { return got_str_drop_last(verb, 2) }
    return got_str_drop_last(verb, 2)
}

// ── got_conjugate: main conjugation entry point ───────────────────────────────
//
// verb:   Gothic infinitive in Latin romanisation (e.g. "wisan", "nasjan")
//         or English canonical label ("be", "go", "have")
// tense:  "present" | "past"
// person: "first" | "second" | "third"
// number: "singular" | "plural" (or "dual" — treated as plural)
//
// Returns the inflected form.  Falls back to the infinitive for unknown
// tenses rather than crashing.

fn got_conjugate(verb: String, tense: String, person: String, number: String) -> String {
    let v: String = got_map_canonical(verb)
    let slot: Int = got_slot(person, number)

    // ── Irregular: wisan (to be) ──────────────────────────────────────────────
    if str_eq(v, "wisan") {
        if str_eq(tense, "present") { return got_wisan_present(slot) }
        if str_eq(tense, "past")    { return got_wisan_past(slot) }
        return v
    }

    // ── Irregular: haban (to have) ────────────────────────────────────────────
    if str_eq(v, "haban") {
        if str_eq(tense, "present") { return got_haban_present(slot) }
        if str_eq(tense, "past")    { return got_haban_past(slot) }
        return v
    }

    // ── Irregular: gaggan (to go) ─────────────────────────────────────────────
    if str_eq(v, "gaggan") {
        if str_eq(tense, "present") { return got_gaggan_present(slot) }
        if str_eq(tense, "past")    { return got_gaggan_past(slot) }
        return v
    }

    // ── Irregular: saihwan (to see) ───────────────────────────────────────────
    if str_eq(v, "saihwan") {
        if str_eq(tense, "present") { return got_saihwan_present(slot) }
        if str_eq(tense, "past")    { return got_saihwan_past(slot) }
        return v
    }

    // ── Irregular: qiþan (to say) ─────────────────────────────────────────────
    if str_eq(v, "qiþan") {
        if str_eq(tense, "present") { return got_qithan_present(slot) }
        if str_eq(tense, "past")    { return got_qithan_past(slot) }
        return v
    }

    // ── Irregular: niman (to take) ────────────────────────────────────────────
    if str_eq(v, "niman") {
        if str_eq(tense, "present") { return got_niman_present(slot) }
        if str_eq(tense, "past")    { return got_niman_past(slot) }
        return v
    }

    // ── Regular weak conjugation ──────────────────────────────────────────────
    let vclass: String = got_verb_class(v)
    let stem: String = got_verb_stem(v, vclass)

    if str_eq(vclass, "wk1") {
        return got_wk1_conjugate(stem, tense, slot)
    }
    if str_eq(vclass, "wk2") {
        return got_wk2_conjugate(stem, tense, slot)
    }

    // Final fallback: return the infinitive
    return v
}

// ── a-stem masculine paradigm (dags — day) ────────────────────────────────────
//
// The a-stem masculine is the largest Gothic noun class, corresponding to the
// Proto-Germanic *-a- stems (OE -as, German -e plurals).
//
// Nominative singular: dags
// Stem: dag- (strip final -s from nom sg)
//
// Singular:  nom dags   acc dag    gen dagis  dat daga
// Plural:    nom dagos  acc dagans gen dage   dat dagam
//
// Note: some sources list acc sg as "dag" (without -n), consistent with
// Gothic nom≠acc distinction in masculine a-stems.

fn got_decline_a_stem_sg(stem: String, gram_case: String) -> String {
    if str_eq(gram_case, "nominative") { return stem + "s" }
    if str_eq(gram_case, "accusative") { return stem }
    if str_eq(gram_case, "genitive")   { return stem + "is" }
    if str_eq(gram_case, "dative")     { return stem + "a" }
    return stem + "s"
}

fn got_decline_a_stem_pl(stem: String, gram_case: String) -> String {
    if str_eq(gram_case, "nominative") { return stem + "os" }
    if str_eq(gram_case, "accusative") { return stem + "ans" }
    if str_eq(gram_case, "genitive")   { return stem + "e" }
    if str_eq(gram_case, "dative")     { return stem + "am" }
    return stem + "os"
}

// ── o-stem feminine paradigm (gibo — gift) ────────────────────────────────────
//
// The o-stem feminines correspond to Proto-Germanic *-ō- stems.  The
// nominative singular ends in -o; nom and acc plural are identical.
//
// Singular:  nom gibo   acc giba   gen gibos  dat gibai
// Plural:    nom gibos  acc gibos  gen gibo   dat gibom

fn got_decline_o_stem_sg(stem: String, gram_case: String) -> String {
    if str_eq(gram_case, "nominative") { return stem + "o" }
    if str_eq(gram_case, "accusative") { return stem + "a" }
    if str_eq(gram_case, "genitive")   { return stem + "os" }
    if str_eq(gram_case, "dative")     { return stem + "ai" }
    return stem + "o"
}

fn got_decline_o_stem_pl(stem: String, gram_case: String) -> String {
    if str_eq(gram_case, "nominative") { return stem + "os" }
    if str_eq(gram_case, "accusative") { return stem + "os" }
    if str_eq(gram_case, "genitive")   { return stem + "o" }
    if str_eq(gram_case, "dative")     { return stem + "om" }
    return stem + "os"
}

// ── n-stem masculine paradigm (guma — man) ────────────────────────────────────
//
// The n-stems (weak nouns) are characterised by -n- appearing in all cases
// except the nominative singular.  They are sometimes called "weak nouns"
// by analogy with Old English grammar.
//
// Singular:  nom guma   acc guman  gen gumins  dat gumin
// Plural:    nom gumans acc gumans gen gumane  dat gumam

fn got_decline_n_stem_sg(stem: String, gram_case: String) -> String {
    if str_eq(gram_case, "nominative") { return stem + "a" }
    if str_eq(gram_case, "accusative") { return stem + "an" }
    if str_eq(gram_case, "genitive")   { return stem + "ins" }
    if str_eq(gram_case, "dative")     { return stem + "in" }
    return stem + "a"
}

fn got_decline_n_stem_pl(stem: String, gram_case: String) -> String {
    if str_eq(gram_case, "nominative") { return stem + "ans" }
    if str_eq(gram_case, "accusative") { return stem + "ans" }
    if str_eq(gram_case, "genitive")   { return stem + "ane" }
    if str_eq(gram_case, "dative")     { return stem + "am" }
    return stem + "ans"
}

// ── Stem type detection ────────────────────────────────────────────────────────
//
// Infers the stem class from the nominative singular form.
//
// Strategy:
//   ends in -s and previous char is not a vowel  -> a-stem masc (dags type)
//   ends in -o  -> o-stem fem (gibo type)
//   ends in -a  -> n-stem masc (guma type)
//   ends in -s and previous char is a vowel       -> could be various; default a-stem
//   otherwise   -> default to a-stem
//
// For the common case where the caller passes the paradigm lemma directly:
//   "dags" -> "a", "gibo" -> "o", "guma" -> "n"

fn got_stem_type(noun: String) -> String {
    if got_str_ends(noun, "o") { return "o" }
    if got_str_ends(noun, "a") { return "n" }
    if got_str_ends(noun, "s") { return "a" }
    // Fallback for other forms
    return "a"
}

// got_extract_stem: strip the nom-sg suffix to obtain the bare stem.
//
// a-stem: strip final -s  (dags -> dag)
// o-stem: strip final -o  (gibo -> gib)
// n-stem: strip final -a  (guma -> gum)
//
// All suffix bytes are single-byte ASCII, so str_len gives byte=char counts.

fn got_extract_stem(noun: String, stype: String) -> String {
    let n: Int = str_len(noun)
    // All three suffixes are 1 byte each
    return str_slice(noun, 0, n - 1)
}

// ── Gender inference for article selection ─────────────────────────────────────
//
// The demonstrative-article used in got_noun_phrase depends on gender.
// Gender correlates with stem class in Gothic (imperfect but useful heuristic):
//   a-stem -> masculine -> sa
//   o-stem -> feminine  -> þo  (nom sg of feminine demonstrative)
//   n-stem -> masculine -> sa
//
// Neuter a-stems (like "waurd" — word) exist but are not distinguished here;
// the NLG layer is expected to pass explicit gender when the distinction matters.

fn got_demo_article(stype: String) -> String {
    if str_eq(stype, "o") { return "þo" }
    // a-stem and n-stem both masculine
    return "sa"
}

// ── got_decline: main declension entry point ──────────────────────────────────
//
// noun:      nominative singular in Gothic Latin romanisation
//            (e.g. "dags", "gibo", "guma")
// gram_case: "nominative" | "accusative" | "genitive" | "dative"
// number:    "singular" | "plural"
//
// Returns the inflected form.  Unknown stem types return the nominative
// singular unchanged rather than producing garbage output.

fn got_decline(noun: String, gram_case: String, number: String) -> String {
    let stype: String = got_stem_type(noun)
    let stem: String = got_extract_stem(noun, stype)

    if str_eq(stype, "a") {
        if str_eq(number, "singular") { return got_decline_a_stem_sg(stem, gram_case) }
        return got_decline_a_stem_pl(stem, gram_case)
    }

    if str_eq(stype, "o") {
        if str_eq(number, "singular") { return got_decline_o_stem_sg(stem, gram_case) }
        return got_decline_o_stem_pl(stem, gram_case)
    }

    if str_eq(stype, "n") {
        if str_eq(number, "singular") { return got_decline_n_stem_sg(stem, gram_case) }
        return got_decline_n_stem_pl(stem, gram_case)
    }

    // Unknown: return the nominative singular unchanged
    return noun
}

// ── got_noun_phrase: noun phrase builder ──────────────────────────────────────
//
// Gothic has no definite article.  The demonstrative pronouns sa (masc) /
// so (fem) / þata (neut) are used in contexts where a definite-article-like
// meaning is required (closely following Greek ὁ/ἡ/τό in Wulfila's translation).
//
// When definite=true this function prepends the gender-appropriate demonstrative
// in its nominative singular form.  For non-nominative cases the demonstrative
// should ideally be declined to match; this implementation prepends the nom-sg
// form as a simplification suitable for NLG output.  Callers requiring full
// demonstrative agreement should call got_decline_demonstrative separately.
//
// noun:      nominative singular Gothic noun
// gram_case: "nominative" | "accusative" | "genitive" | "dative"
// number:    "singular" | "plural"
// definite:  "true" prepends the demonstrative; any other value omits it

fn got_noun_phrase(noun: String, gram_case: String, number: String, definite: String) -> String {
    let declined: String = got_decline(noun, gram_case, number)

    if str_eq(definite, "true") {
        let stype: String = got_stem_type(noun)
        let article: String = got_demo_article(stype)
        return article + " " + declined
    }

    return declined
}
