using System;
using UnityEngine;
using UnityEngine.Rendering.PostProcessing;

[Serializable]
[PostProcess(typeof(GlitchRenderer), PostProcessEvent.AfterStack, "Custom/Glitch")]
public sealed class Glitch : PostProcessEffectSettings
{
	[Range(0f, 1f), Tooltip("Glitch effect intensity.")]
	public FloatParameter blend = new FloatParameter { value = 0.5f };

	public TextureParameter displacementMap = new TextureParameter();

	[Header("Glitch Intensity")]
	[Range(0, 1)]
	public FloatParameter flipIntensity = new FloatParameter();

	[Range(0, 1)]
	public FloatParameter colorIntensity = new FloatParameter();
}

public sealed class GlitchRenderer : PostProcessEffectRenderer<Glitch>
{
	float glitchup, glitchdown, flicker, glitchupTime = 0.05f, glitchdownTime = 0.05f, flickerTime = 0.5f;

	public override void Render(PostProcessRenderContext context)
	{
		var sheet = context.propertySheets.Get(Shader.Find("Hidden/Custom/Glitch"));

		sheet.properties.SetFloat("_Blend", settings.blend);

		sheet.properties.SetFloat("_ColorIntensity", settings.colorIntensity);
		sheet.properties.SetTexture("_DispTex", settings.displacementMap);

		flicker += Time.deltaTime * settings.colorIntensity;

		if(flicker > flickerTime)
		{
			sheet.properties.SetFloat("filterRadius", UnityEngine.Random.Range(-3f, 3f) * settings.colorIntensity);
			sheet.properties.SetVector("direction", Quaternion.AngleAxis(UnityEngine.Random.Range(0, 360) * settings.colorIntensity, Vector3.forward) * Vector4.one);
			flicker = 0;
			flickerTime = UnityEngine.Random.value;
		}

		if(settings.colorIntensity == 0)
			sheet.properties.SetFloat("filterRadius", 0);

		glitchup += Time.deltaTime * settings.flipIntensity;

		if(glitchup > glitchupTime)
		{
			if(UnityEngine.Random.value < 0.1f * settings.flipIntensity)
				sheet.properties.SetFloat("flip_up", UnityEngine.Random.Range(0, 1f) * settings.flipIntensity);
			else
				sheet.properties.SetFloat("flip_up", 0);

			glitchup = 0;
			glitchupTime = UnityEngine.Random.value / 10f;
		}

		if(settings.flipIntensity == 0)
			sheet.properties.SetFloat("flip_up", 0);


		glitchdown += Time.deltaTime * settings.flipIntensity;

		if(glitchdown > glitchdownTime)
		{
			if(UnityEngine.Random.value < 0.1f * settings.flipIntensity)
				sheet.properties.SetFloat("flip_down", 1 - UnityEngine.Random.Range(0, 1f) * settings.flipIntensity);
			else
				sheet.properties.SetFloat("flip_down", 1);

			glitchdown = 0;
			glitchdownTime = UnityEngine.Random.value / 10f;
		}

		if(settings.flipIntensity == 0)
			sheet.properties.SetFloat("flip_down", 1);

		if(UnityEngine.Random.value < 0.05 * settings.blend)
		{
			sheet.properties.SetFloat("displace", UnityEngine.Random.value * settings.blend);
			sheet.properties.SetFloat("scale", 1 - UnityEngine.Random.value * settings.blend);
		}
		else
			sheet.properties.SetFloat("displace", 0);

		context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, 0);
	}
}