module OnlineConlang.Constants.Consonants

open OnlineConlang.Foundation

type MannerArticulation = Nasal
                        | Plosive
                        | SibilantAffricate
                        | NonSibilantAffricate
                        | SibilantFricative
                        | NonSibilantFricative
                        | Approximant
                        | Tap
                        | Trill
                        | LateralAffricate
                        | LateralFricative
                        | LateralApproximant
                        | LateralTap

type Voicedness = Unvoiced | Voiced

type PlaceArticulation = Bilabial
                       | Labiodental
                       | Linguolabial
                       | Dental
                       | Alveolar
                       | Postalveolar
                       | Retroflex
                       | Palatal
                       | Velar
                       | Uvular
                       | Pharyngeal
                       | Glottal

type MannerArticulationClick = TenuisNonLateral
                             | VoicedNonLateral
                             | NasalNonLateral
                             | TenuisLateral
                             | VoicedLateral
                             | NasalLateral

type PulmonicConsonant =
    | BasicConsonant of PlaceArticulation * MannerArticulation * Voicedness * string
    | CoArtConsonant of PlaceArticulation * PlaceArticulation * MannerArticulation * Voicedness * string
    member this.IPASymbol = (this :> IIPARepresentable).IPASymbol
    interface IIPARepresentable with
        member this.IPASymbol =
            match this with
            | BasicConsonant (_, _, _, s) -> s
            | CoArtConsonant (_, _, _, _, s) -> s

type EjectiveConsonant =
    | EjectiveConsonant of PlaceArticulation * MannerArticulation * string
    member this.IPASymbol = (this :> IIPARepresentable).IPASymbol
    interface IIPARepresentable with
        member this.IPASymbol =
            match this with
            | EjectiveConsonant (_, _, s) -> s

type ClickConsonant =
    | ClickConsonant of PlaceArticulation * PlaceArticulation * MannerArticulationClick * string
    member this.IPASymbol = (this :> IIPARepresentable).IPASymbol
    interface IIPARepresentable with
        member this.IPASymbol =
            match this with
            | ClickConsonant (_, _, _, s) -> s

type ImplosiveConsonant =
    | ImplosiveConsonant of PlaceArticulation * Voicedness * string
    member this.IPASymbol = (this :> IIPARepresentable).IPASymbol
    interface IIPARepresentable with
        member this.IPASymbol =
            match this with
            | ImplosiveConsonant (_, _, s) -> s

type Consonant =
    | Pulmonic of PulmonicConsonant
    | Ejective of EjectiveConsonant
    | Click of ClickConsonant
    | Implosive of ImplosiveConsonant
    member this.IPASymbol = (this :> IIPARepresentable).IPASymbol
    interface IIPARepresentable with
        member this.IPASymbol =
            match this with
            | Pulmonic  c -> c.IPASymbol
            | Ejective  c -> c.IPASymbol
            | Click     c -> c.IPASymbol
            | Implosive c -> c.IPASymbol

let pulmonicConsonants = Set.ofList [
    BasicConsonant (Bilabial, Nasal, Unvoiced, "mÃ•")
    BasicConsonant (Bilabial, Nasal, Voiced, "m")
    BasicConsonant (Labiodental, Nasal, Voiced, "…±")
    BasicConsonant (Linguolabial, Nasal, Voiced, "nÃº")
    BasicConsonant (Alveolar, Nasal, Unvoiced, "nÃ•")
    BasicConsonant (Alveolar, Nasal, Voiced, "n")
    BasicConsonant (Retroflex, Nasal, Unvoiced, "…≥Ãä")
    BasicConsonant (Retroflex, Nasal, Voiced, "…≥")
    BasicConsonant (Palatal, Nasal, Unvoiced, "…≤Ãä")
    BasicConsonant (Palatal, Nasal, Voiced, "…≤")
    BasicConsonant (Velar, Nasal, Unvoiced, "≈ãÃä")
    BasicConsonant (Velar, Nasal, Voiced, "≈ã")
    BasicConsonant (Uvular, Nasal, Voiced, "…¥")

    BasicConsonant (Bilabial, Plosive, Unvoiced, "p")
    BasicConsonant (Bilabial, Plosive, Voiced, "b")
    BasicConsonant (Labiodental, Plosive, Unvoiced, "pÃ™")
    BasicConsonant (Labiodental, Plosive, Voiced, "bÃ™")
    BasicConsonant (Linguolabial, Plosive, Unvoiced, "tÃº")
    BasicConsonant (Linguolabial, Plosive, Voiced, "dÃº")
    BasicConsonant (Alveolar, Plosive, Unvoiced, "t")
    BasicConsonant (Alveolar, Plosive, Voiced, "d")
    BasicConsonant (Retroflex, Plosive, Unvoiced, " à")
    BasicConsonant (Retroflex, Plosive, Voiced, "…ñ")
    BasicConsonant (Palatal, Plosive, Unvoiced, "c")
    BasicConsonant (Palatal, Plosive, Voiced, "…ü")
    BasicConsonant (Velar, Plosive, Unvoiced, "k")
    BasicConsonant (Velar, Plosive, Voiced, "…°")
    BasicConsonant (Uvular, Plosive, Unvoiced, "q")
    BasicConsonant (Uvular, Plosive, Voiced, "…¢")
    BasicConsonant (Pharyngeal, Plosive, Unvoiced, " °")
    BasicConsonant (Glottal, Plosive, Unvoiced, " î")

    BasicConsonant (Alveolar, SibilantAffricate, Unvoiced, "tÕ°s")
    BasicConsonant (Alveolar, SibilantAffricate, Voiced, "dÕ°z")
    BasicConsonant (Postalveolar, SibilantAffricate, Unvoiced, "tÃ†Õ° É")
    BasicConsonant (Postalveolar, SibilantAffricate, Voiced, "dÃ†Õ° í")
    BasicConsonant (Retroflex, SibilantAffricate, Unvoiced, "tÕ° Ç")
    BasicConsonant (Retroflex, SibilantAffricate, Voiced, "dÕ° ê")
    BasicConsonant (Palatal, SibilantAffricate, Unvoiced, "tÕ°…ï")
    BasicConsonant (Palatal, SibilantAffricate, Voiced, "dÕ° ë")

    BasicConsonant (Bilabial, NonSibilantAffricate, Unvoiced, "pÕ°…∏")
    BasicConsonant (Bilabial, NonSibilantAffricate, Voiced, "bÕ°Œ≤")
    BasicConsonant (Labiodental, NonSibilantAffricate, Unvoiced, "pÃ™Õ°f")
    BasicConsonant (Labiodental, NonSibilantAffricate, Voiced, "bÃ™Õ°v")
    BasicConsonant (Dental, NonSibilantAffricate, Unvoiced, "tÃ™Õ°Œ∏")
    BasicConsonant (Dental, NonSibilantAffricate, Voiced, "dÃ™Õ°√∞")
    BasicConsonant (Alveolar, NonSibilantAffricate, Unvoiced, "tÕ°…πÃùÃä")
    BasicConsonant (Alveolar, NonSibilantAffricate, Voiced, "dÕ°…πÃù")
    BasicConsonant (Postalveolar, NonSibilantAffricate, Unvoiced, "tÃ†Õ°…πÃ†ÃäÀî")
    BasicConsonant (Postalveolar, NonSibilantAffricate, Voiced, "dÃ†Õ°…πÃ†Àî")
    BasicConsonant (Palatal, NonSibilantAffricate, Unvoiced, "cÕ°√ß")
    BasicConsonant (Palatal, NonSibilantAffricate, Voiced, "…üÕ° ù")
    BasicConsonant (Velar, NonSibilantAffricate, Unvoiced, "kÕ°x")
    BasicConsonant (Velar, NonSibilantAffricate, Voiced, "…°Õ°…£")
    BasicConsonant (Uvular, NonSibilantAffricate, Unvoiced, "qÕ°œá")
    BasicConsonant (Uvular, NonSibilantAffricate, Voiced, "…¢Õ° Å")
    BasicConsonant (Pharyngeal, NonSibilantAffricate, Unvoiced, " °Õ° ú")
    BasicConsonant (Pharyngeal, NonSibilantAffricate, Voiced, " °Õ° ¢")
    BasicConsonant (Glottal, NonSibilantAffricate, Unvoiced, " îÕ°h")

    BasicConsonant (Alveolar, SibilantFricative, Unvoiced, "s")
    BasicConsonant (Alveolar, SibilantFricative, Voiced, "z")
    BasicConsonant (Postalveolar, SibilantFricative, Unvoiced, " É")
    BasicConsonant (Postalveolar, SibilantFricative, Voiced, " í")
    BasicConsonant (Retroflex, SibilantFricative, Unvoiced, " Ç")
    BasicConsonant (Retroflex, SibilantFricative, Voiced, " ê")
    BasicConsonant (Palatal, SibilantFricative, Unvoiced, "…ï")
    BasicConsonant (Palatal, SibilantFricative, Voiced, " ë")

    BasicConsonant (Bilabial, NonSibilantFricative, Unvoiced, "…∏")
    BasicConsonant (Bilabial, NonSibilantFricative, Voiced, "Œ≤")
    BasicConsonant (Labiodental, NonSibilantFricative, Unvoiced, "f")
    BasicConsonant (Labiodental, NonSibilantFricative, Voiced, "v")
    BasicConsonant (Linguolabial, NonSibilantFricative, Unvoiced, "Œ∏Ãº")
    BasicConsonant (Linguolabial, NonSibilantFricative, Voiced, "√∞Ãº")
    BasicConsonant (Dental, NonSibilantFricative, Unvoiced, "Œ∏")
    BasicConsonant (Dental, NonSibilantFricative, Voiced, "√∞")
    BasicConsonant (Alveolar, NonSibilantFricative, Unvoiced, "Œ∏Ã†")
    BasicConsonant (Alveolar, NonSibilantFricative, Voiced, "√∞Ã†")
    BasicConsonant (Postalveolar, NonSibilantFricative, Unvoiced, "…πÃ†ÃäÀî")
    BasicConsonant (Postalveolar, NonSibilantFricative, Voiced, "…πÃ†Àî")
    BasicConsonant (Retroflex, NonSibilantFricative, Unvoiced, "…ªÃäÀî")
    BasicConsonant (Retroflex, NonSibilantFricative, Voiced, "…ªÀî")
    BasicConsonant (Palatal, NonSibilantFricative, Unvoiced, "√ß")
    BasicConsonant (Palatal, NonSibilantFricative, Voiced, " ù")
    BasicConsonant (Velar, NonSibilantFricative, Unvoiced, "x")
    BasicConsonant (Velar, NonSibilantFricative, Voiced, "…£")
    BasicConsonant (Uvular, NonSibilantFricative, Unvoiced, "œá")
    BasicConsonant (Uvular, NonSibilantFricative, Voiced, " Å")
    BasicConsonant (Pharyngeal, NonSibilantFricative, Unvoiced, "ƒß")
    BasicConsonant (Pharyngeal, NonSibilantFricative, Voiced, " ï")
    BasicConsonant (Glottal, NonSibilantFricative, Unvoiced, "h")
    BasicConsonant (Glottal, NonSibilantFricative, Voiced, "…¶")

    BasicConsonant (Labiodental, Approximant, Voiced, " ã")
    BasicConsonant (Alveolar, Approximant, Voiced, "…π")
    BasicConsonant (Retroflex, Approximant, Voiced, "…ª")
    BasicConsonant (Palatal, Approximant, Voiced, "j")
    BasicConsonant (Velar, Approximant, Voiced, "…∞")
    BasicConsonant (Glottal, Approximant, Voiced, " îÃû")

    BasicConsonant (Bilabial, Tap, Voiced, "‚±±Ãü")
    BasicConsonant (Labiodental, Tap, Voiced, "‚±±")
    BasicConsonant (Linguolabial, Tap, Voiced, "…æÃº")
    BasicConsonant (Alveolar, Tap, Unvoiced, "…æÃ•")
    BasicConsonant (Alveolar, Tap, Voiced, "…æ")
    BasicConsonant (Retroflex, Tap, Unvoiced, "…ΩÃä")
    BasicConsonant (Retroflex, Tap, Voiced, "…Ω")
    BasicConsonant (Velar, Tap, Voiced, "…°ÃÜ")
    BasicConsonant (Uvular, Tap, Voiced, "…¢ÃÜ")
    BasicConsonant (Pharyngeal, Tap, Voiced, " °ÃÜ")

    BasicConsonant (Bilabial, Trill, Unvoiced, " ôÃ•")
    BasicConsonant (Bilabial, Trill, Voiced, " ô")
    BasicConsonant (Alveolar, Trill, Unvoiced, "rÃ•")
    BasicConsonant (Alveolar, Trill, Voiced, "r")
    BasicConsonant (Retroflex, Trill, Unvoiced, "…ΩÃärÃ•")
    BasicConsonant (Retroflex, Trill, Voiced, "…Ωr")
    BasicConsonant (Uvular, Trill, Unvoiced, " ÄÃ•")
    BasicConsonant (Uvular, Trill, Voiced, " Ä")
    BasicConsonant (Pharyngeal, Trill, Unvoiced, " ú")
    BasicConsonant (Pharyngeal, Trill, Voiced, " ¢")

    BasicConsonant (Alveolar, LateralAffricate, Unvoiced, "tÕ°…¨")
    BasicConsonant (Alveolar, LateralAffricate, Voiced, "dÕ°…Æ")
    BasicConsonant (Retroflex, LateralAffricate, Unvoiced, "tÕ°Íûé")
    BasicConsonant (Retroflex, LateralAffricate, Voiced, "dÕ°…≠Àî")
    BasicConsonant (Palatal, LateralAffricate, Unvoiced, "cÕ° éÃùÃä")
    BasicConsonant (Palatal, LateralAffricate, Voiced, "…üÕ° éÃù")
    BasicConsonant (Velar, LateralAffricate, Unvoiced, "kÕ°ùºÑ")
    BasicConsonant (Velar, LateralAffricate, Voiced, "…°Õ° üÃù")

    BasicConsonant (Alveolar, LateralFricative, Unvoiced, "…¨")
    BasicConsonant (Alveolar, LateralFricative, Voiced, "…Æ")
    BasicConsonant (Retroflex, LateralFricative, Unvoiced, "Íûé")
    BasicConsonant (Retroflex, LateralFricative, Voiced, "…≠Àî")
    BasicConsonant (Palatal, LateralFricative, Unvoiced, " éÃùÃä")
    BasicConsonant (Palatal, LateralFricative, Voiced, " éÃù")
    BasicConsonant (Velar, LateralFricative, Unvoiced, "ùºÑ")
    BasicConsonant (Velar, LateralFricative, Voiced, " üÃù")

    BasicConsonant (Alveolar, LateralApproximant, Voiced, "l")
    BasicConsonant (Retroflex, LateralApproximant, Voiced, "…≠")
    BasicConsonant (Palatal, LateralApproximant, Voiced, " é")
    BasicConsonant (Velar, LateralApproximant, Voiced, " ü")
    BasicConsonant (Uvular, LateralApproximant, Voiced, " üÃ†")

    BasicConsonant (Alveolar, LateralTap, Unvoiced, "…∫Ã•")
    BasicConsonant (Alveolar, LateralTap, Voiced, "…∫")
    BasicConsonant (Retroflex, LateralTap, Unvoiced, "…≠Ã•ÃÜ")
    BasicConsonant (Retroflex, LateralTap, Voiced, "…≠ÃÜ")
    BasicConsonant (Palatal, LateralTap, Voiced, " éÃÜ")
    BasicConsonant (Velar, LateralTap, Voiced, " üÃÜ")

    CoArtConsonant (Bilabial, Alveolar, Nasal, Voiced, "nÕ°m")
    CoArtConsonant (Bilabial, Velar, Nasal, Voiced, "≈ãÕ°m")
    CoArtConsonant (Bilabial, Alveolar, Plosive, Unvoiced, "tÕ°p")
    CoArtConsonant (Bilabial, Alveolar, Plosive, Voiced, "dÕ°b")
    CoArtConsonant (Bilabial, Velar, Plosive, Unvoiced, "kÕ°p")
    CoArtConsonant (Bilabial, Velar, Plosive, Voiced, "gÕ°b")
    CoArtConsonant (Uvular, Pharyngeal, Plosive, Unvoiced, "qÕ° °")

    CoArtConsonant (Bilabial, Palatal, Approximant, Unvoiced, "…•Ãä")
    CoArtConsonant (Bilabial, Palatal, Approximant, Voiced, "…•")
    CoArtConsonant (Bilabial, Velar, Approximant, Unvoiced, " ç")
    CoArtConsonant (Bilabial, Velar, Approximant, Voiced, "w")

    CoArtConsonant (Labiodental, Velar, NonSibilantFricative, Unvoiced, "…ß")
    CoArtConsonant (Alveolar, Velar, LateralApproximant, Voiced, "…´")
    ]

let ejectiveConsonants = Set.ofList [
    EjectiveConsonant (Bilabial, Plosive, "p º")
    EjectiveConsonant (Alveolar, Plosive, "t º")
    EjectiveConsonant (Retroflex, Plosive, " à º")
    EjectiveConsonant (Palatal, Plosive, "c º")
    EjectiveConsonant (Velar, Plosive, "k º")
    EjectiveConsonant (Uvular, Plosive, "q º")
    EjectiveConsonant (Pharyngeal, Plosive, " ° º")

    EjectiveConsonant (Alveolar, SibilantAffricate, "tÕ°s º")
    EjectiveConsonant (Postalveolar, SibilantAffricate, "tÃ†Õ° É º")
    EjectiveConsonant (Retroflex, SibilantAffricate, "tÕ° Ç º")

    EjectiveConsonant (Dental, NonSibilantAffricate, "tÃ™Õ°Œ∏ º")
    EjectiveConsonant (Velar, NonSibilantAffricate, "kÕ°x º")
    EjectiveConsonant (Uvular, NonSibilantAffricate, "qÕ°œá º")

    EjectiveConsonant (Alveolar, SibilantFricative, "s º")
    EjectiveConsonant (Postalveolar, SibilantFricative, " É º")
    EjectiveConsonant (Retroflex, SibilantFricative, " Ç º")
    EjectiveConsonant (Palatal, SibilantFricative, "…ï º")

    EjectiveConsonant (Bilabial, NonSibilantFricative, "…∏ º")
    EjectiveConsonant (Labiodental, NonSibilantFricative, "f º")
    EjectiveConsonant (Dental, NonSibilantFricative, "Œ∏ º")
    EjectiveConsonant (Velar, NonSibilantFricative, "x º")
    EjectiveConsonant (Uvular, NonSibilantFricative, "œá º")

    EjectiveConsonant (Alveolar, LateralAffricate, "tÕ°…¨ º")
    EjectiveConsonant (Palatal, LateralAffricate, "cÕ° éÃùÃä º")
    EjectiveConsonant (Velar, LateralAffricate, "kÕ°ùºÑ º")

    EjectiveConsonant (Alveolar, LateralFricative, "…¨ º")
    ]

let clickConsonants = Set.ofList [
    ClickConsonant (Velar, Bilabial, TenuisNonLateral, "kÕ° ò")
    ClickConsonant (Velar, Dental, TenuisNonLateral, "kÕ°«Ä")
    ClickConsonant (Velar, Alveolar, TenuisNonLateral, "kÕ°«É")
    ClickConsonant (Velar, Retroflex, TenuisNonLateral, "kÕ°‚Äº")
    ClickConsonant (Velar, Palatal, TenuisNonLateral, "kÕ°«Ç")

    ClickConsonant (Uvular, Bilabial, TenuisNonLateral, "qÕ° ò")
    ClickConsonant (Uvular, Dental, TenuisNonLateral, "qÕ°«Ä")
    ClickConsonant (Uvular, Alveolar, TenuisNonLateral, "qÕ°«É")
    ClickConsonant (Uvular, Retroflex, TenuisNonLateral, "qÕ°‚Äº")
    ClickConsonant (Uvular, Palatal, TenuisNonLateral, "qÕ°«Ç")

    ClickConsonant (Velar, Bilabial, VoicedNonLateral, "…°Õ° ò")
    ClickConsonant (Velar, Dental, VoicedNonLateral, "…°Õ°«Ä")
    ClickConsonant (Velar, Alveolar, VoicedNonLateral, "…°Õ°«É")
    ClickConsonant (Velar, Retroflex, VoicedNonLateral, "…°Õ°‚Äº")
    ClickConsonant (Velar, Palatal, VoicedNonLateral, "…°Õ°«Ç")

    ClickConsonant (Uvular, Bilabial, VoicedNonLateral, "…¢Õ° ò")
    ClickConsonant (Uvular, Dental, VoicedNonLateral, "…¢Õ°«Ä")
    ClickConsonant (Uvular, Alveolar, VoicedNonLateral, "…¢Õ°«É")
    ClickConsonant (Uvular, Retroflex, VoicedNonLateral, "…¢Õ°‚Äº")
    ClickConsonant (Uvular, Palatal, VoicedNonLateral, "…¢Õ°«Ç")

    ClickConsonant (Velar, Bilabial, NasalNonLateral, "≈ãÕ° ò")
    ClickConsonant (Velar, Dental, NasalNonLateral, "≈ãÕ°«Ä")
    ClickConsonant (Velar, Alveolar, NasalNonLateral, "≈ãÕ°«É")
    ClickConsonant (Velar, Retroflex, NasalNonLateral, "≈ãÕ°‚Äº")
    ClickConsonant (Velar, Palatal, NasalNonLateral, "≈ãÕ°«Ç")
    ClickConsonant (Velar, Velar, NasalNonLateral, " û")

    ClickConsonant (Uvular, Bilabial, NasalNonLateral, "…¥Õ° ò")
    ClickConsonant (Uvular, Dental, NasalNonLateral, "…¥Õ°«Ä")
    ClickConsonant (Uvular, Alveolar, NasalNonLateral, "…¥Õ°«É")
    ClickConsonant (Uvular, Retroflex, NasalNonLateral, "…¥Õ°‚Äº")
    ClickConsonant (Uvular, Palatal, NasalNonLateral, "…¥Õ°«Ç")

    ClickConsonant (Velar, Alveolar, TenuisLateral, "kÕ°«Å")

    ClickConsonant (Uvular, Alveolar, TenuisLateral, "qÕ°«Å")

    ClickConsonant (Velar, Alveolar, VoicedLateral, "…°Õ°«Å")

    ClickConsonant (Uvular, Alveolar, VoicedLateral, "…¢Õ°«Å")

    ClickConsonant (Velar, Alveolar, NasalLateral, "≈ãÕ°«Å")

    ClickConsonant (Uvular, Alveolar, NasalLateral, "…¥Õ°«Å")
    ]

let implosiveConsonants = Set.ofList [
    ImplosiveConsonant (Bilabial, Unvoiced, "…ìÃ•")
    ImplosiveConsonant (Bilabial, Voiced, "…ì")

    ImplosiveConsonant (Alveolar, Unvoiced, "…óÃ•")
    ImplosiveConsonant (Alveolar, Voiced, "…ó")

    ImplosiveConsonant (Retroflex, Unvoiced, "·∂ëÃä")
    ImplosiveConsonant (Retroflex, Voiced, "·∂ë")

    ImplosiveConsonant (Palatal, Unvoiced, " ÑÃä")
    ImplosiveConsonant (Palatal, Voiced, " Ñ")

    ImplosiveConsonant (Velar, Unvoiced, "…†Ãä")
    ImplosiveConsonant (Velar, Voiced, "…†")

    ImplosiveConsonant (Uvular, Unvoiced, " õÃ•")
    ImplosiveConsonant (Uvular, Voiced, " õ")
    ]
