using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class DrawFullscreenPass : ScriptableRenderPass
{
    public FilterMode FilterMode { get; set; }
    public DrawFullscreenFeature.Settings Settings { get; set; }

    private RenderTargetIdentifier _source;
    private RenderTargetIdentifier _destination;
    private int _temporaryRTId = Shader.PropertyToID("TempRT");

    private int _sourceId;
    private int _destinationId;
    private bool _isSourceAndDestinationSameTarget;

    private string _profilerTag;

    public DrawFullscreenPass(string tag)
    {
        _profilerTag = tag;
    }

    public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    {
        RenderTextureDescriptor blitTargetDescriptor = renderingData.cameraData.cameraTargetDescriptor;
        blitTargetDescriptor.depthBufferBits = 0;
        _isSourceAndDestinationSameTarget =
            Settings.sourceType == Settings.destinationType &&
            (Settings.sourceType == BufferType.CameraColor ||
             Settings.sourceTextureId == Settings.destinationTextureId);

        var renderer = renderingData.cameraData.renderer;
        if (Settings.sourceType == BufferType.CameraColor)
        {
            _sourceId = -1;
            _source = renderer.cameraColorTarget;
        }
        else
        {
            _sourceId = Shader.PropertyToID(Settings.sourceTextureId);
            cmd.GetTemporaryRT(_sourceId, blitTargetDescriptor, FilterMode);
            _source = new RenderTargetIdentifier(_sourceId);
        }

        if (_isSourceAndDestinationSameTarget)
        {
            _destinationId = _temporaryRTId;
            cmd.GetTemporaryRT(_destinationId, blitTargetDescriptor, FilterMode);
            _destination = new RenderTargetIdentifier(_destinationId);
        }
        else if (Settings.destinationType == BufferType.CameraColor)
        {
            _destinationId = -1;
            _destination = renderer.cameraColorTarget;
        }
        else
        {
            _destinationId = Shader.PropertyToID(Settings.destinationTextureId);
            cmd.GetTemporaryRT(_destinationId, blitTargetDescriptor, FilterMode);
            _destination = new RenderTargetIdentifier(_destinationId);
        }
    }

    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
        CommandBuffer cmd = CommandBufferPool.Get(_profilerTag);

        if (_isSourceAndDestinationSameTarget)
        {
            cmd.Blit(_source, _destination, Settings.blitMaterial, Settings.blitMaterialPassIndex);
            cmd.Blit(_destination, _source);
        }
        else
        {
            cmd.Blit(_source, _destination, Settings.blitMaterial, Settings.blitMaterialPassIndex);
        }
        
        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
    }

    public override void FrameCleanup(CommandBuffer cmd)
    {
        if (_destinationId != -1)
        {
            cmd.ReleaseTemporaryRT(_destinationId);
        }

        if (_source == _destination && _source != -1)
        {
            cmd.ReleaseTemporaryRT(_sourceId);
        }
    }
}