using UnityEngine;

namespace eagle {
    /// <summary>
    /// Broadcasts the viewport's screen-space bounds as a global shader property each frame.
    /// Attach to the Scroll View's Viewport GameObject.
    /// Shaders that declare float4 _ViewportClipRect receive (xMin, yMin, xMax, yMax) in pixels.
    /// </summary>
    [RequireComponent(typeof(RectTransform))]
    public class ViewportClipper : MonoBehaviour {
        private static readonly int ViewportClipRectId = Shader.PropertyToID("_ViewportClipRect");
        private RectTransform _rect;
        private readonly Vector3[] _corners = new Vector3[4];

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

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

            var canvas = GetComponentInParent<Canvas>();
            if (canvas.renderMode == RenderMode.ScreenSpaceOverlay) {
                // World corners are already in screen pixels for overlay canvases
                Shader.SetGlobalVector(
                        ViewportClipRectId,
                        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(ViewportClipRectId, new Vector4(min.x, min.y, max.x, max.y));
            }
        }
    }
}
