using UnityEngine;

namespace eagle {
    /// <summary>
    /// Broadcasts a popup panel's screen-space bounds as a global shader property.
    /// Effect shaders discard fragments inside this rect so they don't render over the popup.
    /// Clears the rect on disable so effects render normally when the popup is hidden.
    /// </summary>
    [RequireComponent(typeof(RectTransform))]
    public class PopupClipper : MonoBehaviour {
        private static readonly int PopupClipRectId = Shader.PropertyToID("_PopupClipRect");
        private RectTransform _rect;
        private readonly Vector3[] _corners = new Vector3[4];

        public static void Ensure(GameObject popup) {
            if (!popup.TryGetComponent<PopupClipper>(out _)) { popup.AddComponent<PopupClipper>(); }
        }

        void Awake() { _rect = GetComponent<RectTransform>(); }

        void LateUpdate() {
            _rect.GetWorldCorners(_corners);

            var canvas = GetComponentInParent<Canvas>();
            if (canvas.renderMode == RenderMode.ScreenSpaceOverlay) {
                Shader.SetGlobalVector(
                        PopupClipRectId,
                        new Vector4(_corners[0].x, _corners[0].y, _corners[2].x, _corners[2].y));
            } else {
                var cam = canvas.worldCamera;
                var min = RectTransformUtility.WorldToScreenPoint(cam, _corners[0]);
                var max = RectTransformUtility.WorldToScreenPoint(cam, _corners[2]);
                Shader.SetGlobalVector(PopupClipRectId, new Vector4(min.x, min.y, max.x, max.y));
            }
        }

        void OnDisable() { Shader.SetGlobalVector(PopupClipRectId, Vector4.zero); }
    }
}
