﻿using System.Collections;
using UnityEngine;
using System;
using UnityEditor;
using System.Reflection;
using System.Text.RegularExpressions;

[CustomPropertyDrawer(typeof(EnumFlagsAttribute))]
public class EnumFlagsAttributeDrawer : PropertyDrawer
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        System.Object fieldObject = GetSerializedPropertyField(property);
        if (fieldObject != null)
            property.longValue = Convert.ToInt64(EditorGUI.EnumFlagsField(position, label, (Enum)fieldObject));
    }

    public static System.Object GetSerializedPropertyField(SerializedProperty prop)
    {
        System.Object fieldObject = prop.serializedObject.targetObject;
        System.Type containingObjectType = fieldObject.GetType();
        System.Reflection.FieldInfo fieldInfo = null;

        string[] paths = prop.propertyPath.Split('.');
        for (int i = 0; i < paths.Length; i++)
        {
            string fieldName = paths[i];
            if (fieldName == "Array" && i + 1 < paths.Length)
            {
                string fieldDataName = paths[i + 1];
                Match match = Regex.Match(fieldDataName, @"data\[(\d+)\]");
                if (match.Success)
                {
                    i++;
                    int elementIndex = Convert.ToInt32(match.Groups[1].Value);
                    IList listFieldObject = (IList)fieldObject;
                    if (elementIndex < 0 || elementIndex >= listFieldObject.Count)
                        return null;
                    fieldObject = ((IList)fieldObject)[elementIndex];
                    continue;
                }
            }

            fieldInfo = containingObjectType.GetField(fieldName);
            if (fieldInfo != null)
            {
                fieldObject = fieldInfo.GetValue(fieldObject);
                if (fieldInfo.FieldType.IsArray)
                    containingObjectType = GetFieldArrayElementType(fieldInfo);
                else
                    containingObjectType = fieldInfo.FieldType;
            }
            else
            {
                return null;
            }
        }

        return fieldObject;
    }

    public static System.Type GetFieldArrayElementType(FieldInfo field)
    {
        string fullName = field.FieldType.FullName.Substring(0, field.FieldType.FullName.Length - 2); //-2 to remove the "[]" at the end of the field name for the array type
        return Type.GetType(string.Format("{0},{1}", fullName, field.FieldType.Assembly.GetName().Name));
    }
}
