using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;

using UnityEngine;
using UnityEngine.UI;
using Utility;
using Object = UnityEngine.Object;

public class CustomStateController : MonoBehaviour, ISerializationCallbackReceiver
{
    [Flags]
    [Serializable]
    public enum UIStateType
    {
        Null = 0,
        Scale = 2,
        Active = 4,
        Position = 8,
        Rotation = 16,
        RBSize = 32,
        ImageColor = 64,
        TextColor = 128,
        Icon = 256,
    }


    [Serializable]
    public class UIStateData
    {
        public List<StateInfo> StateInfos;

        public UIStateData()
        {
            StateInfos = new List<StateInfo>();
        }
    }


    [Serializable]
    public class StateInfo
    {
        [SerializeField] public GameObject Target;

        //v4专用数据源
        [SerializeField] public List<UIStateType> UIStateV4Types;
        [SerializeField] public List<Vector4> UIStateV4Datas;

        //Str 专用数据源
        [SerializeField] public List<UIStateType> UIStateStrTypes;
        [SerializeField] public List<string> UIStateStrDatas;
    }


    [SerializeField] public List<UIStateData> data = new List<UIStateData>();


    public List<Object> AllComs = new List<Object>();

    [SerializeField]
    public List<UIStateType> AllComsStateTypes = new List<UIStateType>();

    public int CurrIndex;


    public void AddData()
    {
        data.Add(CreatData());
        CurrIndex = data.Count - 1;
    }

    public void RemoveData(int index)
    {
        data.RemoveAt(index);
        CurrIndex = data.Count - 1;
        if (data.Count == 0)
        {
            ChangeState(-1);
        }
    }

    public void SaveData()
    {
        data[CurrIndex] = CreatData();
    }


    public UIStateData CreatData()
    {
        UIStateData uiStateData = new UIStateData();


        for (var i = 0; i < AllComs.Count; i++)
        {
            Object _object = AllComs[i];

            if (_object == null)
            {
                Debug.LogError("保存状态数据的目标为空");
                continue;
            }


            GameObject go = AllComs[i] as GameObject;
            if (go == null)
            {
                Debug.LogError("保存状态数据的目标为空");
                continue;
            }

            StateInfo stateInfo = new StateInfo();

            stateInfo.UIStateV4Datas = new List<Vector4>();
            stateInfo.UIStateV4Types = new List<UIStateType>();


            stateInfo.Target = AllComs[i] as GameObject;

            if (AllComsStateTypes[i].HasFlag(UIStateType.Active))
            {
                Vector4 vector4 = new Vector4();
                vector4.x = go.gameObject.activeSelf ? 1 : 0;

                stateInfo.UIStateV4Types.Add(UIStateType.Active);
                stateInfo.UIStateV4Datas.Add(vector4);
            }

            if (AllComsStateTypes[i].HasFlag(UIStateType.Position))
            {
                Vector4 vector4 = go.GetComponent<RectTransform>().anchoredPosition;

                stateInfo.UIStateV4Types.Add(UIStateType.Position);
                stateInfo.UIStateV4Datas.Add(vector4);
            }


            if (AllComsStateTypes[i].HasFlag(UIStateType.Scale))
            {
                Vector4 vector4 = go.GetComponent<RectTransform>().localScale;

                stateInfo.UIStateV4Types.Add(UIStateType.Scale);
                stateInfo.UIStateV4Datas.Add(vector4);
            }

            if (AllComsStateTypes[i].HasFlag(UIStateType.Rotation))
            {
                Vector4 vector4 = go.GetComponent<RectTransform>().localRotation.eulerAngles;

                stateInfo.UIStateV4Types.Add(UIStateType.Rotation);
                stateInfo.UIStateV4Datas.Add(vector4);
            }

            if (AllComsStateTypes[i].HasFlag(UIStateType.RBSize))
            {
                Vector4 vector4 = go.GetComponent<RectTransform>().sizeDelta;

                stateInfo.UIStateV4Types.Add(UIStateType.RBSize);
                stateInfo.UIStateV4Datas.Add(vector4);
            }

            if (AllComsStateTypes[i].HasFlag(UIStateType.ImageColor))
            {
                Vector4 vector4 = go.GetComponent<Image>().color;

                stateInfo.UIStateV4Types.Add(UIStateType.ImageColor);
                stateInfo.UIStateV4Datas.Add(vector4);
            }

            if (AllComsStateTypes[i].HasFlag(UIStateType.TextColor))
            {
                Vector4 vector4 = go.GetComponent<Text>().color;

                stateInfo.UIStateV4Types.Add(UIStateType.TextColor);
                stateInfo.UIStateV4Datas.Add(vector4);
            }

         
            
            if (AllComsStateTypes[i].HasFlag(UIStateType.Icon))
            {
                if (stateInfo.UIStateStrDatas == null)
                {
                    stateInfo.UIStateStrDatas = new List<string>();
                    stateInfo.UIStateStrTypes = new List<UIStateType>();
                }

                string str = go.GetComponent<Image>().sprite.ToString();

                stateInfo.UIStateStrTypes.Add(UIStateType.Icon);
                stateInfo.UIStateStrDatas.Add(str);
            }


            uiStateData.StateInfos.Add(stateInfo);
        }

        return uiStateData;
    }


    public void ChangeState(int selectIndex)
    {
        if (selectIndex < 0)
        {
            return;
        }

        CurrIndex = selectIndex;
        UIStateData uiStateData = data[selectIndex];


        foreach (var keyValuePair in uiStateData.StateInfos)
        {
            GameObject go = keyValuePair.Target;
            if (go == null)
            {
                Debug.LogError("保存状态数据的目标不存在");
                continue;
            }

            if (keyValuePair.UIStateV4Types != null)
            {
                for (var i = 0; i < keyValuePair.UIStateV4Types.Count; i++)
                {
                    switch (keyValuePair.UIStateV4Types[i])
                    {
                        case UIStateType.Active:
                            bool active;
                            
                            active = Math.Abs(keyValuePair.UIStateV4Datas[i].x - 1) < 0.00001;

                            go.gameObject.SetActive(active);
                            break;
                        case UIStateType.Position:
                            Vector2 pos = keyValuePair.UIStateV4Datas[i];
                            go.GetComponent<RectTransform>().anchoredPosition = pos;
                            break;

                        case UIStateType.Scale:
                            Vector3 scale = keyValuePair.UIStateV4Datas[i];
                            go.GetComponent<RectTransform>().localScale = scale;
                            break;
                        case UIStateType.Rotation:
                            Quaternion rotation = Quaternion.Euler(keyValuePair.UIStateV4Datas[i]);

                            go.GetComponent<RectTransform>().localRotation = rotation;
                            break;
                        case UIStateType.RBSize:
                            Vector2 sizeDelta = keyValuePair.UIStateV4Datas[i];
                            go.GetComponent<RectTransform>().sizeDelta = sizeDelta;
                            break;
                        case UIStateType.ImageColor:
                            Color imageColorData = keyValuePair.UIStateV4Datas[i];
                            go.GetComponent<Image>().color = imageColorData;
                            break;
                        case UIStateType.TextColor:
                            Color textColorData = keyValuePair.UIStateV4Datas[i];
                            go.GetComponent<Text>().color = textColorData;
                            break;
                       
                    }
                }
            }


            if (keyValuePair.UIStateStrTypes != null)
            {
                for (var i = 0; i < keyValuePair.UIStateStrTypes.Count; i++)
                {
                    switch (keyValuePair.UIStateStrTypes[i])
                    {
                    
                        case UIStateType.Icon:
                            string iconName = keyValuePair.UIStateStrDatas[i];
                            go.GetComponent<Image>().sprite = Resources.Load<Sprite>("Sprite/"+iconName);
                            break;
                    }
                }
            }
        }
    }


    public void OnBeforeSerialize()
    {
    }

    public void OnAfterDeserialize()
    {
    }
}