using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;

namespace DBT
{
    public class SceneBaseShaderGUI : ShaderGUI
    {
        private static class Styles
        {
            public static readonly GUIContent surfaceType = new GUIContent("Surface Type", "选择模式");
            public static readonly GUIContent cullingText = new GUIContent("Render Face", "渲染单反双面");
            public static readonly GUIContent alphaClipText = new GUIContent("Alpha Clipping", "alphaClip");
            public static readonly GUIContent alphaClipThresholdText = new GUIContent("Threshold","Cutoff");
            public static readonly GUIContent MainAlphaLabel = new GUIContent("MainAlpha", "MainAlpha");
    
            public static GUIContent colorLabel = EditorGUIUtility.TrTextContent("Color", "");
            public static GUIContent mainLabel = EditorGUIUtility.TrTextContent("Main(RGBA)", "Main:主贴图(RGBA)+主颜色(RGB)");
            public static GUIContent bumpMapLabel = EditorGUIUtility.TrTextContent("Normalmap", "");
            public static GUIContent normalScale1Label = EditorGUIUtility.TrTextContent("NormalScale", "");
            public static GUIContent detailNormalLabel = EditorGUIUtility.TrTextContent("DetailNormal (RGB)", "");
            public static GUIContent UVSecLabel = EditorGUIUtility.TrTextContent("UVSec", "");
            public static GUIContent normalScale0Label = EditorGUIUtility.TrTextContent("DetailNormalScale", "");
            public static GUIContent blendTexLabel = EditorGUIUtility.TrTextContent("BlendTex (RGB)", "");
            public static GUIContent BlendNormalLabel = EditorGUIUtility.TrTextContent("BlendNormal (RGB)", "");
            public static GUIContent normalScale2Label = EditorGUIUtility.TrTextContent("BlendNormalScale", "");

            //public static string lightText = "[----------Light----------]";        
            // public static GUIContent light1Label = EditorGUIUtility.TrTextContent("Directional Light","");
            // public static GUIContent light2Label = EditorGUIUtility.TrTextContent("LightDir","");
            // public static GUIContent lightDirLabel = EditorGUIUtility.TrTextContent("LightDir","");
            //public static GUIContent hColorLabel = EditorGUIUtility.TrTextContent("HighLight Color","");
            //public static GUIContent lightIntensityLabel = EditorGUIUtility.TrTextContent("HighLight Intensity","");
            public static GUIContent diffuseIntensityLabel = EditorGUIUtility.TrTextContent("Diffuse_Intensity","");
            //public static GUIContent LMStrengthLabel = EditorGUIUtility.TrTextContent("Lightmap强度","");
            //public static GUIContent SMStrengthLabel = EditorGUIUtility.TrTextContent("ShadowMask强度","");

            public static string SpecularText = "[----------Specular----------]";       
            public static GUIContent metalONLabel = EditorGUIUtility.TrTextContent("Metal_ON","");
            public static GUIContent AlphaMetalLabel = EditorGUIUtility.TrTextContent("有透明通道打开使用新增遮罩图","");
            public static GUIContent metallicLabel = EditorGUIUtility.TrTextContent("Metallic","");
            public static GUIContent roughnessLabel = EditorGUIUtility.TrTextContent("Roughness","");
            public static GUIContent SpecStrengthLabel = EditorGUIUtility.TrTextContent("非金属高光强度","");
            public static GUIContent MetalStrengthLabel = EditorGUIUtility.TrTextContent("金属高光强度","");
            //public static GUIContent SkyEnvLabel = EditorGUIUtility.TrTextContent("天空反射球：反射值","");
            public static GUIContent MetalMaskLabel = EditorGUIUtility.TrTextContent("有透明通道时新增遮罩图","");
            public static GUIContent EnvirbrightnessLabel = EditorGUIUtility.TrTextContent("X：整体反射值Y：非金属反射影响度W:受天气颜色程度","");
            //public static GUIContent maxbrightnessLabel = EditorGUIUtility.TrTextContent("反射亮度","");
            //public static GUIContent bloomRangeLabel = EditorGUIUtility.TrTextContent("高光bloom","");
            //public static GUIContent BloomFactorLabel = EditorGUIUtility.TrTextContent("整体bloom","");
            //public static string environmentText = "[----------Environment----------]";       
            public static GUIContent environmentReflectionsLabel = EditorGUIUtility.TrTextContent("Environment Reflections","");
            //public static GUIContent ambientLabel = EditorGUIUtility.TrTextContent("Ambient Color","");
            //public static GUIContent envShadowLabel = EditorGUIUtility.TrTextContent("Env Shadow","");
            public static GUIContent receiveShadowsLabel = EditorGUIUtility.TrTextContent("Receive Shadows","");

            public static readonly GUIContent HSVLabel = new GUIContent("HSV","");
            public static GUIContent colorHSVLabel = EditorGUIUtility.TrTextContent("Color HSV",""); 
            public static GUIContent hueShiftLabel = EditorGUIUtility.TrTextContent("HueShiftW","色相"); 
            public static GUIContent satLabel = EditorGUIUtility.TrTextContent("SaturationW","饱和"); 
            public static GUIContent valLabel = EditorGUIUtility.TrTextContent("BrightnessW","明度");

            public static GUIContent EmissionMapLabel = EditorGUIUtility.TrTextContent("EmissionMap","");

            //public static readonly GUIContent RampLabel = new GUIContent("Ramp","");
            //public static GUIContent rampOnLabel = EditorGUIUtility.TrTextContent("Ramp On",""); 
            //public static GUIContent rampThresholdLabel = EditorGUIUtility.TrTextContent("Ramp Threshold","");
            //public static GUIContent rampSmoothLabel = EditorGUIUtility.TrTextContent("Ramp Smooth","");
            //public static GUIContent sColorLabel = EditorGUIUtility.TrTextContent("SColor","");

            public static readonly GUIContent BlendLabel = new GUIContent("Blend","");
            public static GUIContent useBlendLabel = EditorGUIUtility.TrTextContent("Use Blend","");
            public static GUIContent blendLabel = EditorGUIUtility.TrTextContent("Blend Level","");
            public static GUIContent blendDirectionLabel = EditorGUIUtility.TrTextContent("Blend Direction","");
            public static GUIContent BlendColorLabel = EditorGUIUtility.TrTextContent("Blend Color","");
        }
        
        public enum SurfaceType
        {
            Opaque,
            Transparent
        }
        public enum RenderFace
        {
            Front = 2,
            Back = 1,
            Both = 0
        }

        protected MaterialEditor materialEditor { get; set; }
        protected MaterialProperty surfaceTypeProp { get; set; }
        protected MaterialProperty cullingProp { get; set; }
        protected MaterialProperty alphaClipProp { get; set; }
        protected MaterialProperty alphaCutoffProp { get; set; }
        protected MaterialProperty queueOffsetProp { get; set; }
        MaterialProperty MainAlphaProp = null;

        MaterialProperty Color = null;
        MaterialProperty mainTex = null;
        MaterialProperty bumpMap = null;
        MaterialProperty normalScale1 = null;
        MaterialProperty UVSec = null;
        MaterialProperty detailNormal = null;
        MaterialProperty normalScale0 = null;
        MaterialProperty blendTex = null;
        MaterialProperty BlendNormal = null;
        MaterialProperty normalScale2 = null;

         MaterialProperty bake_MainTex = null; //由于官方URP不支持shadowMask烘培，但shadowmask使用的主要贴图名称是 _MainTex,所有当赋值_BaeMap时，也给_MainTex赋值，shader中需要加入 [HideInInspector] _MainTex("BaseMap", 2D) = "white" {} 

        // MaterialProperty Light1 = null;
        // MaterialProperty Light2 = null;
        // MaterialProperty LightDir = null;
        //MaterialProperty HColor = null;
        //MaterialProperty LightIntensity = null;
        MaterialProperty diffuseIntensity = null;
        //MaterialProperty LMStrength = null;
        //MaterialProperty SMStrength = null;

        MaterialProperty MetalON = null;
        MaterialProperty AlphaMetal = null;
        MaterialProperty Metallic = null;
        MaterialProperty Roughness = null;
        MaterialProperty SpecStrength = null;
        MaterialProperty MetalStrength = null;
        //MaterialProperty SkyEnv = null;
        MaterialProperty MetalMask = null;
        MaterialProperty Envirbrightness = null;
        //MaterialProperty maxbrightness = null;
        //MaterialProperty bloomRange = null;
        //MaterialProperty BloomFactor = null;
        MaterialProperty EnvironmentReflections = null;

        //MaterialProperty Ambient = null;
        //MaterialProperty EnvShadow = null;
        MaterialProperty ReceiveShadows = null;

        MaterialProperty ColorHSV = null;
        MaterialProperty hueShift = null;
        MaterialProperty sat = null;
        MaterialProperty val = null;
        MaterialProperty EMISSION = null;
        MaterialProperty EmissionColor = null;
        MaterialProperty EmissionMap = null;

        //MaterialProperty RampOn = null;
        //MaterialProperty RampThreshold = null;
        //MaterialProperty RampSmooth = null;
        //MaterialProperty SColor = null;

        MaterialProperty UseBlend = null;
        MaterialProperty Blend = null;
        MaterialProperty BlendDirection = null;
        MaterialProperty BlendColor = null;
        bool m_RampFoldout;
        bool m_HSVFoldout;
        bool m_BlendFoldout;
        public MaterialEditor m_MaterialEditor;
        

        public void FindProperties(MaterialProperty[] props)
        {
            surfaceTypeProp = FindProperty("_Surface", props);
            cullingProp = FindProperty("_Cull", props);
            alphaClipProp = FindProperty("_AlphaClip", props);
            alphaCutoffProp = FindProperty("_Cutoff", props);
            MainAlphaProp = FindProperty("_MainAlpha", props);

            Color = FindProperty("_Color", props);
            mainTex = FindProperty("_BaseMap", props);
            bumpMap = FindProperty("_BumpMap", props);
            normalScale1 = FindProperty("_NormalScale1", props);
            UVSec = FindProperty("_UVSec", props);
            detailNormal = FindProperty("_DetailNormal", props);
            normalScale0 = FindProperty("_NormalScale0", props);
            blendTex = FindProperty("_BlendTex", props);
            BlendNormal = FindProperty("_BlendNormal", props);
            normalScale2 = FindProperty("_NormalScale2", props);

            try
            {
                bake_MainTex = FindProperty("_MainTex", props);
            }
            catch (System.Exception ex)
            {
                bake_MainTex = null;
            }

            // Light1 = FindProperty("_Light1", props);
            // Light2 = FindProperty("_Light2", props);
            // LightDir = FindProperty("_LightDir", props);
            //HColor = FindProperty("_HColor", props);
            //LightIntensity = FindProperty("_LightIntensity", props);
            diffuseIntensity = FindProperty("_diffuse_intensity", props);
            //LMStrength = FindProperty("_LM_Strength", props);
            //SMStrength = FindProperty("_SM_Strength", props);

            MetalON = FindProperty("_Metal_ON", props);
            AlphaMetal = FindProperty("_Alpha_Metal", props);
            Metallic = FindProperty("_Metallic", props);
            Roughness = FindProperty("_Roughness", props);
            SpecStrength = FindProperty("_SpecStrength", props);
            MetalStrength = FindProperty("_MetalStrength", props);
            //SkyEnv = FindProperty("_EvnTex", props);
            MetalMask = FindProperty("_Metal_Mask", props);
            Envirbrightness = FindProperty("_envir_brightness", props);
            //maxbrightness = FindProperty("_max_brightness", props);
            //bloomRange = FindProperty("_bloom_range", props);
            //BloomFactor = FindProperty("_BloomFactor", props);
            EnvironmentReflections = FindProperty("_EnvironmentReflections", props);
            //Ambient = FindProperty("_Ambient", props);
            //EnvShadow = FindProperty("_EnvShadow", props);
            ReceiveShadows = FindProperty("_Receive_Shadows", props);

            ColorHSV = FindProperty("_Color_HSV", props);
            hueShift = FindProperty("_HueShift", props);
            sat = FindProperty("_Sat", props);
            val = FindProperty("_Val", props);

            EMISSION = FindProperty("_EMISSION", props);
            EmissionColor = FindProperty("_EmissionColor", props);
            EmissionMap = FindProperty("_EmissionMap", props);

            //RampOn = FindProperty("_Ramp_On", props);
            //RampThreshold = FindProperty("_RampThreshold", props);
            //RampSmooth = FindProperty("_RampSmooth", props);
            //SColor = FindProperty("_SColor", props);
            UseBlend = FindProperty("_Use_Blend", props);
            Blend = FindProperty("_Blend", props);
            BlendDirection = FindProperty("_BlendDirection", props);
            BlendColor = FindProperty("_BlendColor", props);

        }
        public static void SetupMaterialBlendMode(Material material)
        {
            if (material == null)
                throw new ArgumentNullException("material");
            
            bool alphaClip = material.GetFloat("_AlphaClip") == 1;
            if (alphaClip)
            {
                material.EnableKeyword("_ALPHATEST_ON");
            }
            else
            {
                material.DisableKeyword("_ALPHATEST_ON");
            }

            SurfaceType surfaceType = (SurfaceType)material.GetFloat("_Surface");
            if (surfaceType == SurfaceType.Opaque)
            {
                if (alphaClip)
                {
                    material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
                    material.SetOverrideTag("RenderType", "TransparentCutout");
                    material.SetShaderPassEnabled("SRPDefaultUnlit", true);
                }
                else
                {
                    material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Geometry;
                    material.SetOverrideTag("RenderType", "Opaque");
                    material.SetShaderPassEnabled("SRPDefaultUnlit", false);
                    material.SetFloat("_Cutoff", 0);
                }
                //material.renderQueue += queueOffset;
                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
                material.SetInt("_ZWrite", 1);
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                
            }
            else
            {
                var queue = (int) UnityEngine.Rendering.RenderQueue.Transparent;

                material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
                material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
                material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
                // General Transparent Material Settings
                material.SetOverrideTag("RenderType", "Transparent");
                
                if (alphaClip)
                {
                    material.SetInt("_ZWrite", 1);
                }
                else
                {
                    material.SetInt("_ZWrite", 0);
                }
                //material.renderQueue = queue + queueOffset;
                material.renderQueue = queue;
                material.SetShaderPassEnabled("SRPDefaultUnlit", true);
            }
        }
        public void ShaderPropertiesGUI(Material material)
        {
            EditorGUI.BeginChangeCheck();
            {
                //GUILayout.Label(Styles.shaderText, EditorStyles.boldLabel);
                SetupMaterialBlendMode(material);
                if (material == null)
                    throw new ArgumentNullException("material");
                    DoPopup(Styles.surfaceType, surfaceTypeProp, Enum.GetNames(typeof(SurfaceType)));

                EditorGUI.BeginChangeCheck();
                EditorGUI.showMixedValue = cullingProp.hasMixedValue;
                var culling = (RenderFace)cullingProp.floatValue;
                culling = (RenderFace)EditorGUILayout.EnumPopup(Styles.cullingText, culling);
                if (EditorGUI.EndChangeCheck())
                {
                    m_MaterialEditor.RegisterPropertyChangeUndo(Styles.cullingText.text);
                    cullingProp.floatValue = (float)culling;
                    material.doubleSidedGI = (RenderFace)cullingProp.floatValue != RenderFace.Front;
                }

                EditorGUI.showMixedValue = false;

                EditorGUI.BeginChangeCheck();
                EditorGUI.showMixedValue = alphaClipProp.hasMixedValue;
                var alphaClipEnabled = EditorGUILayout.Toggle(Styles.alphaClipText, alphaClipProp.floatValue == 1);
                if (EditorGUI.EndChangeCheck())
                    alphaClipProp.floatValue = alphaClipEnabled ? 1 : 0;
                EditorGUI.showMixedValue = false;

                if (alphaClipProp.floatValue == 1)
                {
                m_MaterialEditor.ShaderProperty(alphaCutoffProp, Styles.alphaClipThresholdText, 1);
                m_MaterialEditor.ShaderProperty(MainAlphaProp, Styles.MainAlphaLabel,1);
                }

                m_MaterialEditor.TexturePropertySingleLine(Styles.mainLabel, mainTex, Color);
                m_MaterialEditor.TexturePropertySingleLine(Styles.bumpMapLabel, bumpMap, normalScale1);
                m_MaterialEditor.TexturePropertySingleLine(Styles.detailNormalLabel, detailNormal,normalScale0,UVSec);
                m_MaterialEditor.TexturePropertySingleLine(Styles.EmissionMapLabel, EmissionMap, EmissionColor,EMISSION);

                //GUILayout.Label(Styles.lightText, EditorStyles.boldLabel);
                // m_MaterialEditor.ShaderProperty(Light1, Styles.light1Label);
                // m_MaterialEditor.ShaderProperty(Light2, Styles.light2Label);
                // m_MaterialEditor.ShaderProperty(LightDir, Styles.lightDirLabel);
                //m_MaterialEditor.ShaderProperty(HColor, Styles.hColorLabel);
                //m_MaterialEditor.ShaderProperty(LightIntensity, Styles.lightIntensityLabel);
                m_MaterialEditor.ShaderProperty(diffuseIntensity, Styles.diffuseIntensityLabel);
                //m_MaterialEditor.ShaderProperty(LMStrength, Styles.LMStrengthLabel);
                //m_MaterialEditor.ShaderProperty(SMStrength, Styles.SMStrengthLabel);
                m_MaterialEditor.ShaderProperty(ReceiveShadows, Styles.receiveShadowsLabel);
                m_MaterialEditor.ShaderProperty(EnvironmentReflections, Styles.environmentReflectionsLabel);

                GUILayout.Label(Styles.SpecularText, EditorStyles.boldLabel);
                m_MaterialEditor.ShaderProperty(MetalON, Styles.metalONLabel);
                m_MaterialEditor.ShaderProperty(AlphaMetal, Styles.AlphaMetalLabel);
                m_MaterialEditor.ShaderProperty(Metallic, Styles.metallicLabel);
                m_MaterialEditor.ShaderProperty(Roughness, Styles.roughnessLabel);
                m_MaterialEditor.ShaderProperty(SpecStrength, Styles.SpecStrengthLabel);
                m_MaterialEditor.ShaderProperty(MetalStrength, Styles.MetalStrengthLabel);
                m_MaterialEditor.ShaderProperty(Envirbrightness, Styles.EnvirbrightnessLabel);
                //m_MaterialEditor.TexturePropertySingleLine(Styles.SkyEnvLabel,SkyEnv,maxbrightness);
                m_MaterialEditor.TexturePropertySingleLine(Styles.MetalMaskLabel,MetalMask);
                //m_MaterialEditor.ShaderProperty(bloomRange, Styles.bloomRangeLabel);
                //m_MaterialEditor.ShaderProperty(BloomFactor, Styles.BloomFactorLabel);

                //GUILayout.Label(Styles.environmentText, EditorStyles.boldLabel);
                //m_MaterialEditor.ShaderProperty(Ambient, Styles.ambientLabel);
                //m_MaterialEditor.ShaderProperty(EnvShadow, Styles.envShadowLabel);

                EditorGUI.BeginChangeCheck();
                m_HSVFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(m_HSVFoldout, Styles.HSVLabel);
                if (m_HSVFoldout)
                {
                    m_MaterialEditor.ShaderProperty(ColorHSV, Styles.colorHSVLabel);
                    m_MaterialEditor.ShaderProperty(hueShift, Styles.hueShiftLabel);
                    m_MaterialEditor.ShaderProperty(sat, Styles.satLabel);
                    m_MaterialEditor.ShaderProperty(val, Styles.valLabel);
                    EditorGUILayout.Space();
                }
                EditorGUILayout.EndFoldoutHeaderGroup();

                EditorGUI.BeginChangeCheck();

                //EditorGUI.BeginChangeCheck();
                //m_RampFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(m_RampFoldout, Styles.RampLabel);
                //if (m_RampFoldout)
                //{
                //    //DrawAdvancedOptions(material);
                //    m_MaterialEditor.ShaderProperty(RampOn, Styles.rampOnLabel);
                //    m_MaterialEditor.ShaderProperty(RampThreshold, Styles.rampThresholdLabel);
                //    m_MaterialEditor.ShaderProperty(RampSmooth, Styles.rampSmoothLabel);
                //    m_MaterialEditor.ShaderProperty(SColor, Styles.sColorLabel);
                //    EditorGUILayout.Space();
                //}
                //EditorGUILayout.EndFoldoutHeaderGroup();
                
                EditorGUI.BeginChangeCheck();
                m_BlendFoldout = EditorGUILayout.BeginFoldoutHeaderGroup(m_BlendFoldout, Styles.BlendLabel);
                if (m_BlendFoldout)
                {
                    m_MaterialEditor.ShaderProperty(blendTex, Styles.blendTexLabel);
                    m_MaterialEditor.TexturePropertySingleLine(Styles.BlendNormalLabel, BlendNormal, normalScale2);
                    m_MaterialEditor.ShaderProperty(BlendColor, Styles.BlendColorLabel);
                    m_MaterialEditor.ShaderProperty(UseBlend, Styles.useBlendLabel);
                    m_MaterialEditor.ShaderProperty(Blend, Styles.blendLabel);
                    m_MaterialEditor.ShaderProperty(BlendDirection, Styles.blendDirectionLabel);
                    EditorGUILayout.Space();
                }
                EditorGUILayout.EndFoldoutHeaderGroup();

                EditorGUILayout.Space();   
            }

            if (bake_MainTex != null && mainTex != null)
            {
                bake_MainTex.textureValue = mainTex.textureValue;
            }
            if (EditorGUI.EndChangeCheck())
            {
                
            }
        }

        public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props)
        {
            if (materialEditor == null)
                throw new ArgumentNullException("materialEditor");
            //base.FindProperties(props);
            FindProperties(props);
            m_MaterialEditor = materialEditor;
            Material material = materialEditor.target as Material;
            //base.ShaderPropertiesGUI(material);
            ShaderPropertiesGUI(material);
            m_MaterialEditor.RenderQueueField();
            m_MaterialEditor.EnableInstancingField();
        }
         public void DoPopup(GUIContent label, MaterialProperty property, string[] options)
        {
            DoPopup(label, property, options, m_MaterialEditor);
        }

        public static void DoPopup(GUIContent label, MaterialProperty property, string[] options, MaterialEditor materialEditor)
        {
            if (property == null)
                throw new ArgumentNullException("property");

            EditorGUI.showMixedValue = property.hasMixedValue;

            var mode = property.floatValue;
            EditorGUI.BeginChangeCheck();
            mode = EditorGUILayout.Popup(label, (int)mode, options);
            if (EditorGUI.EndChangeCheck())
            {
                materialEditor.RegisterPropertyChangeUndo(label.text);
                property.floatValue = mode;
            }

            EditorGUI.showMixedValue = false;
        }
        
    }
}
