using UnityEngine;

namespace Thousandto.Launcher.ExternalLibs
{
    public class AnimBloom : MonoBehaviour
    {
        [SerializeField]
        int m_downSampleFactor = 4;

        [SerializeField]
        int m_blurIterations = 1;

        [SerializeField]
        [Range(0.25f, 5.0f)]
        private float m_blurSize = 1.0f;

        [SerializeField]
        [Range(0.0f, 2.0f)]
        float m_threshhold = 0.78f;

        [SerializeField]
        [Range(0.0f, 2.5f)]
        float m_intensity = 0.75f;      // downSample ctrl, color adjust

        private Shader ms_downSampleShader = null;
        private Shader ms_gaussianBlurShader = null;
        private Shader ms_compositeShader = null;

        private Material ms_downSampleMaterial = null;
        private Material ms_gaussianBlurMaterial = null;
        private Material ms_compositeMaterial = null;

        void OnDestroy()
        {
            OnDisable();
        }

        void OnRenderImage(RenderTexture source, RenderTexture destination)
        {
            CheckResources();
            int width = source.width / m_downSampleFactor;
            int height = source.width / m_downSampleFactor;

            RenderTexture rt = RenderTexture.GetTemporary(width, height, 0, source.format);
            rt.filterMode = FilterMode.Bilinear;
            rt.antiAliasing = 1;
            rt.name = "RenderTexture4";

            // down sample and extract
            ms_downSampleMaterial.SetVector("_Parameter", new Vector4(1.0f, 0.0f, m_threshhold, m_intensity));
            Graphics.Blit(source, rt, ms_downSampleMaterial);

            // do gaussian blur 
            for (int i = 0; i < m_blurIterations; ++i)
            {
                //v blur
                RenderTexture rt1 = RenderTexture.GetTemporary(width, height, 0, source.format);
                rt1.name = "RenderTexture5";
                rt1.antiAliasing = 1;
                rt1.filterMode = FilterMode.Bilinear;
                ms_gaussianBlurMaterial.SetVector("_Parameter", new Vector4(0.0f, 1.0f, (m_blurSize + (i * 1.0f)), 0.0f));
                Graphics.Blit(rt, rt1, ms_gaussianBlurMaterial);
                RenderTexture.ReleaseTemporary(rt);
                rt = rt1;

                // h blur
                rt1 = RenderTexture.GetTemporary(width, height, 0, source.format);
                rt1.name = "RenderTexture6";
                rt1.filterMode = FilterMode.Bilinear;
                rt1.antiAliasing = 1;
                ms_gaussianBlurMaterial.SetVector("_Parameter", new Vector4(1.0f, 0.0f, (m_blurSize + (i * 1.0f)), 0.0f));
                Graphics.Blit(rt, rt1, ms_gaussianBlurMaterial);
                RenderTexture.ReleaseTemporary(rt);
                rt = rt1;
            }

            // composite bloom
            ms_compositeMaterial.SetTexture("_BloomTex", rt);
            Graphics.Blit(source, destination, ms_compositeMaterial);
            RenderTexture.ReleaseTemporary(rt);
        }

        void OnDisable()
        {
            if (ms_downSampleMaterial != null)
            {
                UnityEngine.Object.Destroy(ms_downSampleMaterial);
                ms_downSampleMaterial = null;
            }
            if (ms_gaussianBlurMaterial != null)
            {
                UnityEngine.Object.Destroy(ms_gaussianBlurMaterial);
                ms_gaussianBlurMaterial = null;
            }
            if (ms_compositeMaterial != null)
            {
                UnityEngine.Object.Destroy(ms_compositeMaterial);
                ms_compositeMaterial = null;
            }
        }

        void OnEnable()
        {
            CheckResources();
        }

        void CheckResources()
        {
            if (ms_downSampleShader == null)
                ms_downSampleShader = ShaderFactory.Find("Ares/Bloom/BloomExtractPass");
            if (ms_gaussianBlurShader == null)
                ms_gaussianBlurShader = ShaderFactory.Find("Ares/Bloom/BloomGaussianBlurPass");
            if (ms_compositeShader == null)
                ms_compositeShader = ShaderFactory.Find("Ares/Bloom/BloomCompositePass");
            if (ms_downSampleMaterial == null)
                ms_downSampleMaterial = new Material(ms_downSampleShader);
            if (ms_gaussianBlurMaterial == null)
                ms_gaussianBlurMaterial = new Material(ms_gaussianBlurShader);
            if (ms_compositeMaterial == null)
                ms_compositeMaterial = new Material(ms_compositeShader);
        }
    }
}