using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using System;
using UnityEngine.UI;


namespace SimplifyXR
{
    public enum PanelAspect
    {
        square,
        wide, 
        custom, 
        ignore
    }

    [System.Serializable]
    public class PanelAspectProperties
    {
        public float horizontal;
        public float vertical;
    }

    [System.Serializable]
    public class DisplayElement
    {
        public string id;
        public bool display;

        public DisplayElement(string id, bool display)
        {
            this.id = id;
            this.display = display;
        }
    }

    public enum XRCompatibility
    {
        none, 
        MRTK2, 
        XRI, 
        MRTK3
    }

    public enum XRPanelType
    {
        worldSpace, 
        handAnchored
    }
    

    public class StandardPanel : MonoBehaviour
    {
        [Header("Panel Setup")]
        [Tooltip("Adds the neccessary XR components from the selected XR library to the panel.")]
        public XRCompatibility xRCompatability;

        [Conditional("xRCompatability", XRCompatibility.none, ComparisonType.NotEqual),
            Conditional("xRCompatability", XRCompatibility.XRI, ComparisonType.NotEqual)]
        public XRPanelType xRPanelType;


        [Tooltip("Changes the panel aspect ratio.")]
        public PanelAspect panelAspect;


        [Conditional("panelAspect", PanelAspect.custom, ComparisonType.Equals)]
        public PanelAspectProperties panelAspectProperties;

        [Range(0, 1), Tooltip("Specifies how much z-depth to add to child elements in the hierarchy")]
        public float panelDepth;
        [Tooltip("Specifies the curve to use for the panel depth")]
        public AnimationCurve depthCurve;

        [Header("Panel Styling")]
        [Tooltip("Specify if the panel should use any custom styles")]
        public bool useCustomStyles;
        [Conditional("useCustomStyles", true, ComparisonType.Equals),
            Tooltip("Select a Panel Theme scriptable object to update the current panel's styles.")]
        public PanelTheme panelTheme;
        [Conditional("useCustomStyles", true, ComparisonType.Equals), 
            Tooltip("Specify custom hover depth properties for on hover rollover button states.")]
        public bool customHoverDepthProperties = true;

        [Conditional("customHoverDepthProperties", true, ComparisonType.Equals), 
            Conditional("useCustomStyles", true, ComparisonType.Equals),
            Tooltip("Toggle to enable or disable the hover depth behavior on button rollover states.")]
        public bool enableHoverDepth = true;


        [Conditional("useCustomStyles", true, ComparisonType.Equals),
            Conditional("customHoverDepthProperties", true, ComparisonType.Equals),
            Tooltip("The properties to affect the behavior of the hover depth button rollover state.")]
        public HoverDepthProperties hoverDepthProperties;


        [Header("Panel Display"),
            Tooltip("Customize which elements of the panel should be shown or hidden.")]
        public bool customizeDisplay;



        [HideInInspector]
        public List<DisplayElement> displayElements;

        public DisplayElement GetDisplayElementByID(string id)
        {
            return displayElements.Where(e => e.id == id).FirstOrDefault();
        }

        public void UpdateDisplayElementByID(string id, bool value)
        {
            displayElements.ToList().ForEach(e =>
            {
                if (e.id == id)
                {
                    e.display = value;
                    return;
                }
            });
        }



        public Dictionary<XRCompatibility, IXRPanelConfig> GetAllConfigurations()
        {
            var type = typeof(IXRPanelConfig);
            var types = AppDomain.CurrentDomain.GetAssemblies()
            .SelectMany(s => s.GetTypes())
            .Where(p => type.IsAssignableFrom(p) && !type.Equals(p));

            var configurations = new Dictionary<XRCompatibility, IXRPanelConfig>();

            types.ToList().ForEach(type =>
            {
                var instance = (IXRPanelConfig)Activator.CreateInstance(type);

                configurations.Add(instance.Compatibility(), instance);
            });

            return configurations;

        }

        public void HandleConfigurations(Dictionary<XRCompatibility, IXRPanelConfig> configurations)
        {
            configurations.Keys.ToList().ForEach(
                c => {
                    if (configurations.ContainsKey(c)
                 && c != xRCompatability) configurations[c].RemoveConfiguration(gameObject, this.xRPanelType);
                });

            if (configurations.ContainsKey(xRCompatability)) configurations[xRCompatability]?
                    .SetupConfiguration(gameObject, this.xRPanelType);

        }

        public void HandleConfigurations(Dictionary<XRCompatibility, IXRPanelConfig> configurations, 
            List<Button> buttons)
        {
            configurations.Keys.ToList().ForEach(
                c => {
                    if (configurations.ContainsKey(c)
                 && c != xRCompatability) configurations[c].RemoveConfiguration(buttons);
                });

            if (configurations.ContainsKey(xRCompatability)) configurations[xRCompatability]?
                    .SetupConfiguration(buttons);

        }

        public void UpdateHoverDepth(ElementRoot root)
        {

            var buttons = root.GetComponentsInChildren<Button>(true);
            buttons.ToList().ForEach(b =>
            {
                var hoverDepth = b.gameObject.GetOrAddNewComponent<HoverDepth>();
                var props = new HoverDepthProperties();
                props = hoverDepthProperties;
                hoverDepth.depthProperties = props;
                hoverDepth.enabled = enableHoverDepth;

#if UNITY_EDITOR
                UnityEditor.EditorUtility.SetDirty(hoverDepth);
#endif

            });
        }

    }

}


