﻿using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using System;

[Serializable, VolumeComponentMenu("Post-processing/Snapshot Pro (HDRP)/Cutout")]
public sealed class Cutout : CustomPostProcessVolumeComponent, IPostProcessComponent
{
    [Tooltip("Enable the effect?")]
    public BoolParameter enabled = new BoolParameter(false);

    [Tooltip("The texture to use for the cutout.")]
    public TextureParameter cutoutTexture = new TextureParameter(null);

    [Tooltip("The colour of the area outside the cutout.")]
    public ColorParameter borderColor = new ColorParameter(Color.white);

    [Tooltip("Should the cutout texture stretch to fit the screen's aspect ratio?")]
    public BoolParameter stretch = new BoolParameter(false);

    [Tooltip("How zoomed-in the texture is. 1 = unzoomed.")]
    public ClampedFloatParameter zoom = new ClampedFloatParameter(1.0f, 0.01f, 10.0f);

    [Tooltip("How offset the texture is from the centre of the screen (in UV space).")]
    public Vector2Parameter offset = new Vector2Parameter(Vector2.zero);

    [Range(0.0f, 360.0f), Tooltip("How much the texture is rotated (anticlockwise, in degrees).")]
    public ClampedFloatParameter rotation = new ClampedFloatParameter(0.0f, 0.0f, 360.0f);

    Material m_Material;

    public bool IsActive() => m_Material != null && enabled.value;

    // Remember to add this post process in the Custom Post Process Orders list 
    // (Project Settings > HDRP Default Settings).
    public override CustomPostProcessInjectionPoint injectionPoint => 
        CustomPostProcessInjectionPoint.AfterPostProcess;

    const string kShaderName = "SnapshotProHDRP/Cutout";

    public override void Setup()
    {
        if (Shader.Find(kShaderName) != null)
        {
            m_Material = new Material(Shader.Find(kShaderName));
        }
        else
        {
            Debug.LogError($"Unable to find shader '{kShaderName}' for the Cutout effect.");
        }  
    }

    public override void Render(CommandBuffer cmd, HDCamera camera, RTHandle source, RTHandle destination)
    {
        if (m_Material == null)
        {
            return;
        }

        m_Material.SetTexture("_CutoutTex", cutoutTexture.value);
        m_Material.SetColor("_BorderColor", borderColor.value);
        m_Material.SetInt("_Stretch", stretch.value ? 1 : 0);
        m_Material.SetFloat("_Zoom", zoom.value);
        m_Material.SetVector("_Offset", offset.value);
        m_Material.SetFloat("_Rotation", rotation.value * Mathf.Deg2Rad);
        m_Material.SetTexture("_InputTexture", source);
        HDUtils.DrawFullScreen(cmd, m_Material, destination);
    }

    public override void Cleanup()
    {
        CoreUtils.Destroy(m_Material);
    }
}
