/// Represents the languages that the text to translate shall use.
///
/// It can be either an automatic detection, or a predefined [`Language`](enum.Language.html).
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq)]
pub enum InputLanguage {
    /// Automatic language detection.
    Automatic,
    /// Defined language input.
    Defined(Language),
}

/// Represents all the languages available for translation.
///
/// They are all compatible with the Yandex API.
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq)]
pub enum Language {
    Afrikaans,
    Albanian,
    Amharic,
    Arabic,
    Armenian,
    Azerbaijan,
    Bashkir,
    Basque,
    Belarusian,
    Bengali,
    Bosnian,
    Bulgarian,
    Burmese,
    Catalan,
    Cebuano,
    Chinese,
    Croatian,
    Czech,
    Danish,
    Dutch,
    English,
    Esperanto,
    Estonian,
    Finnish,
    French,
    Galician,
    Georgian,
    German,
    Greek,
    Gujarati,
    HaitianCreole,
    Hebrew,
    HillMari,
    Hindi,
    Hungarian,
    Icelandic,
    Indonesian,
    Irish,
    Italian,
    Japanese,
    Javanese,
    Kannada,
    Kazakh,
    Khmer,
    Korean,
    Kyrgyz,
    Laotian,
    Latin,
    Latvian,
    Lithuanian,
    Luxembourgish,
    Macedonian,
    Malagasy,
    Malay,
    Malayalam,
    Maltese,
    Maori,
    Marathi,
    Mari,
    Mongolian,
    Nepali,
    Norwegian,
    Papiamento,
    Persian,
    Polish,
    Portuguese,
    Punjabi,
    Romanian,
    Russian,
    Scottish,
    Serbian,
    Sinhala,
    Slovakian,
    Slovenian,
    Spanish,
    Sundanese,
    Swahili,
    Swedish,
    Tagalog,
    Tajik,
    Tamil,
    Tatar,
    Telugu,
    Thai,
    Turkish,
    Udmurt,
    Ukrainian,
    Urdu,
    Uzbek,
    Vietnamese,
    Welsh,
    Xhosa,
    Yiddish,
}

impl Language {
    pub fn to_language_code(&self) -> &'static str {
        use Language::*;
        match *self {
            // YANDEX api-compatibles
            Afrikaans => "af",
            Albanian => "sq",
            Amharic => "am",
            Arabic => "ar",
            Armenian => "hy",
            Azerbaijan => "az",
            Bashkir => "ba",
            Basque => "eu",
            Belarusian => "be",
            Bengali => "bn",
            Bosnian => "bs",
            Bulgarian => "bg",
            Burmese => "my",
            Catalan => "ca",
            Cebuano => "ceb",
            Chinese => "zh",
            Croatian => "hr",
            Czech => "cs",
            Danish => "da",
            Dutch => "nl",
            English => "en",
            Esperanto => "eo",
            Estonian => "et",
            Finnish => "fi",
            French => "fr",
            Galician => "gl",
            Georgian => "ka",
            German => "de",
            Greek => "el",
            Gujarati => "gu",
            HaitianCreole => "ht",
            Hebrew => "he",
            HillMari => "mrj",
            Hindi => "hi",
            Hungarian => "hu",
            Icelandic => "is",
            Indonesian => "id",
            Irish => "ga",
            Italian => "it",
            Japanese => "ja",
            Javanese => "jv",
            Kannada => "kn",
            Kazakh => "kk",
            Khmer => "km",
            Korean => "ko",
            Kyrgyz => "ky",
            Laotian => "lo",
            Latin => "la",
            Latvian => "lv",
            Lithuanian => "lt",
            Luxembourgish => "lb",
            Macedonian => "mk",
            Malagasy => "mg",
            Malay => "ms",
            Malayalam => "ml",
            Maltese => "mt",
            Maori => "mi",
            Marathi => "mr",
            Mari => "mhr",
            Mongolian => "mn",
            Nepali => "ne",
            Norwegian => "no",
            Papiamento => "pap",
            Persian => "fa",
            Polish => "pl",
            Portuguese => "pt",
            Punjabi => "pa",
            Romanian => "ro",
            Russian => "ru",
            Scottish => "gd",
            Serbian => "sr",
            Sinhala => "si",
            Slovakian => "sk",
            Slovenian => "sl",
            Spanish => "es",
            Sundanese => "su",
            Swahili => "sw",
            Swedish => "sv",
            Tagalog => "tl",
            Tajik => "tg",
            Tamil => "ta",
            Tatar => "tt",
            Telugu => "te",
            Thai => "th",
            Turkish => "tr",
            Udmurt => "udm",
            Ukrainian => "uk",
            Urdu => "ur",
            Uzbek => "uz",
            Vietnamese => "vi",
            Welsh => "cy",
            Xhosa => "xh",
            Yiddish => "yi",
        }
    }

    pub fn from_language_code(code: String) -> Option<Language> {
        use Language::*;
        match code.as_str() {
            // YANDEX api-compatibles
            "af" => Some(Afrikaans),
            "sq" => Some(Albanian),
            "am" => Some(Amharic),
            "ar" => Some(Arabic),
            "hy" => Some(Armenian),
            "az" => Some(Azerbaijan),
            "ba" => Some(Bashkir),
            "eu" => Some(Basque),
            "be" => Some(Belarusian),
            "bn" => Some(Bengali),
            "bs" => Some(Bosnian),
            "bg" => Some(Bulgarian),
            "my" => Some(Burmese),
            "ca" => Some(Catalan),
            "ceb" => Some(Cebuano),
            "zh" => Some(Chinese),
            "hr" => Some(Croatian),
            "cs" => Some(Czech),
            "da" => Some(Danish),
            "nl" => Some(Dutch),
            "en" => Some(English),
            "eo" => Some(Esperanto),
            "et" => Some(Estonian),
            "fi" => Some(Finnish),
            "fr" => Some(French),
            "gl" => Some(Galician),
            "ka" => Some(Georgian),
            "de" => Some(German),
            "el" => Some(Greek),
            "gu" => Some(Gujarati),
            "ht" => Some(HaitianCreole),
            "he" => Some(Hebrew),
            "mrj" => Some(HillMari),
            "hi" => Some(Hindi),
            "hu" => Some(Hungarian),
            "is" => Some(Icelandic),
            "id" => Some(Indonesian),
            "ga" => Some(Irish),
            "it" => Some(Italian),
            "ja" => Some(Japanese),
            "jv" => Some(Javanese),
            "kn" => Some(Kannada),
            "kk" => Some(Kazakh),
            "km" => Some(Khmer),
            "ko" => Some(Korean),
            "ky" => Some(Kyrgyz),
            "lo" => Some(Laotian),
            "la" => Some(Latin),
            "lv" => Some(Latvian),
            "lt" => Some(Lithuanian),
            "lb" => Some(Luxembourgish),
            "mk" => Some(Macedonian),
            "mg" => Some(Malagasy),
            "ms" => Some(Malay),
            "ml" => Some(Malayalam),
            "mt" => Some(Maltese),
            "mi" => Some(Maori),
            "mr" => Some(Marathi),
            "mhr" => Some(Mari),
            "mn" => Some(Mongolian),
            "ne" => Some(Nepali),
            "no" => Some(Norwegian),
            "pap" => Some(Papiamento),
            "fa" => Some(Persian),
            "pl" => Some(Polish),
            "pt" => Some(Portuguese),
            "pa" => Some(Punjabi),
            "ro" => Some(Romanian),
            "ru" => Some(Russian),
            "gd" => Some(Scottish),
            "sr" => Some(Serbian),
            "si" => Some(Sinhala),
            "sk" => Some(Slovakian),
            "sl" => Some(Slovenian),
            "es" => Some(Spanish),
            "su" => Some(Sundanese),
            "sw" => Some(Swahili),
            "sv" => Some(Swedish),
            "tl" => Some(Tagalog),
            "tg" => Some(Tajik),
            "ta" => Some(Tamil),
            "tt" => Some(Tatar),
            "te" => Some(Telugu),
            "th" => Some(Thai),
            "tr" => Some(Turkish),
            "udm" => Some(Udmurt),
            "uk" => Some(Ukrainian),
            "ur" => Some(Urdu),
            "uz" => Some(Uzbek),
            "vi" => Some(Vietnamese),
            "cy" => Some(Welsh),
            "xh" => Some(Xhosa),
            "yi" => Some(Yiddish),
            _ => None,
        }
    }
}

// ! --------------- used for tests ---------------

// TODO find a way to do #[cfg(test)]
impl Language {
    pub fn iterator() -> std::slice::Iter<'static, Language> {
        use Language::*;
        static LANGUAGE: [Language; 93] = [
            Afrikaans,
            Albanian,
            Amharic,
            Arabic,
            Armenian,
            Azerbaijan,
            Bashkir,
            Basque,
            Belarusian,
            Bengali,
            Bosnian,
            Bulgarian,
            Burmese,
            Catalan,
            Cebuano,
            Chinese,
            Croatian,
            Czech,
            Danish,
            Dutch,
            English,
            Esperanto,
            Estonian,
            Finnish,
            French,
            Galician,
            Georgian,
            German,
            Greek,
            Gujarati,
            HaitianCreole,
            Hebrew,
            HillMari,
            Hindi,
            Hungarian,
            Icelandic,
            Indonesian,
            Irish,
            Italian,
            Japanese,
            Javanese,
            Kannada,
            Kazakh,
            Khmer,
            Korean,
            Kyrgyz,
            Laotian,
            Latin,
            Latvian,
            Lithuanian,
            Luxembourgish,
            Macedonian,
            Malagasy,
            Malay,
            Malayalam,
            Maltese,
            Maori,
            Marathi,
            Mari,
            Mongolian,
            Nepali,
            Norwegian,
            Papiamento,
            Persian,
            Polish,
            Portuguese,
            Punjabi,
            Romanian,
            Russian,
            Scottish,
            Serbian,
            Sinhala,
            Slovakian,
            Slovenian,
            Spanish,
            Sundanese,
            Swahili,
            Swedish,
            Tagalog,
            Tajik,
            Tamil,
            Tatar,
            Telugu,
            Thai,
            Turkish,
            Udmurt,
            Ukrainian,
            Urdu,
            Uzbek,
            Vietnamese,
            Welsh,
            Xhosa,
            Yiddish,
        ];
        LANGUAGE.iter()
    }
}
