// Created with MonoDevelop
//
//    Copyright (C) 2016 Hiperscan GmbH Dresden, Germany
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Globalization;
using System.IO;
using System.Reflection;
using Hiperscan.Unix;

namespace Hiperscan.Common.I18n
{
    public static class CatalogLocale
    {
        public enum LocaleType
        {
            Unknown,
            de_DE,
            en_GB,
            cs_CZ,
            it_IT,
            es_ES,
            ru_RU,
            pt_BR,
        }

        private const string LANGUAGE = "LANGUAGE";
        private const string COUNTRY = "COUNTRY";
        public const string NO_SUBSTANCE_NAME = "NO_SUBSTANCE_NAME";
        public const string C = "C";
        public const string DEFAULT_LANGUAGE = "en";

        public static void SetEnvironmentLang(string locale_type)
        {
            LocaleType locale = LocaleType.Unknown;

            locale_type = locale_type.Replace("-", "_");
            locale_type = locale_type.Split('.')[0];

            try
            {
                if (locale_type.Contains("_"))
                    locale = (LocaleType)Enum.Parse(typeof(LocaleType), locale_type, true);
                else
                    locale = CatalogLocale.GetLocaleByLanguageCode(locale_type);
                    
                CatalogLocale.SetEnvironmentLang(locale);
            }
            catch(Exception)
            {
                CatalogLocale.SetEnvironmentLang(LocaleType.Unknown);
            }
        }

        public static void SetEnvironmentLang(LocaleType locale_type)
        {
            if (Environment.OSVersion.Platform == PlatformID.Unix)
                Environment.SetEnvironmentVariable("LANGUAGE", locale_type.ToString());
        }

        public static LocaleType ConvertStringToLocaleType(string value)
        {
            value = value.Replace("-", "_");
            value = value.Split('.')[0];

            return (LocaleType)Enum.Parse(typeof(LocaleType), value, true);
        }

        public static LocaleType GetLocaleByLanguageCode(string code)
        {
            LocaleType type = LocaleType.Unknown;
            code = (code ?? String.Empty).ToLower();
            if (code.Length != 2)
                return type;

            bool already_found = false;

            foreach (string loc in Enum.GetNames(typeof(LocaleType)))
            {
                if (loc.StartsWith(code, StringComparison.InvariantCulture) == true)
                {
                    if (already_found)
                        throw new Exception(String.Format("Language code '{0}' is not unique.", code));

                    already_found = true;
                    type = (LocaleType)Enum.Parse(typeof(LocaleType), loc, true);
                }
            }

            return type;
        }


        public static string FullName
        {
            get
            {
                string full_name = string.Empty;

                switch (CatalogLocale.Language)
                {

                    case "de":
                        full_name = "Deutsch";
                        break;

                    case "en":
                        full_name = "English";
                        break;

                    case "cs":
                        full_name = "Česky";
                        break;

                    case "it":
                        full_name = "Italiano";
                        break;

                    case "es":
                        full_name = "Español";
                        break;

                    case "ru":
                        full_name = "Русский";
                        break;

                    case "pt":
                        full_name = "Português";
                        break;

                    case "C":
                        full_name = "Posix default";
                        break;

                    default:
                        throw new ArgumentException(Catalog.GetString("Unknown locale language:") + " " + CatalogLocale.Language);

                }

                return full_name;
            }
        }

        public static LocaleType GetLocaleType()
        {
            string val = Catalog.GetString(Catalog.LANGUAGE_COUNTRY);
            if (val == Catalog.LANGUAGE_COUNTRY)
                return LocaleType.Unknown;
            try
            {
                LocaleType type = (LocaleType)Enum.Parse(typeof(LocaleType), val);
                return type;
            }
            catch (Exception ex)
            {
                throw new ArgumentException(String.Format(Catalog.GetString("Unknown locale type: {0}"), val), ex);
            }
        }

        public static string Language
        {
            get
            {
                string val = Catalog.GetString(Catalog.LANGUAGE_COUNTRY).Split(new char[]{'_', '-'})[0];
                if (val == CatalogLocale.LANGUAGE)
                    return CatalogLocale.C;

                return val;
            }
        }

        public static string Country
        {
            get
            {
                string val = Catalog.GetString("LANGUAGE_COUNTRY").Split(new char[]{'_', '-'})[1];
                if (val == CatalogLocale.COUNTRY)
                    return CatalogLocale.C;

                return val;
            }
        }

        public static string Info
        {
            get
            {
                if (CatalogLocale.Language == CatalogLocale.C && string.IsNullOrEmpty(CatalogLocale.Country))
                    return string.Format("Internationalization is set to: {0} ({1}; CurrentCulture = {2})", CatalogLocale.Language, CatalogLocale.FullName, CultureInfo.CurrentCulture);
                return string.Format("Internationalization is set to: {0}-{1} ({2}; CurrentCulture = {3})", CatalogLocale.Language, CatalogLocale.Country, CatalogLocale.FullName, CultureInfo.CurrentCulture);
            }
        }
    }
}
