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

namespace UnityEditor.SLZMaterialUI
{
    public class EmissionToggleField : Toggle, BaseMaterialField
    {
        
        public int shaderPropertyIdx;
        public int GetShaderPropIdx() { return shaderPropertyIdx; }
        public MaterialProperty materialProperty;
        bool isIntField = false;
        string keyword;
        public delegate void BeforeChangeEvent(ChangeEvent<bool> evt);
        public void Initialize(MaterialProperty materialProperty, int shaderPropertyIdx, string keyword, bool isIntField, bool noStyle = false)
        {
            this.materialProperty = materialProperty;
            this.shaderPropertyIdx = shaderPropertyIdx;
            this.isIntField = isIntField;
            this.keyword = keyword;
            this.RegisterValueChangedCallback(OnChangedEvent);
            bool state = false;
            if (isIntField)
            {
                state = materialProperty.intValue != 0 ? true : false;
            }
            else
            {
                state = materialProperty.floatValue > 0 ? true : false;
            }

            this.SetValueWithoutNotify(state);
            
            style.marginRight = 3;
            if (materialProperty.hasMixedValue)
            {
                this.showMixedValue = true;
            }
            
            if (!noStyle)
            {
                label = materialProperty.displayName;
                SetFullLineStyle();
            }
        }
        public void SetFullLineStyle()
        {
            VisualElement label = this.ElementAt(0);
            label.AddToClassList("materialGUILeftBox");
            label.style.overflow = Overflow.Hidden;
            label.style.minWidth = 0;
            VisualElement color = this.ElementAt(1);
            color.AddToClassList("materialGUIRightBox");
            style.justifyContent = Justify.FlexStart;
        }
        public void OnChangedEvent(ChangeEvent<bool> evt)
        {
            
            if (isIntField)
            {
                materialProperty.intValue = evt.newValue ? 1 : 0;
            }
            else
            {
                materialProperty.floatValue = evt.newValue ? 1 : 0;
            }
            
        
            Object[] targets = materialProperty.targets;
            int numMats = targets.Length;
            // Setting the value through the materialProperty already recorded an undo, append to that
            Undo.RecordObjects(targets, Undo.GetCurrentGroupName());

            SetKeywordOnTargets(evt.newValue);
            SetGIFlagsOnTargets(evt.newValue);

            Undo.CollapseUndoOperations(Undo.GetCurrentGroup());
            Undo.IncrementCurrentGroup();

            this.showMixedValue = false;
        }

        void SetKeywordOnTargets(bool value) 
        { 
        
            if (keyword != null)
            {
                Object[] materials = materialProperty.targets;
                int numMaterials = materials.Length;
                Shader s = (materials[0] as Material).shader;
                LocalKeyword kw = new LocalKeyword(s, keyword);             
                for (int i = 0; i < numMaterials; i++) 
                {
                    (materials[0] as Material).SetKeyword(kw, value);
                }
            }
        }
        void SetGIFlagsOnTargets(bool state)
        {

            Object[] materials = materialProperty.targets;
            int numMaterials = materials.Length;
           
            for (int i = 0; i < numMaterials; i++)
            {
                (materials[0] as Material).globalIlluminationFlags = state ? MaterialGlobalIlluminationFlags.BakedEmissive : MaterialGlobalIlluminationFlags.EmissiveIsBlack;
            }

        }
        public void UpdateMaterialProperty(MaterialProperty boundProp)
        {
            materialProperty = boundProp;
            bool state = false;
            if (isIntField)
            {
                state = materialProperty.intValue != 0 ? true : false;
            }
            else
            {
                state = materialProperty.floatValue > 0 ? true : false;
            }
            if (value != state)
            {
                this.SetValueWithoutNotify(state);
            }
            this.showMixedValue = materialProperty.hasMixedValue;
        }
    }
}