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

namespace UnityEngine.Rendering.Universal
{


    [Serializable]
    //[PostProcess(typeof(SunshaftRenderer), PostProcessEvent.BeforeStack, "Custom/Sunshaft")]
    //public sealed class Sunshaft : PostProcessEffectSettings
    //{

    //    [ColorUsage(true), Tooltip("Custom color to use for sun shaft.")]
    //    public UnityEngine.Rendering.PostProcessing.ColorParameter color = new UnityEngine.Rendering.PostProcessing.ColorParameter { value = Color.black };

    //    public override bool IsEnabledAndSupported(PostProcessRenderContext context)
    //    {
    //        return enabled.value && color.value.a > 0f;
    //// #if UNITY_EDITOR
    ////         return enabled.value && color.value.a > 0f && 
    ////             EnvironmentSystem.instance != null &&
    ////             EnvironmentSystem.instance.m_sun != null;
    //// #else
    ////         return enabled.value && color.value.a > 0f && 
    ////         EnvironmentSystem.instance != null &&
    ////         EnvironmentSystem.instance.m_sun != null &&
    ////         (SystemInfo.graphicsDeviceType != GraphicsDeviceType.Direct3D11 &&
    ////         SystemInfo.graphicsDeviceType != GraphicsDeviceType.Direct3D12);
    //// #endif
    //    }

    //}

    public class SunshaftRenderer
    {

        static readonly int s_sunshaft_tempRtA_ID = Shader.PropertyToID("_sunshaft_tempRtA");
        static readonly int s_sunshaft_tempRtB_ID = Shader.PropertyToID("_sunshaft_tempRtB");

        static readonly int m_ScreenLightPos_ID = Shader.PropertyToID("_ScreenLightPos");
        static readonly int m_Alpha_ID = Shader.PropertyToID("_Alpha");
        static readonly int m_GodRayTex_ID = Shader.PropertyToID("_GodRayTex");
        static readonly int m_ShaftColor_ID = Shader.PropertyToID("_ShaftColor");
        Vector3 LightPos_WorldSpace;
        Vector3 lightScreenPos;
        RenderTargetIdentifier m_tempRtA = new RenderTargetIdentifier(s_sunshaft_tempRtA_ID);
        RenderTargetIdentifier m_tempRtB = new RenderTargetIdentifier(s_sunshaft_tempRtB_ID);
        int m_screenHeight = -1;
        int m_screenWidth = -1;
        bool m_bCreateRT = false;

        public void Setup()
        {
           
          
        }

        public void Release(CommandBuffer cmd)
        {
            if (m_bCreateRT == true)
            {
                cmd.ReleaseTemporaryRT(s_sunshaft_tempRtA_ID);
                cmd.ReleaseTemporaryRT(s_sunshaft_tempRtB_ID);
            }
            m_bCreateRT = false;

        }
        public DepthTextureMode GetCameraFlags()
        {
            return Camera.main.depthTextureMode;
        }
        public bool Render(CommandBuffer cmd,
            ScriptableRenderContext context, 
            ref RenderingData renderingData, 
            FastPostProcess.PostProcessSettings settings,
            RenderTargetIdentifier source,
            RenderTargetIdentifier destination)
        {
            bool ret = false;

            //CommandBuffer cmd = CommandBufferPool.Get("SunShaft");

            cmd.BeginSample("Sunshaft");
           
            if (context != null && settings.SunShaft_Material != null)
            {
                Camera camera = renderingData.cameraData.camera;
                Vector3 sunDir = settings.SunShaft_SunDir;
                LightPos_WorldSpace = camera.transform.position + sunDir * 5000;
                lightScreenPos = camera.WorldToScreenPoint(LightPos_WorldSpace);

                if (IsBackLighting(ref renderingData)/* &&
                    (settings.SunShat_Timeline >= 6 && settings.SunShat_Timeline <= 18)*/)
                {
                    

                    Material material = settings.SunShaft_Material;

                    

                    CheckRenderTexture(cmd, context, ref renderingData); 
                    Vector4 screenLightPos = new Vector4(lightScreenPos.x / camera.pixelWidth, lightScreenPos.y / camera.pixelHeight, 0, 0);
                    // TODO :set color
                    material.SetColor(m_ShaftColor_ID, settings.SunShaft_Color);
                    material.SetVector(m_ScreenLightPos_ID, screenLightPos);
                    //sunShaft.properties.SetFloat(m_Alpha_ID, Mathf.Pow(Vector3.Dot(lightDirct, X2Interface.ICameraHelper.Instance.MainCameraTransform.forward), 3.0f));
                    material.SetFloat(m_Alpha_ID, 1 - (Mathf.Pow((screenLightPos.x - 0.5f), 4f) + Mathf.Pow((screenLightPos.y - 0.5f), 4f)) * 8f);

                    cmd.BlitFullscreenTriangle(m_tempRtA, m_tempRtB, material, 0, false, true);
                    cmd.BlitFullscreenTriangle(m_tempRtB, m_tempRtA, material, 1, false, true);
                    cmd.SetGlobalTexture(m_GodRayTex_ID, m_tempRtA);
                    cmd.BlitFullscreenTriangle(source, destination, material, 2, false, true);
                    ret = true;
                }
                else
                {
                    //#if UNITY_EDITOR && SCENE_EDITOR
                    //                cmd.BlitFullscreenTriangle(context.source, context.destination);
                    //#else
                    //                    context.destination = context.source;
                    //#endif

                    ret = false;
                }
            }
            else
            {
                ret = false;
            }
            cmd.EndSample("Sunshaft");

            //context.ExecuteCommandBuffer(cmd);
            //CommandBufferPool.Release(cmd);

            return ret;
        }

        void CheckRenderTexture(CommandBuffer cmd, ScriptableRenderContext context, ref RenderingData renderingData)
        {
            m_bCreateRT = true;
            //if (renderingData.cameraData.camera.scaledPixelHeight != m_screenHeight || renderingData.cameraData.camera.scaledPixelWidth != m_screenWidth)
            //    Release(cmd);
            

            RenderTextureDescriptor opaqueDesc = renderingData.cameraData.cameraTargetDescriptor;
            m_screenHeight = opaqueDesc.height;
            m_screenWidth = opaqueDesc.width; 

            CreateRenderTexture(cmd, s_sunshaft_tempRtA_ID, 4, ref renderingData);
            CreateRenderTexture(cmd, s_sunshaft_tempRtB_ID, 4, ref renderingData);
        }

        void CreateRenderTexture(CommandBuffer cmd, int id, int scale, ref RenderingData renderingData)
        {
            RenderTextureDescriptor desc = renderingData.cameraData.cameraTargetDescriptor;
            desc.depthBufferBits = 0;
            desc.width = m_screenWidth / scale;
            desc.height = m_screenHeight / scale;
            desc.useMipMap = false;
            desc.colorFormat = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGB111110Float) ? RenderTextureFormat.RGB111110Float : RenderTextureFormat.ARGBHalf;
            cmd.GetTemporaryRT(id, desc, FilterMode.Bilinear);        }


        bool IsBackLighting(ref RenderingData renderingData)
        {
            return lightScreenPos.z > 0 &&
                lightScreenPos.x > 0 &&
                lightScreenPos.x < renderingData.cameraData.camera.pixelWidth &&
                lightScreenPos.y > 0 &&
                lightScreenPos.y < renderingData.cameraData.camera.pixelHeight;
        }

    }
}   // namespace UnityEngine.Rendering.Universal