using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Experimental.Rendering.Universal;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
using UnityEngine.UI;

public class parallaxCloudFeature : ScriptableRendererFeature
{
    [System.Serializable]
    public class ParallaxCloudSettings
    {
        public string passTag = "parallax cloud";
        public RenderTexture renderTexture = null;
    }

    [System.Serializable]
    public class FilterSettings
    {
        // TODO: expose opaque, transparent, all ranges as drop down
        public RenderQueueType RenderQueueType = RenderQueueType.Transparent;
        public LayerMask LayerMask = ~0;
        public string[] PassNames = { "ParallaxCloud" };

        public FilterSettings()
        {
            RenderQueueType = RenderQueueType.Transparent;
            LayerMask = ~0;
        }
    }

    public ParallaxCloudSettings settings = new ParallaxCloudSettings();

    ParallaxCloudRenderPass cloudPass;

    public override void Create()
    {
        FilterSettings filter = new FilterSettings();
        cloudPass = new ParallaxCloudRenderPass(settings.passTag, RenderPassEvent.BeforeRenderingTransparents, settings.renderTexture, filter.PassNames,
            filter.RenderQueueType, filter.LayerMask);
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        if (ParallaxCloud.cloudCount > 0)
        {
            renderer.EnqueuePass(cloudPass);
        }
    }
}

public class ParallaxCloudRenderPass : ScriptableRenderPass
{
    RenderQueueType renderQueueType;
    FilteringSettings m_FilteringSettings;
    string m_ProfilerTag;
    RenderTexture renderTexture = null;
    ProfilingSampler m_ProfilingSampler;

    List<ShaderTagId> m_ShaderTagIdList = new List<ShaderTagId>();

    RenderStateBlock m_RenderStateBlock;

    static readonly int sp_Parallax_Cloud_Rt_size = Shader.PropertyToID("_Parallax_Cloud_Rt_size");

    public ParallaxCloudRenderPass(string profilerTag, RenderPassEvent renderPassEvent, RenderTexture renderTexture, string[] shaderTags, RenderQueueType renderQueueType, int layerMask)
    {
        m_ProfilerTag = profilerTag;
        m_ProfilingSampler = new ProfilingSampler(profilerTag);
        this.renderPassEvent = renderPassEvent;
        this.renderTexture = renderTexture;
        this.renderQueueType = renderQueueType;
        RenderQueueRange renderQueueRange = (renderQueueType == RenderQueueType.Transparent)
            ? RenderQueueRange.transparent
            : RenderQueueRange.opaque;
        m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask);

        if (shaderTags != null && shaderTags.Length > 0)
        {
            foreach (var passName in shaderTags)
                m_ShaderTagIdList.Add(new ShaderTagId(passName));
        }
        else
        {
            m_ShaderTagIdList.Add(new ShaderTagId("UniversalForward"));
            m_ShaderTagIdList.Add(new ShaderTagId("LightweightForward"));
            m_ShaderTagIdList.Add(new ShaderTagId("SRPDefaultUnlit"));
        }

        m_RenderStateBlock = new RenderStateBlock(RenderStateMask.Nothing);
    }

    public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
    {
        base.Configure(cmd, cameraTextureDescriptor);

        ConfigureTarget(new RenderTargetIdentifier(renderTexture));
        ConfigureClear(ClearFlag.All, Color.clear);
    }

    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
        SortingCriteria sortingCriteria = (renderQueueType == RenderQueueType.Transparent)
            ? SortingCriteria.CommonTransparent
            : renderingData.cameraData.defaultOpaqueSortFlags;

        DrawingSettings drawingSettings = CreateDrawingSettings(m_ShaderTagIdList, ref renderingData, sortingCriteria);

        CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag);
        using (new ProfilingScope(cmd, m_ProfilingSampler))
        {
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();
            cmd.SetGlobalVector(sp_Parallax_Cloud_Rt_size, new Vector4(renderTexture.width, renderTexture.height));
            context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref m_FilteringSettings,
                ref m_RenderStateBlock);
        }
        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
    }
}



