using UnityEngine;
using UnityEngine.Rendering.Universal;

namespace ImpactCFX.Decals.URP
{
    [AddComponentMenu("Impact CFX/Decal/Impact Decal (URP)")]
    /// <summary>
    /// A decal with special features specific to the URP decal projector.
    /// </summary>
    public class ImpactDecalURP : ImpactDecal
    {
        [Tooltip("The URP decal projector component.")]
        [SerializeField]
        private DecalProjector decalProjector;
        [Tooltip("Choose a random decal from an atlas?")]
        [SerializeField]
        private bool useAtlas;
        [Tooltip("The UV region to use for the decals.")]
        [SerializeField]
        private Rect atlasUVRegion = new Rect(0, 0, 1, 1);
        [Tooltip("The number of decal tiles in the atlas.")]
        [SerializeField]
        private Vector2Int atlasTiles;
        [Tooltip("Should the decal fade over time?")]
        [SerializeField]
        private bool fadeOverTime;
        [Tooltip("The time before the decal begins to fade.")]
        [SerializeField]
        private float lifeTime;
        [Tooltip("Once fading, how long the decal takes to fade out.")]
        [SerializeField]
        private float fadeTime;
        [Tooltip("Curve for tweaking the fade opacity.")]
        [SerializeField]
        private AnimationCurve fadeCurve = AnimationCurve.Linear(0, 1, 1, 0);

        private float timer;

        private void Reset()
        {
            decalProjector = GetComponentInChildren<DecalProjector>();
        }

        protected override void placeDecal(CollisionResultData collisionResultData)
        {
            base.placeDecal(collisionResultData);

            timer = 0;

            if (useAtlas)
            {
                Vector2Int randomCoordinates = new Vector2Int(Random.Range(0, atlasTiles.x), Random.Range(0, atlasTiles.y));
                Vector2 d = new Vector2(atlasUVRegion.width / atlasTiles.x, atlasUVRegion.height / atlasTiles.y);

                Rect rect = new Rect(atlasUVRegion.x + randomCoordinates.x * d.x,
                    atlasUVRegion.y + randomCoordinates.y * d.y,
                    d.x,
                    d.y);

                decalProjector.uvBias = rect.min;
                decalProjector.uvScale = rect.size;
            }

            if (fadeOverTime)
            {
                decalProjector.fadeFactor = 1;
            }
        }

        public override void UpdatePooledObject()
        {
            if (fadeOverTime)
            {
                timer += Time.deltaTime;

                if (timer > lifeTime)
                {
                    float fade = fadeCurve.Evaluate((timer - lifeTime) / fadeTime);
                    decalProjector.fadeFactor = fade;

                    if (fade <= 0)
                    {
                        ReturnToPool();
                    }
                }
            }

            base.UpdatePooledObject();

            //Override NeedsUpdate to always be true if fading.
            if (fadeOverTime)
            {
                NeedsUpdate = true;
            }
        }
    }
}