// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
#if UNITY_EDITOR
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Animancer.Editor
{
    /// [Editor-Only]
    /// Allows any object to be highlighted in the GUI like with
    /// .
    /// 
    /// https://kybernetik.com.au/animancer/api/Animancer.Editor/ObjectHighlightGUI
    /// 
    public static class ObjectHighlightGUI
    {
        /************************************************************************************************************************/
        /// The highlight will start by expanding then contracting over this duration.
        public const double ExpandDuration = 0.5f;
        /// After the  the highlight will fade out over this duration.
        public const double LingerDuration = 2;
        /// The size that the highlight expands to.
        public const float HighlightSize = 5;
        /// The colour used to highlight the pinged object.
        public static readonly Color HighlightColor = EditorGUIUtility.isProSkin
            ? new(0.8f, 0.6f, 0.2f, 0.4f)
            : new(1, 0.75f, 0.25f, 0.4f);
        /// 
        public static double CurrentTime => EditorApplication.timeSinceStartup;
        /************************************************************************************************************************/
        /// The object currently being highlighted.
        public static object Target { get; private set; }
        /// The time when the highlight was started.
        public static double StartTime { get; private set; }
        /************************************************************************************************************************/
        /// Sets the target object to start highlighting it.
        public static void Highlight(object target)
        {
            if (target is Object unityObject)
            {
                EditorGUIUtility.PingObject(unityObject);
                return;
            }
            Target = target;
            StartTime = CurrentTime;
        }
        /************************************************************************************************************************/
        /// Draws the highlight if the given `target` is the current .
        public static void Draw(Rect area, object target)
        {
            if (Target != target ||
                Event.current.type != EventType.Repaint)
                return;
            var elapsedTime = CurrentTime - StartTime;
            if (elapsedTime < ExpandDuration + LingerDuration)
            {
                if (elapsedTime < ExpandDuration)
                {
                    var size = HighlightSize * Mathf.Sin((float)(elapsedTime / ExpandDuration * Mathf.PI));
                    area.x -= size;
                    area.y -= size;
                    area.width += size * 2;
                    area.height += size * 2;
                }
                elapsedTime /= ExpandDuration + LingerDuration;
                var color = HighlightColor;
                color.a *= (float)(1 - elapsedTime);
                EditorGUI.DrawRect(area, color);
                InternalEditorUtility.RepaintAllViews();
            }
            else
            {
                Target = null;
            }
        }
        /************************************************************************************************************************/
    }
}
#endif