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

namespace RothenburgAR.UI
{
    public enum UIMaterial
    {
        BaseOpaque,
        BaseTransparent,
        LightOpaque,
        LightTransparent,
        DarkOpaque,
        DarkTransparent,
        ProjectionEffect,
        ExhibitOutline,
        ReticuleBorder,
        TitleBorder,
    }


    internal class UIColorSchemeManager : Singleton<UIColorSchemeManager>
    {
        private Dictionary<UIMaterial, Material> _uiMaterials;
        public List<UIColorScheme> AvailableUIColorSchemes { get; private set; }

        public int CurrentColorSchemeID = 0;

        internal void Initialize()
        {
            AvailableUIColorSchemes = new List<UIColorScheme>();
            InitUIMaterialDictionary();
            InitializeUIColorSchemes();
            SetUiColorScheme(0);
        }

        public void SetUiColorScheme(int uiColorSchemeId)
        {
            UIColorScheme scheme;
            if (AvailableUIColorSchemes.Count < uiColorSchemeId)
            {
                Debug.LogError("UIColorScheme '" + uiColorSchemeId + "' not found. Defaulting to Light Blue Scheme.");
                scheme = new UIColorScheme("t_color_name_light_blue", "#03A9F4", "#E1F5FE", "#0277BD", 0.75f);
            }
            else
            {
                scheme = AvailableUIColorSchemes[uiColorSchemeId];
                CurrentColorSchemeID = uiColorSchemeId;
            }

            _uiMaterials[UIMaterial.BaseOpaque].color = scheme.BaseColorOpaque;
            _uiMaterials[UIMaterial.BaseTransparent].color = scheme.BaseColorTransparent;

            _uiMaterials[UIMaterial.LightOpaque].color = scheme.LightColorOpaque;
            _uiMaterials[UIMaterial.LightTransparent].color = scheme.LightColorTransparent;

            _uiMaterials[UIMaterial.DarkOpaque].color = scheme.DarkColorOpaque;
            _uiMaterials[UIMaterial.DarkTransparent].color = scheme.DarkColorTransparent;

            _uiMaterials[UIMaterial.ProjectionEffect].color = scheme.LightColorTransparent;
            _uiMaterials[UIMaterial.ExhibitOutline].color = scheme.BaseColorOpaque;
            _uiMaterials[UIMaterial.ReticuleBorder].color = scheme.BaseColorTransparent;
            _uiMaterials[UIMaterial.TitleBorder].color = scheme.BaseColorOpaque;
        }

        public Material GetUIMaterial(UIMaterial uiMaterial)
        {
            Material material;
            if (_uiMaterials.TryGetValue(uiMaterial, out material) == false)
            {
                Debug.LogError("Material " + uiMaterial + " not found in UIMaterials.");
                material = null;
            }

            return material;
        }

        private void InitUIMaterialDictionary()
        {
            _uiMaterials = new Dictionary<UIMaterial, Material>
            {
                {UIMaterial.BaseOpaque, Resources.Load<Material>("Materials/UIBaseOpaque")},
                {UIMaterial.BaseTransparent, Resources.Load<Material>("Materials/UIBaseTransparent")},
                {UIMaterial.LightOpaque, Resources.Load<Material>("Materials/UILightOpaque")},
                {UIMaterial.LightTransparent, Resources.Load<Material>("Materials/UILightTransparent")},
                {UIMaterial.DarkOpaque, Resources.Load<Material>("Materials/UIDarkOpaque")},
                {UIMaterial.DarkTransparent, Resources.Load<Material>("Materials/UIDarkTransparent")},
                {UIMaterial.ProjectionEffect, Resources.Load<Material>("Materials/UIMaterialProjectionEffect")},
                {UIMaterial.ExhibitOutline, Resources.Load<Material>("Materials/UIExhibitOutline")},
                {UIMaterial.ReticuleBorder, Resources.Load<Material>("Materials/UIReticuleMasked")},
                {UIMaterial.TitleBorder, Resources.Load<Material>("Materials/UITitleBorderMasked")}
                
            };
        }

        private void InitializeUIColorSchemes()
        {
            var file = Resources.Load<TextAsset>("colors");
            Debug.Log("Loading colors from Resources..");

            if (file == null)
            {
                // Set default colors, if not able to load
                Debug.LogWarning("colors.xml does not exist in Resources folder - use default colors");
                AvailableUIColorSchemes = new List<UIColorScheme>
                {
                    new UIColorScheme("t_color_name_light_blue", "#03A9F4", "#E1F5FE", "#0277BD", 0.75f),
                    new UIColorScheme("t_color_name_red", "#F44336", "#FFEBEE", "#C62828", 0.75f),
                    new UIColorScheme("t_color_name_light_green", "#8BC34A", "#F1F8E9", "#558B2F", 0.75f),
                };
                return;
            }

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

            var colorNodes = doc.SelectNodes("//color");
            if (colorNodes == null) return;
            foreach (XmlNode colorNode in colorNodes)
            {
                var name = colorNode.Attributes["name"].Value;
                var baseColor = colorNode.SelectSingleNode("base").Attributes["color"].Value;
                var lightColor = colorNode.SelectSingleNode("light").Attributes["color"].Value;
                var darkColor = colorNode.SelectSingleNode("dark").Attributes["color"].Value;
                var transparencyString = colorNode.SelectSingleNode("transparency").Attributes["value"].Value;
                float transparencyFloat =
                    float.Parse(transparencyString, CultureInfo.InvariantCulture.NumberFormat);
                
                AvailableUIColorSchemes.Add(new UIColorScheme(name, baseColor, lightColor, darkColor, transparencyFloat));

            }
        }
    }
}