using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using Excel2Json;
using Fort23.Core;
using Fort23.UTool;

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

using UnityEngine.UI;
using Utility;
using EventSystem = UnityEngine.EventSystems.EventSystem;

namespace Fort23.Mono
{
    public enum UILayer
    {
        Bottom, //最底层UI（主界面）
        Middle, //中间UI（各种Panel）
        Top, //最顶层UI节点
        Loading, // 加载界面
    }

    /// <summary>
    /// 销毁类型
    /// </summary>
    public enum UIDestroyType
    {
        DelayDestroy,
        ImmediatelyDestroy,
        NotDestroy,
    }

    /// <summary>
    /// 如果有同时弹出多个UI界面冲突的地方，推荐用async/await的方法一次操作，这样就不用单独去为了适配打开多个UI的需求而改动太多的代码（主要是这样改动会牺牲大部分情况下的性能）
    /// </summary>
    public class UIManager : Entity
    {
        public static UIManager Instance { get; set; }

        // public RectTransform UIRootTransform;
        public Vector2 sizeDelta;

        public EventSystem current;

        /// <summary>
        /// 父节点（InitClip）
        /// </summary>
        private Transform _parent;

        /// <summary>
        /// 所有展示BG的ui
        /// </summary>
        public List<UIPanel> AllShowBGUIs = new List<UIPanel>();

        /// <summary>
        /// 顶部ui列表 可以通过导航栏跳转的界面
        /// </summary>
        public List<UIPanel> TopUIPanels = new List<UIPanel>();

        /// <summary>
        /// 所有top层ui
        /// </summary>
        public List<UIPanel> NoFocusTopUIPanels = new List<UIPanel>();

        /// <summary>
        /// 预先定好的几个层，数量和UILayer对应
        /// </summary>
        // public Canvas[] canvases = new Canvas[3];
        public Camera UICamera;

        public Canvas Canvas;
        public Transform[] UILayers = new Transform[4];

        /// <summary>
        /// 当前打开的ui
        /// </summary>
        public UIPanel currOpenPanel;


        /// <summary>
        /// UI布局大小
        /// </summary>
        private Vector2 UIScale;


        private BetterList<UIPanel> _lastShowPanel = new BetterList<UIPanel>();

        private Graphic currDeapthGraphic;

        /// <summary>
        /// 需要销毁的UI
        /// </summary>
        public Dictionary<string, UIPanel> destroyUI = new Dictionary<string, UIPanel>();

        public CustomCameraStack CurrCustomCameraStack
        {
            get { return _currCustomCameraStack; }
            set
            {
                _currCustomCameraStack = value;
                RefreshFull();
            }
        }
        
        public void CleanLastShowPanel()
        {
            _lastShowPanel.Clear();
        }
        
        private CustomCameraStack _currCustomCameraStack;

        /// <summary>
        /// 屏蔽字库
        /// </summary>
        public string MaskWordData;

        /// <summary>
        /// 展示文字提示长度
        /// </summary>
        public int ShowTextCount;

        /// <summary>
        /// 展示文字提示最大长度
        /// </summary>
        public int ShowTextMaxCount = 1;

        /// <summary>
        /// 上一个界面
        /// </summary>
        public UIPanel LastUIPanel;

        [CustomMethod(CustomMethodType.Awake)]
        public async void Awake(Transform parent)
        {
            Instance = this;
            _parent = parent;
        }

        public async CTask InitUI()
        {
            if (Canvas == null)
            {
                AssetHandle assetBundle =
                    await AssetBundleLoadManager.Instance.LoadAssetAsyncTask<GameObject>("Canvas.prefab");
                GameObject prefab = assetBundle.AssetObject<GameObject>();
                // UIRootTransform = prefab.GetComponent<RectTransform>();
                sizeDelta = prefab.GetComponent<RectTransform>().sizeDelta;
                if (1.0f * Screen.width / Screen.height < 1334f / 750f)
                {
                    sizeDelta = new Vector2(1334, 750);
                }

                // return;
                Canvas = prefab.GetComponent<Canvas>();
                prefab.transform.SetParent(_parent);
                UILayers[0] = prefab.transform.GetChild(0);
                UILayers[1] = prefab.transform.GetChild(1);
                UILayers[2] = prefab.transform.GetChild(2);
                UILayers[3] = prefab.transform.GetChild(3);
                UICamera = prefab.transform.GetComponentInChildren<Camera>();

              
            }

            // if (MaskWordData == null)
            // {
            //     AssetHandle assetBundle =
            //         await AssetBundleLoadManager.Instance.LoadAssetAsyncTask<TextAsset>("guofu.txt");
            //     TextAsset text = assetBundle.AssetObject<TextAsset>();
            //     MaskWordData = text.text;
            //     assetBundle.Release();
            // }
        }


        public RectTransform GetLayer(UILayer layer)
        {
            try
            {
                int index = (int)layer;

                return (RectTransform)UILayers[index];
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }

        public void SetEventSystemEnable(bool value)
        {
            // current.isClose = !value;
        }

        [CustomMethod(CustomMethodType.Update)]
        public async void Update()
        {
            if (currDeapthGraphic != null)
            {
                UGUIIamgeTool.minDepth = currDeapthGraphic.canvasRenderer.absoluteDepth;
                UGUIIamgeTool.renderOrder = currDeapthGraphic.canvas.renderOrder;
            }
            else
            {
                UGUIIamgeTool.minDepth = -1;
                UGUIIamgeTool.renderOrder = 0;
            }

           
            
        }

        /// <summary>
        /// 隐藏当前全部的UIPanel(只是不显示，不是销毁)  排除不在隐藏之列的UI
        /// </summary>
        public void HindCurrAllShowPanel()
        {
            if (_lastShowPanel.Count > 0)
            {
                return;
            }

            _lastShowPanel.Clear();
            UIPanel[] allShowPanel = GetComponentAll<UIPanel>();
            for (int i = 0; i < allShowPanel.Length; i++)
            {
                

                if (allShowPanel[i].GObjectPoolInterface.activeSelf)
                {
                    allShowPanel[i].GObjectPoolInterface.SetActive(false);
                    _lastShowPanel.Add(allShowPanel[i]);
                }
            }
        }

        public async CTask ShowLastHindAllShowPanel()
        {
            for (int i = 0; i < _lastShowPanel.Count; i++)
            {
                if (_lastShowPanel[i].GObjectPoolInterface != null)
                {
                    _lastShowPanel[i].GObjectPoolInterface.SetActive(true);
                }
            }


            if (_lastShowPanel.Contains(TopUIPanels[^1]))
            {
                _lastShowPanel.Clear();
                if (TopUIPanels[^1].isShow)
                {
                    await TopUIPanels[^1].GetFocus();
                }
            }

            _lastShowPanel.Clear();
        }

        /// <summary>
        /// 用窗口打开某个界面(不可重复的预设，适用于一切带有关闭按钮的窗口UI) 
        /// </summary>
        /// <param name="callback"> ui加载完成时的回调</param>
        /// <param name="layer"> ui需要显示在那一层，现在分为3层</param>
        /// <param name="isFocus"> 是否时需要获取焦点</param>
        /// <param name="uiData">打开UI时的透传数据</param>
        /// <param name="isShowBG">是否需要显示统一的背板</param>
        /// isFullUI 是否是全面屏UI
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public async CTask<T> LoadAndOpenPanel<T>(Action<T> callback, UILayer layer = UILayer.Middle,
            bool isFocus = true, object[] uiData = null, bool isShowBG = false, bool isFullUI = false,
            bool isActiveAnima = true)
            where T : UIPanel, new()
        {
            try
            {
                Type type;
                current = EventSystem.current;

                type = typeof(T);
                T uiPanel;
                // 获取UI绑定属性
                UIBindingAttribute uiBindingAttribute =
                    type.GetCustomAttribute(typeof(UIBindingAttribute)) as UIBindingAttribute;
                if (uiBindingAttribute == null)
                {
                    LogTool.Error($"类型{type.Name}没有添加UIBindingAttribute!");
                    // ShowTips($"类型{buildType.Name}没有添加UIBindingAttribute!");
                    return null;
                }

                // TDManager.Instance.PartCount(uiBindingAttribute.prefab);
                if (isFocus)
                {
                    if (currOpenPanel != null)
                    {
                        if (currOpenPanel.isShow)
                        {
                            await currOpenPanel.LoseFocus();
                            currOpenPanel = null;
                        }
                        else
                        {
                            currOpenPanel = null;
                        }
                    }
                }


                using (await CoroutineLockComponent.Instance.Wait(uiBindingAttribute.prefab))
                {
                    if (current != null)
                    {
                        // current.isClose = true;
                    }


                    // 不可以重复打开Panel，但是可以把上一个拿来使用。
                    if (!Components.ContainsKey(type))
                    {
                        GameObject gameObjectPool = await FetchUI(uiBindingAttribute, GetLayer(layer));
                        if (gameObjectPool == null)
                            return null;
                        uiPanel = AddComponent<T, GameObject>(gameObjectPool, false);
                        uiPanel.uiName = uiBindingAttribute.prefab;
                        uiPanel.isFocus = isFocus;
                        await uiPanel.SetUIGameObject(gameObjectPool);
                        gameObjectPool.SetActive(false);
                    }
                    else
                    {
                        uiPanel = GetComponent<T>();
                        if (uiPanel.DestroyTimerEntity != null)
                        {
                            TimerComponent.Instance.Remove(uiPanel.DestroyTimerEntity.ID);
                            uiPanel.DestroyTimerEntity.Destroy();
                        }

                        destroyUI.Remove(uiBindingAttribute.prefab);
                    }

                    uiPanel.isFullUI = isFullUI;
                    // 等待数据准备好才初始化UI
                    if (await uiPanel.AsyncInit(uiData))
                    {
                        if (uiPanel.IsBreadcrumbBarPanel) //打开界面之前判断是否已经在堆栈当中 如果是就移除此界面往后的堆栈 保持他时在堆栈的最上方
                        {
                            if (TopUIPanels.Contains(uiPanel))
                            {
                                int index = TopUIPanels.IndexOf(uiPanel);
                                int count = TopUIPanels.Count - index;

                                for (int i = index + 1; i < TopUIPanels.Count; i++)
                                {
                                    if (TopUIPanels[i].isShow)
                                    {
                                        HideUIUIPanel(TopUIPanels[i]);
                                    }
                                }


                                TopUIPanels.RemoveRange(index, count);
                            }
                        }

                        if (layer == UILayer.Top && !NoFocusTopUIPanels.Contains(uiPanel))
                            NoFocusTopUIPanels.Add(uiPanel);
                        uiPanel.isActiveAnima = isActiveAnima;
                        await uiPanel.Open();


                        if (current != null)
                        {
                            // current.isClose = false;
                        }


                        await TimerComponent.Instance.WaitAsync(1); //等待一帧 让渲染完成后在执行完成逻辑
                        callback?.Invoke(uiPanel);

                    

                        RefreshFull();

                      
                        if (isShowBG)
                        {
                            uiPanel.IsShowCustomBGPanel = true;
                            if (!AllShowBGUIs.Contains(uiPanel))
                                AllShowBGUIs.Add(uiPanel);
                            // await GetBackgroundPanel(uiPanel);
                        }

                        return uiPanel;
                    }
                    else
                    {
                        if (current != null)
                        {
                            // current.isClose = false;
                        }

                        // 界面数据没准备好，因此本次操作将被销毁
                        LogTool.Log($"数据准备失败，请检查{type.Name}的Init方法中的逻辑");
                        // ShowTips($"数据准备失败，请检查{buildType.Name}的Init方法中的逻辑");
                        uiPanel.Close();
                        return null;
                    }
                }
            }
            catch (Exception e)
            {
                if (current != null)
                {
                    // current.isClose = false;
                }

                LogTool.Error(typeof(T).ToString() + "  " + e.Message);
                LogTool.Exception(e);
                return null;
            }
        }

        public void RefreshFull()
        {
            Graphic min = null;
            UIPanel[] allPanel = GetComponentAll<UIPanel>();
            if (allPanel == null)
            {
                return;
            }

            for (int i = 0; i < allPanel.Length; i++)
            {
                UIPanel panel = allPanel[i];
                if (panel != null && panel.minDepth != null && !panel.IsClose && panel.isShow && panel.GObjectPoolInterface.activeSelf && panel.isFullUI)
                {
                    if (min == null)
                    {
                        min = panel.minDepth;
                        continue;
                    }

                    if (min != null && panel.minDepth.canvasRenderer.absoluteDepth > min.canvasRenderer.absoluteDepth)
                    {
                        min = panel.minDepth;
                    }
                }
            }

            if (min != null)
            {
                UGUIIamgeTool.minDepth = min.canvasRenderer.absoluteDepth;
                UGUIIamgeTool.renderOrder = min.canvas.renderOrder;
            }
            else
            {
                UGUIIamgeTool.minDepth = -1;
                UGUIIamgeTool.renderOrder = 0;
            }

            currDeapthGraphic = min;

            if (_currCustomCameraStack == null)
            {
                // URPTool.Instance.IsNotRenderMainCamera = false;
                return;
            }


            bool isFull = false;
            for (int i = 0; i < allPanel.Length; i++)
            {
                UIPanel panel = allPanel[i];
                if (panel != null && !panel.IsClose && panel.isShow && panel.GObjectPoolInterface.activeSelf && panel.isFullUI)
                {
                    isFull = true;
                    break;
                }
            }

            // URPTool.Instance.IsNotRenderMainCamera = isFull;
        }

        /// <summary>
        /// 关闭最上层堆栈的uiPanel
        /// </summary>
        public void HideTopPanel()
        {
            if (TopUIPanels.Count > 0)
            {
                if (TopUIPanels[^1] != null)
                {
                    TopUIPanels[^1].Hide();
                }
            }
        }

        /// <summary>
        /// 加入topUI堆栈
        /// </summary>
        public void AddTopStack(UIPanel uiPanel)
        {
            if (!TopUIPanels.Contains(uiPanel))
            {
                TopUIPanels.Add(uiPanel);
                uiPanel.IsBreadcrumbBarPanel = true;
            }
        }

        /// <summary>
        /// 弹出堆栈
        /// </summary>
        public void RemoveTopStack(UIPanel uiPanel)
        {
            if (TopUIPanels.Contains(uiPanel))
            {
                TopUIPanels.Remove(uiPanel);
            }
        }


        /// <summary>
        /// 关闭最顶部的ui
        /// </summary>
        public UIPanel CloseTopUI()
        {
            if (TopUIPanels.Count > 0)
            {
                UIPanel uiPanel = TopUIPanels[^1];
                uiPanel.IsBreadcrumbBarPanel = false; //返回关闭的时候将它设置为false 表示可以被删除

                HideUIUIPanel(uiPanel);

                return uiPanel;
            }


            return null;
        }

        /// <summary>
        /// 隐藏所有堆栈的ui
        /// </summary>
        public void HideAllStackUI()
        {
            for (var i = 0; i < TopUIPanels.Count; i++)
            {
                HideUIUIPanel(TopUIPanels[i]);
            }
        }

    

     
        /// <summary>
        /// 打开堆栈最上方
        /// </summary>
        public async void OpenTopUI()
        {
            if (TopUIPanels.Count > 0)
            {
                UIPanel uiPanel = TopUIPanels[^1];

                await uiPanel.Show();
            }
        }

        public Material UISpineMaterial;

       

        

        /// <summary>
        /// 创建组件 可重复使用的(这个方法,只是提供gameObject和脚本的绑定，没有经过池子，因此gameObject依然还挂在原来的预设上)
        /// </summary>
        /// <param name="root">父节点</param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public async CTask<T> CreateGComponentForObject<T>(GameObject gameObject, Action<T> callback,
            RectTransform root = null,
            object[] uiData = null, bool isInstance = false, string poolName = null, bool isActiveAnima = true)
            where T : UIComponent, new()
        {
            try
            {
                Type type = typeof(T);
                // // 获取UI绑定属性
                UIBindingAttribute uiBindingAttribute =
                    type.GetCustomAttribute(typeof(UIBindingAttribute)) as UIBindingAttribute;
                if (uiBindingAttribute == null)
                {
                    LogTool.Error($"类型{type.Name}没有添加UIBindingAttribute!");
                    return null;
                }

                GameObject newObject = gameObject;

                T gameObjectPool = null;
                if (isInstance)
                {
                    string newPoolName = string.IsNullOrEmpty(poolName) ? gameObject.name + ".prefab" : poolName;
                    gameObjectPool = GObjectPool.Instance.FetchAsyncForGameObject<T>(gameObject, newPoolName);
                    newObject = gameObjectPool.own;
                    // gameObjectPool.own.transform.SetParent(root);
                    // newObject = GameObject.Instantiate(gameObject);
                }
                else
                {
                    gameObjectPool = Activator.CreateInstance<T>();
                    // UIEventMono uiEventMono = newObject.GetComponent<UIEventMono>();
                    // if (uiEventMono != null)
                    // {
                    //     uiEventMono.Destory();
                    // }
                }

                if (gameObjectPool == null)
                {
                    return null;
                }

                gameObjectPool.SetGameObject(newObject);
                return await SetGComponentInfo(gameObjectPool, callback, root, uiData, isActiveAnima);
            }
            catch (Exception e)
            {
                LogTool.Exception(e);
                return null;
            }
        }

        /// <summary>
        /// 创建组件 可重复使用的
        /// </summary>
        /// <param name="root">父节点</param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public async CTask<T> CreateGComponent<T>(Action<T> callback, RectTransform root = null, object[] uiData = null,
            string poolName = null, Clock clock = null, bool isActive = true, bool isActiveAnima = true)
            where T : UIComponent, new()
        {
            try
            {
                Type type = typeof(T);
                // 获取UI绑定属性
                UIBindingAttribute uiBindingAttribute =
                    type.GetCustomAttribute(typeof(UIBindingAttribute)) as UIBindingAttribute;
                if (uiBindingAttribute == null)
                {
                    LogTool.Error($"类型{type.Name}没有添加UIBindingAttribute!");
                    return null;
                }

                T gameObjectPool = await GObjectPool.Instance.FetchAsync<T>(uiBindingAttribute.prefab + ".prefab",
                    poolName: poolName, clock: clock);
                if (gameObjectPool == null)
                {
                    return default;
                }


                T cTask = await SetGComponentInfo(gameObjectPool, callback, root, uiData, isActiveAnima);
                gameObjectPool.own.SetActive(isActive);
                return cTask;
            }
            catch (Exception e)
            {
                LogTool.Exception(e);
                return null;
            }
        }

        public void DormancyAllGComponent<T>(string poolName)
        {
            GObjectPool.Instance.DormancyPool<T>(poolName);
        }

        public void DormancyAllGComponent<T>()
        {
            Type type = typeof(T);
            // 获取UI绑定属性
            UIBindingAttribute uiBindingAttribute =
                type.GetCustomAttribute(typeof(UIBindingAttribute)) as UIBindingAttribute;
            if (uiBindingAttribute == null)
            {
                LogTool.Error($"类型{type.Name}没有添加UIBindingAttribute!");
                return;
            }

            string poolName = uiBindingAttribute.prefab + ".prefab";
            GObjectPool.Instance.DormancyPool<T>(poolName);
        }

        public void DormancyGComponent(IGObjectPoolInterface poolInterface)
        {
            GObjectPool.Instance.Recycle(poolInterface);
        }

        private async CTask<T> SetGComponentInfo<T>(T gameObjectPool, Action<T> callback, RectTransform root = null,
            object[] uiData = null, bool isActiveAnima = true) where T : UIComponent, new()
        {
            try
            {
                if (gameObjectPool == null)
                    return null;

                RectTransform rectTransform = gameObjectPool.own.GetComponent<RectTransform>();
                rectTransform.SetParent(root);
                rectTransform.SetAsLastSibling();
                rectTransform.anchoredPosition = Vector3.zero;
                rectTransform.localScale = Vector3.one;
                rectTransform.localEulerAngles = Vector3.zero;
                gameObjectPool.isActiveAnima = isActiveAnima;
                await gameObjectPool.SetUIGameObject(gameObjectPool.own);
                if (await gameObjectPool.AsyncInit(uiData))
                {
                    gameObjectPool.DelEvent(); //为了以防万一，先移除内部事件
                    gameObjectPool.AddEvent();
                    gameObjectPool.Show();
                    // await TimerComponent.Instance.WaitAsync(1);
                    callback?.Invoke(gameObjectPool);
                    return gameObjectPool;
                }
                else
                {
                    LogTool.Log($"数据准备失败，请检查{gameObjectPool.own.name}的Init方法中的逻辑");
                    gameObjectPool.Close();
                    return null;
                }
            }
            catch (Exception e)
            {
                LogTool.Exception(e);
                return null;
            }
        }

        public void HideUIUIPanel<T>(UIDestroyType uiDestroyType = UIDestroyType.DelayDestroy,
            bool isBreadcrumbBarPanel = false) where T : UIPanel
        {
            UIPanel uiPanel = GetComponent<T>();
            if (uiPanel != null)
            {
                HideUIUIPanel(uiPanel, uiDestroyType, isBreadcrumbBarPanel);
            }
        }

        /// <summary>
        /// 关闭UI
        /// </summary>
        /// <param name="uiPanel"></param>
        public void HideUIUIPanel(UIPanel uiPanel, UIDestroyType uiDestroyType = UIDestroyType.DelayDestroy,
            bool isBreadcrumbBarPanel = false)
        {
            if (uiPanel == null)
                return;


            if (uiPanel.IsClose)
            {
                return;
            }


            if (uiPanel.IsShowCustomBGPanel) //如果是开了背景的界面关闭的时候将背景一起关闭
            {
                // HideUIUIPanel(GetComponent<BackgroundPanel>(), UIDestroyType.NotDestroy);
            }

          
            if (!NoFocusTopUIPanels.Contains(uiPanel)) NoFocusTopUIPanels.Remove(uiPanel);
            uiPanel.Close();
            RemoveTopStack(uiPanel); //如果要删除界面判断是否在跳转堆栈 如果是则移除堆栈
            switch (uiDestroyType)
            {
                case UIDestroyType.DelayDestroy:

                    if (!destroyUI.ContainsKey(uiPanel.uiName))
                    {
                        uiPanel.AddDelayDestroy();
                        destroyUI.Add(uiPanel.uiName, uiPanel);
                    }

                    break;
                case UIDestroyType.ImmediatelyDestroy:
                    DestroyUIPanel(uiPanel);
                    break;
                case UIDestroyType.NotDestroy:
                    break;
            }

            RefreshFull();
        }

        public void DestroyUIPanel(UIPanel uiPanel)
        {
            if (uiPanel.Parent == null)
            {
                return;
            }

            destroyUI.Remove(uiPanel.uiName);
            uiPanel.Parent.RemoveComponent(uiPanel);
        }

      
       

        private async CTask<GameObject> FetchUI(UIBindingAttribute uiBindingAttribute, Transform tf)
        {
            GameObjectPool assetBundle =
                await GObjectPool.Instance.FetchAsync<GameObjectPool>(uiBindingAttribute.prefab + ".prefab");
            GameObject gameObject = assetBundle.own;
            if (gameObject == null)
                return null;

            gameObject.transform.SetParent(tf);
            gameObject.transform.SetAsLastSibling();
            gameObject.transform.localScale = Vector3.one;
            return gameObject;
        }


        /// <summary>
    
        /// <summary>
        /// 屏幕转ui坐标
        /// </summary>
        /// <param name="rPosition"></param>
        /// <returns></returns>
        public Vector3 ScreenPointToLocalPointInRectangle(Vector2 rPosition)
        {
            RectTransform rRect = Instance.Canvas.GetComponent<RectTransform>();
            Vector3 lPosition = Instance.UICamera.ScreenToWorldPoint(rPosition);
            Vector4 l4Position =
                new Vector4(lPosition.x, lPosition.y, lPosition.z, 1); // unity默认转化v4，w是0，不会计算x和y的rect的偏移，所以这里要自己搞一下。
            lPosition = rRect.worldToLocalMatrix * l4Position;
            lPosition.z = 0;
            return lPosition;
        }

        /// <summary>
        /// ui组件添加自定义事件
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="eventTriggerType"></param>
        /// <param name="callback"></param>
        public void AddCustomEventListener(UIBehaviour control, EventTriggerType type,
            UnityAction<BaseEventData> callback)
        {
            EventTrigger trigger = control.GetComponent<EventTrigger>();
            if (trigger == null)
            {
                trigger = control.gameObject.AddComponent<EventTrigger>();
            }

            EventTrigger.Entry entry = new EventTrigger.Entry();
            entry.eventID = type;
            entry.callback.AddListener(callback);
            trigger.triggers.Add(entry);
        }

       
        public override void Dispose()
        {
            base.Dispose();
            UGUIIamgeTool.renderOrder = 0;
        }

        /// <summary>
        /// 移除自定义事件
        /// </summary>
        /// <param name="control"></param>
        /// <param name="type"></param>
        /// <param name="callback"></param>
        public void RemoveCustomEventListener(UIBehaviour control, EventTriggerType type,
            UnityAction<BaseEventData> callback)
        {
            EventTrigger trigger = control.GetComponent<EventTrigger>();
            if (trigger == null)
            {
                trigger = control.gameObject.AddComponent<EventTrigger>();
            }

            for (int i = 0; i < trigger.triggers.Count; i++)
            {
                if (trigger.triggers[i].eventID == type)
                {
                    trigger.triggers[i].callback.RemoveListener(callback);
                    // Debug.Log("移除事件");
                }
            }
        }

        public GameObject GetOverUI(GameObject canvas)
        {
            PointerEventData pointerEventData = new PointerEventData(UnityEngine.EventSystems.EventSystem.current);
            pointerEventData.position = Input.mousePosition;
            GraphicRaycaster gr = canvas.GetComponent<GraphicRaycaster>();
            List<RaycastResult> results = new List<RaycastResult>();
            gr.Raycast(pointerEventData, results);
            if (results.Count != 0)
            {
                return results[0].gameObject;
            }

            return null;
        }

        public Vector2 SetPopTipPosition(Vector3 pos, Vector2 sizeDelta)
        {
            Vector2 xy = sizeDelta / 2;

            Vector2 vector2 = Canvas.GetComponent<RectTransform>().sizeDelta;


            float x = vector2.x / 2;
            float y = vector2.y / 2;
            if (pos.x + xy.x >= x)
            {
                pos.x = x - xy.x;
            }
            else if (pos.x - xy.x <= -x)
            {
                pos.x = -x + xy.x;
            }

            if (pos.y + xy.y >= y)
            {
                pos.y = y - xy.y;
            }
            else if (pos.y - xy.y <= -y)
            {
                pos.y = -y + xy.y;
            }

            return pos;
        }

        /// <summary>
        /// 设置数值文本的显示
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        public string SetNumberTextShow(long number)
        {
            if (number > 1000000000000)
            {
                float n = number / 1000000000000f;
                string str = "";
                if (n > 100)
                {
                    int n1 = (int)(n * 10);
                    n = n1 / 10f;
                    str = n.ToString(CultureInfo.InvariantCulture);
                }
                else
                {
                    int n1 = (int)(n * 100);
                    n = n1 / 100f;
                    str = n.ToString(CultureInfo.InvariantCulture);
                }

                return str + "t";
            }

            if (number > 1000000000)
            {
                float n = number / 1000000000f;
                string str = "";
                if (n > 100)
                {
                    int n1 = (int)(n * 10);
                    n = n1 / 10f;
                    str = n.ToString(CultureInfo.InvariantCulture);
                }
                else
                {
                    int n1 = (int)(n * 100);
                    n = n1 / 100f;
                    str = n.ToString(CultureInfo.InvariantCulture);
                }

                return str + "b";
            }

            if (number > 1000000)
            {
                float n = number / 1000000f;
                string str = "";
                if (n > 100)
                {
                    int n1 = (int)(n * 10);
                    n = n1 / 10f;
                    str = n.ToString(CultureInfo.InvariantCulture);
                }
                else
                {
                    int n1 = (int)(n * 100);
                    n = n1 / 100f;
                    str = n.ToString(CultureInfo.InvariantCulture);
                }

                return str + "m";
            }

            if (number > 10000)
            {
                float n = number / 1000f;
                string str = "";
                if (n > 100)
                {
                    int n1 = (int)(n * 10);
                    n = n1 / 10f;
                    str = n.ToString(CultureInfo.InvariantCulture);
                }
                else
                {
                    int n1 = (int)(n * 100);
                    n = n1 / 100f;
                    str = n.ToString(CultureInfo.InvariantCulture);
                }

                return str + "k";
            }

            return number.ToString();
        }

        /// <summary>
        /// 每日是否提醒标记
        /// </summary>
        public enum ToDayDontShowTag
        {
            MjToDiamond = 0,
            DiamondUsed, //钻石使用判断
            RelicIntensify,

            /// <summary>
            /// 经验转换
            /// </summary>
            EXConvert
        }

    


        //判断鼠标是否点在ui上
        public bool IsPointerOverGameObject(Vector2 mousePosition)
        {
            PointerEventData eventData = new PointerEventData(EventSystem.current);
            eventData.position = mousePosition;
            List<RaycastResult> raycastResults = new List<RaycastResult>();
            //发射射线判断是否点到ui
            EventSystem.current.RaycastAll(eventData, raycastResults);
            if (raycastResults.Count > 0)
            {
                return true;
            }
            else
            {
                return false;
            }
        }


        
    }
}