using System.Collections.Generic;
using System.IO;
using System.Xml;
using RothenburgAR.Common;
using UnityEngine;

namespace RothenburgAR
{
    struct LanguageDescription
    {
        public string Key;
        public string Name;
        public string FlagImagePath;
    }


    class LanguageManager : Singleton<LanguageManager>
    {
        public const string ERR_TOKEN_NOT_FOUND = "ERR_TOKEN_NOT_FOUND";
        public const string ERR_NO_TEXT_FOR_LANG = "ERR_NO_TEXT_FOR_LANG";

        private Dictionary<string, TextElement> TextTokenList;
        public List<LanguageDescription> AvailableLanguages;
        public string DefaultLanguageKey { get; set; }
        public string CurrentLanguageKey { get; set; }

        public LanguageManager()
        {
            AvailableLanguages = new List<LanguageDescription>();
            TextTokenList = new Dictionary<string, TextElement>();
        }

        public void AddLanguage(string key, string langName, string flagImagePath)
        {
            Debug.Log("Adding Language; name='" + langName +
                      "'; key='" + key +
                      "'; flagImagePath='" + flagImagePath + "'");
            AvailableLanguages.Add(new LanguageDescription
            {
                Key = key,
                Name = langName,
                FlagImagePath = flagImagePath
            });
        }

        public void AddString(string token, string languagekey, string text)
        {
            if (!TextTokenList.ContainsKey(token))
            {
                TextTokenList.Add(token, new TextElement());
            }
            TextTokenList[token].AddTextElement(languagekey, TextEntryType.Inline, text);
        }

        public void SetTextElement(string token, TextElement textElement)
        {
            TextTokenList[token] = textElement;
        }

        public string GetString(string token)
        {
            return GetString(token, CurrentLanguageKey);
        }

        public string GetString(string token, string languagekey)
        {
            if (!TextTokenList.ContainsKey(token))
            {
                Debug.Log("Could not find language token '" + token + "'");
                return ERR_TOKEN_NOT_FOUND;
            }
            var str = TextTokenList[token].GetTextByLanguage(languagekey);
            if (str != ERR_NO_TEXT_FOR_LANG) return str;

            Debug.Log("Could not find language '" + languagekey + "' for token '" + token + "'");
            if (languagekey == DefaultLanguageKey)
            {
                return ERR_NO_TEXT_FOR_LANG;
            }
            else
            {
                // Try to get it for the default language
                return GetString(token, DefaultLanguageKey);
            }
        }

        public void LoadLanguagesFromXml()
        {
            var file = Resources.Load<TextAsset>("localization");
            Debug.Log("Loading languages from Resources");

            if (file == null)
                throw new FileNotFoundException("Localization file Assets/Resources/localization.xml not found");

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(file.text);

            var languageNodes = doc.SelectNodes("//language");
            foreach (XmlNode languageNode in languageNodes)
            {
                var langKey = languageNode.Attributes["key"].Value;
                var langName = languageNode.Attributes["name"].Value;
                var langFlagPath = languageNode.Attributes["flagPath"].Value;

                AddLanguage(langKey, langName, langFlagPath);

                if (languageNode.Attributes["default"] != null || DefaultLanguageKey == null)
                {
                    Debug.Log("Setting default language to '" + langKey + "'");
                    CurrentLanguageKey = langKey;
                }
            }

            var entryNodes = doc.SelectNodes("//entry");
            foreach (XmlNode entryNode in entryNodes)
            {
                var entryToken = entryNode.Attributes["name"].Value;
                var entryTextElement = TextElement.BuildFromXmlNode(PathHelper.DataPath, entryNode.ChildNodes);

                SetTextElement(entryToken, entryTextElement);
            }
        }
    }
}