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

namespace NaughtyAttributes.Editor {
    [PropertyDrawer(typeof(ReorderableListAttribute))]
    public class ReorderableListPropertyDrawer : PropertyDrawer {
        private Dictionary<string, ReorderableList> reorderableListsByPropertyName = new Dictionary<string, ReorderableList>();

        string GetPropertyKeyName (SerializedProperty property) => property.serializedObject.targetObject.GetInstanceID() + "/" + property.name;

        public override void DrawProperty (SerializedProperty property) {
            EditorDrawUtility.DrawHeader(property);

            if (property.isArray) {
                var key = GetPropertyKeyName(property);

                if (!this.reorderableListsByPropertyName.ContainsKey(key)) {
                    ReorderableList reorderableList = new ReorderableList(property.serializedObject, property, true, true, true, true) {
                        drawHeaderCallback = (Rect rect) => {
                            EditorGUI.LabelField(rect, string.Format("{0}: {1}", property.displayName, property.arraySize), EditorStyles.label);
                        },

                        drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
                            var element = property.GetArrayElementAtIndex(index);
                            rect.y += 2f;

                            EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight), element);
                        }
                    };

                    this.reorderableListsByPropertyName[key] = reorderableList;
                }

                this.reorderableListsByPropertyName[key].DoLayoutList();
            } else {
                string warning = typeof(ReorderableListAttribute).Name + " can be used only on arrays or lists";
                EditorDrawUtility.DrawHelpBox(warning, MessageType.Warning, context: PropertyUtility.GetTargetObject(property));

                EditorDrawUtility.DrawPropertyField(property);
            }
        }

        public override void ClearCache () => this.reorderableListsByPropertyName.Clear();
    }
}
