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

[Serializable, VolumeComponentMenu("Post-processing/Snapshot Pro (HDRP)/Drawing")]
public sealed class Drawing : CustomPostProcessVolumeComponent, IPostProcessComponent
{
    [Tooltip("Drawing overlay texture.")]
    public TextureParameter drawingTex = new TextureParameter(null);

    [Tooltip("Time taken (in seconds) per animation cycle. Set to zero for no animation.")]
    public ClampedFloatParameter animCycleTime = new ClampedFloatParameter(1.0f, 0.0f, 5.0f);

    [Tooltip("Strength of the effect.")]
    public ClampedFloatParameter strength = new ClampedFloatParameter(0.5f, 0.0f, 1.0f);

    [Tooltip("Number of times the drawing texture is tiled.")]
    public ClampedFloatParameter tiling = new ClampedFloatParameter(25.0f, 1.0f, 50.0f);

    [Tooltip("Amount of UV smudging based on drawing texture colour values.")]
    public ClampedFloatParameter smudge = new ClampedFloatParameter(0.001f, 0.0f, 5.0f);

    [Tooltip("Pixels past this depth threshold will not be 'drawn on'.")]
    public ClampedFloatParameter depthThreshold = new ClampedFloatParameter(0.99f, 0.0f, 1.01f);

    Material m_Material;

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

    // 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/Drawing";

    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 Drawing effect.");
        }  
    }

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

        bool isOffset = false;

        if (animCycleTime.value > 0.0f)
        {
            isOffset = (Time.time % animCycleTime.value) < (animCycleTime.value / 2.0f);
        }

        m_Material.SetTexture("_DrawingTex", drawingTex.value);
        m_Material.SetFloat("_OverlayOffset", isOffset ? 0.5f : 0.0f);
        m_Material.SetFloat("_Strength", strength.value);
        m_Material.SetFloat("_Tiling", tiling.value);
        m_Material.SetFloat("_Smudge", smudge.value);
        m_Material.SetFloat("_DepthThreshold", depthThreshold.value);
        
        m_Material.SetTexture("_InputTexture", source);
        HDUtils.DrawFullScreen(cmd, m_Material, destination);
    }

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