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

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

    [Tooltip("Texture to overlay onto each mosaic tile.")]
    public TextureParameter overlayTexture = new TextureParameter(null);

    [Tooltip("Colour of texture overlay.")]
    public ColorParameter overlayColor = new ColorParameter(Color.white);

    [Tooltip("Number of tiles on the x-axis.")]
    public ClampedIntParameter tileSize = new ClampedIntParameter(50, 10, 400);

    [Tooltip("Use sharper point filtering when downsampling?")]
    public BoolParameter usePointFiltering = new BoolParameter(true);

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

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

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

        if(overlayTexture.value != null)
        {
            m_Material.SetTexture("_OverlayTex", overlayTexture.value);
        }
        else
        {
            m_Material.SetTexture("_OverlayTex", Texture2D.whiteTexture);
        }

        int xTileCount = Mathf.FloorToInt((float)source.rt.width / tileSize.value);
        int yTileCount = Mathf.FloorToInt((float)source.rt.height / tileSize.value);

        m_Material.SetColor("_OverlayColor", overlayColor.value);
        m_Material.SetFloat("_XTileCount", xTileCount);
        m_Material.SetFloat("_YTileCount", yTileCount);

        m_Material.SetTexture("_InputTexture", source);

        HDUtils.DrawFullScreen(cmd, m_Material, destination);

        //cmd.Blit(source.rt, tmp, m_Material, 0);
        //cmd.Blit(tmp, destination.rt, m_Material, 1);
    }

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