using UnityEngine;
using UnityEditor;

namespace Jovian.Utilities.Editor {
    [CustomEditor(typeof(CustomRenderQueueMaterialList))]
    public class CustomRenderQueueMaterialListEditor : UnityEditor.Editor {

        private const int MAXNAMELENGTH = 30;

        public override void OnInspectorGUI() {
            if(((CustomRenderQueueMaterialList)target).updateMaterialsInEditor) {
                EditorGUILayout.HelpBox("Enabling 'updateMaterialsInEditor' will cause the Editor to change material files. Only use in debug and please review your changelist before submitting.", MessageType.Warning);
            }
            DrawAddGUI();
            base.OnInspectorGUI();
            DrawAddGUI();
        }

        private void DrawAddGUI() {
            GUILayout.BeginHorizontal();
            if(GUILayout.Button("Add Empty")) {
                AddEmpty();
            }
            if(Selection.activeGameObject) {
                if(GUILayout.Button($"Add from '{GetNiceName(Selection.activeGameObject)}'")) {
                    AddGameObject(Selection.activeGameObject);
                }
            }
            if(Selection.activeObject is Material) {
                if(GUILayout.Button($"Add '{GetNiceName(Selection.activeObject)}'")) {
                    AddMaterial(Selection.activeObject as Material);
                }
            }
            GUILayout.EndHorizontal();
        }

        private string GetNiceName(Object obj) {
            var objectName = obj.name;
            if(objectName.Length > MAXNAMELENGTH) {
                objectName = objectName.Substring(0, MAXNAMELENGTH - 2) + "..";
            }
            return objectName;
        }

        private void AddEmpty() {
            AddElement(null, -1);
        }

        private void AddGameObject(GameObject gameObject) {
            var renderer = gameObject.GetComponentInChildren<Renderer>();
            if(renderer == null) {
                Debug.LogError($"Cannot add Renderer from {gameObject}, there is none.");
                return;
            }
            AddMaterial(renderer.sharedMaterial);
        }

        private void AddMaterial(Material material) {
            if(material == null) {
                Debug.LogError($"Cannot add Material, it is null.");
                return;
            }

            if(((CustomRenderQueueMaterialList)target).DoesMaterialExistInList(material)) {
                Debug.LogError($"Cannot add Material, it is already listed.");
                return;
            }

            AddElement(material, material.renderQueue);
        }

        private void AddElement(Material material, int renderQueue) {
            var listProperty = serializedObject.FindProperty("materialRenderQueueList");
            var count = listProperty.arraySize;
            listProperty.arraySize = count + 1;
            var elementProperty = listProperty.GetArrayElementAtIndex(count);
            var materialProperty = elementProperty.FindPropertyRelative("material");
            var renderQueueProperty = elementProperty.FindPropertyRelative("renderQueue");
            materialProperty.objectReferenceValue = material;
            renderQueueProperty.intValue = renderQueue;
            serializedObject.ApplyModifiedProperties();
        }
    }
}
