using UnityEngine;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor;
#endif
using System.Reflection;

#if UNITY_EDITOR
[InitializeOnLoad]
#endif
public static class PrefabExtension
{
    private static List<int> _dirty = new List<int>();

    static PrefabExtension()
    {
#if UNITY_EDITOR
        UnityEditor.PrefabUtility.prefabInstanceUpdated += OnPrefabInstanceUpdate;
#endif
    }

    public static string OnApplyPrefab = "OnApplyPrefab";

    public static void OnPrefabInstanceUpdate(GameObject instance)
    {
#if UNITY_EDITOR
        GameObject prefab = UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(instance) as GameObject;
        int instanceID = prefab.GetInstanceID();

        if (_dirty.Contains(instanceID))
        {
            _dirty.Remove(instanceID);
            return;
        }

        var components = prefab.GetComponentsInChildren<Component>(true).GetEnumerator();
        bool dirty = false;
        while (components.MoveNext())
        {
            MethodInfo methodInfo = components.Current.GetType().GetMethod(OnApplyPrefab);
            if (methodInfo != null)
            {
                methodInfo.Invoke(components.Current, null);
                dirty = true;
            }
        }

        if (dirty)
        {
            _dirty.Add(instanceID);
            EditorUtility.SetDirty(prefab);
        }
#endif
    }
}