using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.VFX;

namespace ImpactCFX.VFXBatch.EditorScripts
{
    [CustomEditor(typeof(ImpactVFXBatchMaster))]
    public class ImpactVFXBatchMasterEditor : Editor
    {
        private SerializedProperty visualEffectProperty;

        private SerializedProperty vectorsPropertyNameProperty;
        private SerializedProperty countPropertyNameProperty;
        private SerializedProperty capacityPropertyNameProperty;

        private SerializedProperty capacityProperty;

        private string[] exposedTexturePropertyNamesArray;
        private string[] exposedIntPropertyNamesArray;
        private bool hasVisualEffect;

        private void OnEnable()
        {
            visualEffectProperty = serializedObject.FindProperty("visualEffect");

            vectorsPropertyNameProperty = serializedObject.FindProperty("vectorsProperty");
            countPropertyNameProperty = serializedObject.FindProperty("countProperty");
            capacityPropertyNameProperty = serializedObject.FindProperty("capacityProperty");

            capacityProperty = serializedObject.FindProperty("capacity");

            refreshExposedProperties();
        }

        private void refreshExposedProperties()
        {
            VisualEffect visualEffect = visualEffectProperty.objectReferenceValue as VisualEffect;
            hasVisualEffect = visualEffect != null;

            if (hasVisualEffect)
            {
                VisualEffectAsset visualEffectAsset = visualEffect.visualEffectAsset;
                List<VFXExposedProperty> exposedProperties = new List<VFXExposedProperty>();
                List<string> exposedTextureProperties = new List<string>();
                List<string> exposedIntProperties = new List<string>();

                visualEffectAsset.GetExposedProperties(exposedProperties);

                for (int i = 0; i < exposedProperties.Count; i++)
                {
                    VFXExposedProperty vfxExposedProperty = exposedProperties[i];

                    if (vfxExposedProperty.type == typeof(Texture))
                    {
                        exposedTextureProperties.Add(vfxExposedProperty.name);
                    }
                    else if (vfxExposedProperty.type == typeof(int))
                    {
                        exposedIntProperties.Add(vfxExposedProperty.name);
                    }
                }

                exposedTexturePropertyNamesArray = exposedTextureProperties.ToArray();
                exposedIntPropertyNamesArray = exposedIntProperties.ToArray();
            }
            else
            {
                exposedTexturePropertyNamesArray = new string[0];
                exposedIntPropertyNamesArray = new string[0];
            }
        }

        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            EditorGUI.BeginChangeCheck();
            EditorGUILayout.PropertyField(visualEffectProperty);

            if (EditorGUI.EndChangeCheck())
            {
                refreshExposedProperties();
            }

            EditorGUILayout.Separator();

            GUI.enabled = hasVisualEffect;

            EditorGUI.indentLevel++;
            drawPropertyNameField(vectorsPropertyNameProperty, exposedTexturePropertyNamesArray);
            drawPropertyNameField(countPropertyNameProperty, exposedIntPropertyNamesArray);
            drawPropertyNameField(capacityPropertyNameProperty, exposedIntPropertyNamesArray);
            EditorGUI.indentLevel--;

            GUI.enabled = true;

            EditorGUILayout.Separator();

            EditorGUILayout.PropertyField(capacityProperty);

            serializedObject.ApplyModifiedProperties();
        }

        private void drawPropertyNameField(SerializedProperty property, string[] displayedOptions)
        {
            EditorGUILayout.BeginHorizontal();

            string propertyName = property.stringValue;
            int selectedIndex = findPropertyIndex(propertyName, displayedOptions);

            selectedIndex = EditorGUILayout.Popup(new GUIContent(property.displayName, property.tooltip), selectedIndex, displayedOptions);

            if (selectedIndex >= 0)
            {
                propertyName = displayedOptions[selectedIndex];
                property.stringValue = propertyName;
            }


            EditorGUILayout.EndHorizontal();

        }

        private int findPropertyIndex(string propertyName, string[] displayedOptions)
        {
            for (int i = 0; i < displayedOptions.Length; i++)
            {
                if (displayedOptions[i].Equals(propertyName))
                    return i;
            }

            return -1;
        }
    }
}