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

namespace TFramework
{
    [CustomEditor(typeof(Transform))]
    public class TransfromInspector : Editor
    {
        Texture w;
        Texture l;

        [SerializeField]
        bool isW = false;
        [SerializeField]
        bool isL = true;

        Transform trans;
        GUIContent wGC;
        GUIContent lGC;
        GUIContent cGC;

        bool IsCantPaste => !string.IsNullOrEmpty(EditorGUIUtility.systemCopyBuffer) && EditorGUIUtility.systemCopyBuffer.Contains("Vector3(");
        private SerializedProperty m_Scale;
        private Type constrainProportionsTransformScale;
        private SerializedProperty m_ConstrainProportionsScaleProperty;
        private object m_ConstrainProportionsScale;
        private MethodInfo co_Initialize;
        private MethodInfo co_Static_GetMixedValueFields;
        private MethodInfo co_DoGUI;
        private MethodInfo co_Static_IsBit;
        private MethodInfo co_Static_HandleMultiSelectionScaleChanges;
        private GUIContent scaleContent = EditorGUIUtility.TrTextContent("缩放", "GameObject相对于父对象的局部缩放", icon:null);
        private GUIContent positionContent = EditorGUIUtility.TrTextContent("位置", "", icon: null);
        private GUIContent rotateContent = EditorGUIUtility.TrTextContent("旋转", "", icon: null);
        private bool m_IsScaleDirty;

        private void OnEnable()
        {
            w = AssetDatabase.LoadAssetAtPath<Texture>("Assets/TFramework/Editor/Texture/W_icon.png");
            l = AssetDatabase.LoadAssetAtPath<Texture>("Assets/TFramework/Editor/Texture/L_icon.png");
            trans = target as Transform;
            wGC = new GUIContent(w, "显示世界坐标");
            lGC = new GUIContent(l, "显示本地坐标");
            cGC = new GUIContent();
            cGC.tooltip = "按比例约束缩放";
            m_Scale = serializedObject.FindProperty("m_LocalScale");
            m_ConstrainProportionsScaleProperty = serializedObject.FindProperty("m_ConstrainProportionsScale");
            constrainProportionsTransformScale = Type.GetType("UnityEditor.ConstrainProportionsTransformScale,UnityEditor");
            ConstructorInfo constructor = constrainProportionsTransformScale.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(Vector3) }, null);
            m_ConstrainProportionsScale = constructor.Invoke(new object[] { m_Scale.vector3Value });

            co_Initialize = constrainProportionsTransformScale.GetMethod("Initialize", BindingFlags.NonPublic | BindingFlags.Instance);
            co_Static_GetMixedValueFields= constrainProportionsTransformScale.GetMethod("GetMixedValueFields", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
            co_DoGUI= constrainProportionsTransformScale.GetMethod("DoGUI", BindingFlags.NonPublic | BindingFlags.Instance);
            co_Static_IsBit= constrainProportionsTransformScale.GetMethod("IsBit", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
            co_Static_HandleMultiSelectionScaleChanges= constrainProportionsTransformScale.GetMethod("HandleMultiSelectionScaleChanges", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
        }

        public override void OnInspectorGUI()
        {
            serializedObject.Update();
            //base.OnInspectorGUI();
            using (new EditorGUILayout.HorizontalScope())
            {
                GUI.backgroundColor = isW ? Color.white : Color.gray;
                if (GUILayout.Button(wGC, GUILayout.Width(20), GUILayout.Height(20)))
                {
                    isW = true;
                    isL = false;
                }
                GUI.backgroundColor = Color.white;
                GUI.backgroundColor = isL ? Color.white : Color.gray;
                if (GUILayout.Button(lGC, GUILayout.Width(20), GUILayout.Height(20)))
                {
                    isL = true;
                    isW = false;
                }
                GUI.backgroundColor = Color.white;
            }

            if (isW)
            {
                using (new EditorGUILayout.HorizontalScope())
                {
                    trans.position = EditorGUILayout.Vector3Field(positionContent, trans.position);
                    if (GUILayout.Button("复制", GUILayout.ExpandWidth(false)))
                    {
                        string v3 = $"new Vector3({trans.position.x}f,{trans.position.y}f,{trans.position.z}f)";
                        EditorGUIUtility.systemCopyBuffer = v3;
                    }
                    GUI.enabled = IsCantPaste;
                    if (GUILayout.Button("粘贴", GUILayout.ExpandWidth(false)))
                    {
                        trans.position = AnalysisString(EditorGUIUtility.systemCopyBuffer);
                    }
                    GUI.enabled = true;
                }
                using (new EditorGUILayout.HorizontalScope())
                {
                    trans.rotation = Quaternion.Euler(EditorGUILayout.Vector3Field(rotateContent, trans.rotation.eulerAngles));
                    if (GUILayout.Button("复制", GUILayout.ExpandWidth(false)))
                    {
                        string v3 = $"new Vector3({trans.rotation.eulerAngles.x}f,{trans.rotation.eulerAngles.y}f,{trans.rotation.eulerAngles.z}f)";
                        EditorGUIUtility.systemCopyBuffer = v3;
                    }
                    GUI.enabled = IsCantPaste;
                    if (GUILayout.Button("粘贴", GUILayout.ExpandWidth(false)))
                    {
                        trans.rotation = Quaternion.Euler(AnalysisString(EditorGUIUtility.systemCopyBuffer));
                    }
                    GUI.enabled = true;
                }
            }
            else
            {
                using (new EditorGUILayout.HorizontalScope())
                {
                    trans.localPosition = EditorGUILayout.Vector3Field(positionContent, trans.localPosition);
                    if (GUILayout.Button("复制", GUILayout.ExpandWidth(false)))
                    {
                        string v3 = $"new Vector3({trans.localPosition.x}f,{trans.localPosition.y}f,{trans.localPosition.z}f)";
                        EditorGUIUtility.systemCopyBuffer = v3;
                    }
                    GUI.enabled = IsCantPaste;
                    if (GUILayout.Button("粘贴", GUILayout.ExpandWidth(false)))
                    {
                        trans.localPosition = AnalysisString(EditorGUIUtility.systemCopyBuffer);
                    }
                    GUI.enabled = true;
                }
                using (new EditorGUILayout.HorizontalScope())
                {
                    trans.localRotation = Quaternion.Euler(EditorGUILayout.Vector3Field(rotateContent, trans.localRotation.eulerAngles));
                    if (GUILayout.Button("复制", GUILayout.ExpandWidth(false)))
                    {
                        string v3 = $"new Vector3({trans.localRotation.eulerAngles.x}f,{trans.localRotation.eulerAngles.y}f,{trans.localRotation.eulerAngles.z}f)";
                        EditorGUIUtility.systemCopyBuffer = v3;
                    }
                    GUI.enabled = IsCantPaste;
                    if (GUILayout.Button("粘贴", GUILayout.ExpandWidth(false)))
                    {
                        trans.localRotation = Quaternion.Euler(AnalysisString(EditorGUIUtility.systemCopyBuffer));
                    }
                    GUI.enabled = true;
                }
            }
            bool isScaleDirty = m_IsScaleDirty;
            if (isScaleDirty)
            {
                serializedObject.Update();
            }
            using (new EditorGUILayout.HorizontalScope())
            {
                bool flag = trans != null && (bool)co_Initialize.Invoke(m_ConstrainProportionsScale, new object[] {serializedObject.targetObjects }) && this.m_ConstrainProportionsScaleProperty != null;
                if (flag)
                {
                    int num = -1;
                    uint mixedValueFields = (uint)co_Static_GetMixedValueFields.Invoke(null,new object[] {this.m_Scale });
                    Vector3 vector = (Vector3)co_DoGUI.Invoke(m_ConstrainProportionsScale,new object[] { EditorGUILayout.GetControlRect(true, Array.Empty<GUILayoutOption>()), scaleContent, this.m_Scale.vector3Value, base.serializedObject.targetObjects, num, this.m_Scale, this.m_ConstrainProportionsScaleProperty });
                    uint mixedValueFields2 = (uint)co_Static_GetMixedValueFields.Invoke(null, new object[] { this.m_Scale });
                    bool flag2 = vector != this.m_Scale.vector3Value || mixedValueFields != mixedValueFields2;
                    if (flag2)
                    {
                        bool flag3 = serializedObject.targetObjects.Length > 1;
                        if (flag3)
                        {
                            bool flag4 = mixedValueFields != mixedValueFields2;
                            if (flag4)
                            {
                                num = -1;
                                for (int i = 0; i < 3; i++)
                                {
                                    bool flag5 = (bool)co_Static_IsBit.Invoke(null,new object[] { mixedValueFields, i }) && !(bool)co_Static_IsBit.Invoke(null,new object[] { mixedValueFields2, i });
                                    if (flag5)
                                    {
                                        num = i;
                                        break;
                                    }
                                }
                            }
                            bool flag6 = num != -1;
                            if (flag6)
                            {
                                this.m_IsScaleDirty = (bool)co_Static_HandleMultiSelectionScaleChanges.Invoke(null,new object[] 
                                { m_Scale.vector3Value, vector,  
                                    constrainProportionsTransformScale.GetProperty("constrainProportionsScale", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(m_ConstrainProportionsScale), 
                                    serializedObject.targetObjects, num });
                            }
                        }
                        bool flag7 = vector != this.m_Scale.vector3Value;
                        if (flag7)
                        {
                            m_Scale.vector3Value = vector;
                        }
                    }
                }
                else
                {
                    EditorGUILayout.PropertyField(m_Scale, scaleContent, Array.Empty<GUILayoutOption>());
                }


                if (GUILayout.Button("复制", GUILayout.ExpandWidth(false)))
                {
                    string v3 = $"new Vector3({trans.localScale.x}f,{trans.localScale.y}f,{trans.localScale.z}f)";
                    EditorGUIUtility.systemCopyBuffer = v3;
                }
                GUI.enabled = IsCantPaste;
                if (GUILayout.Button("粘贴", GUILayout.ExpandWidth(false)))
                {
                    trans.localScale = AnalysisString(EditorGUIUtility.systemCopyBuffer);
                }
                GUI.enabled = true;
            }
            serializedObject.ApplyModifiedProperties();
            bool isScaleDirty2 = m_IsScaleDirty;
            if (isScaleDirty2)
            {
                m_IsScaleDirty = false;
                EditorGlobalTool.GetTypeInEditorAssemblies("UnityEditor", "Editor").GetMethod("OnForceReloadInspector", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(this,null);
               
            }
        }

        private Vector3 AnalysisString(string str)
        {
            string v3 = str;
            Vector3 vec3 = Vector3.zero;
            if (v3.Contains("Vector3("))
            {
                v3 = v3.Substring(v3.IndexOf("Vector3(") + 8);
                v3 = v3.Remove(v3.IndexOf(')'));
                v3 = v3.Replace("f", "");
                string[] value = v3.Split(',');
                vec3 = new Vector3(float.Parse(value[0]), float.Parse(value[1]), float.Parse(value[2]));
            }
            return vec3;
        }
    }
}
