using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using Object = UnityEngine.Object;

/// <summary>
///  UI管理
///  作者:徐振升
///  最后更新:2018-07-17 15:30
///  联系方式:QQ:359059686
///  项目没有UI管理,此脚本目的为了方便UI管理,目前管理注册中的页面,请勿随意修改。
/// </summary>
public static class UIManager
{
    private static Dictionary<string, WeakReference> templates = new Dictionary<string, WeakReference>();
    private static Dictionary<string, UIView> Views = new Dictionary<string, UIView>();
    private static Dictionary<string, string> UIPath = new Dictionary<string, string>();

    static UIManager()
    {
        //①手动注册UI        //RegisterUI<XLogUIView>("UI/XLogUIView");

        //②自动注册UI        //请把UIView名称与预设名称相同,放在Resource文件根目录下。如自动注册XLogUIView=Resource/XLogUIView

        //私聊界面
        RegisterUI<PrivateChatPanel>("UI/UIViewPrivateChat");
        //公聊界面
        RegisterUI<ChatPanel>("UI/UIViewPublicChat");
        //器材库界面
        RegisterUI<UIViewEquipLib>("UI/UIViewEquipLib");
        //数量选择界面
        RegisterUI<UIViewNumberSelect>("UI/UIViewNumberSelect");
        //背包界面
        RegisterUI<UIViewBag>("UI/UIViewBag");
        //建议界面
        RegisterUI<SuggestPanel>("UI/UIViewSuggest");
        //角色报告
        RegisterUI<UIViewReport>("UI/UIViewReport");
        //问卷调查
        RegisterUI<UIViewQuestionnaire>("UI/UIViewQuestionnaire");
        //评分记录
        RegisterUI<UIViewScore>("UI/UIViewScore");
        //队伍分析
        RegisterUI<UIViewAnalyze>("UI/UIViewAnalyze");
    }
    // 注册UI
    public static void RegisterUI<T>(string prefabPath)
        where T : UIView
    {
        if (!UIPath.ContainsKey(typeof(T).ToString()))
        {
            UIPath.Add(typeof(T).ToString(), prefabPath);
        }
    }
    public static string Normalize(string name)
    {
        int num = name.IndexOf('.');
        if (num < 0)
        {
            return name;
        }
        return name.Substring(0, num);
    }
    // 加载UI
    private static void LoadView<T>(string viewName)
        where T : UIView
    {
        string tempKey = typeof(T).ToString();
        if (!UIPath.ContainsKey(tempKey))
        {
            // 没有注册先注册
            RegisterUI<T>(typeof(T).ToString());
        }
        string tempPath = Normalize(UIPath[tempKey]);
        WeakReference value;
        GameObject gameObject;
        if (templates.TryGetValue(tempPath, out value) && value.IsAlive)
        {
            gameObject = (GameObject)value.Target;
        }
        else
        {
            gameObject = Resources.Load<GameObject>(tempPath);
            if (gameObject != null)
            {
                gameObject.SetActive(false);
                templates[tempPath] = new WeakReference(gameObject);
            }
            else
            {
                // Resource根目录没有发现UIView的Prefab,请添加。
                throw new Exception(string.Format("<<{0}>> prefab not found in Resource folder.", tempPath));
            }
        }
        if (gameObject != null && gameObject.GetComponent<T>() != null)
        {
            //实例化
            GameObject ui = GameObject.Instantiate(gameObject);
            ui.name = gameObject.name;
            //记录初始大小
            Vector3 anchorPos3D = ui.GetComponent<RectTransform>().anchoredPosition3D;
            Vector3 anchorPos = ui.GetComponent<RectTransform>().anchoredPosition;
            Vector3 sizeDel = ui.GetComponent<RectTransform>().sizeDelta;
            Vector3 scale = ui.GetComponent<RectTransform>().localScale;
            //设置父对象
            T view = ui.GetComponent<T>();
            Transform parent = GetUICanvas().transform;
            ui.transform.SetParent(parent);
            //还原初始大小
            ui.GetComponent<RectTransform>().anchoredPosition3D = anchorPos3D;
            ui.GetComponent<RectTransform>().anchoredPosition = anchorPos;
            ui.GetComponent<RectTransform>().sizeDelta = sizeDel;
            ui.GetComponent<RectTransform>().localScale = scale;

            view.ViewName = viewName;
            Views.Add(viewName, view);
        }
    }
    private static GameObject GetUICanvas()
    {
        GameObject gameObject = GameObject.Find("Canvas");
        if (gameObject == null || gameObject.GetComponent<Canvas>() == null)
        {
            gameObject = CreateNewUI();
        }
        return gameObject;
    }

    [Obsolete("暂时弃用,使用GetUICanvas")]
    // 获取对象目录
    private static Transform GetUIElementRoot(UIViewType type)
    {
        GameObject gameObject = GameObject.Find("Canvas");
        if (gameObject == null || gameObject.GetComponent<Canvas>() == null)
        {
            gameObject = CreateNewUI();
        }
        Transform transform = gameObject.transform.Find(type.ToString());
        if (transform == null)
        {
            CreateUIElementRoot("Normal", gameObject);
            CreateUIElementRoot("Popup", gameObject);
            transform = gameObject.transform.Find(type.ToString());
        }
        return transform;
    }
    // 创建新的UI目录
    public static GameObject CreateNewUI()
    {
        GameObject gameObject = new GameObject("Canvas");
        gameObject.layer = LayerMask.NameToLayer("UI");
        Canvas canvas = gameObject.AddComponent<Canvas>();
        canvas.renderMode = RenderMode.ScreenSpaceOverlay;
        gameObject.AddComponent<CanvasScaler>();
        gameObject.AddComponent<GraphicRaycaster>();
        CreateEventSystem();
        return gameObject;
    }
    // 创建UI子目录
    private static void CreateUIElementRoot(string name, GameObject obj)
    {
        GameObject gameObject = new GameObject(name);
        gameObject.layer = LayerMask.NameToLayer("UI");
        RectTransform rect = gameObject.AddComponent<RectTransform>();
        gameObject.transform.SetParent(obj.transform);
        rect.sizeDelta = Vector2.zero;
        rect.localScale = Vector3.one;
        rect.localPosition = Vector3.zero;
        rect.SetAnchor(AnchorPresets.StretchAll);
    }
    // 创建UIEvent
    private static void CreateEventSystem()
    {
        EventSystem eventSystem = Object.FindObjectOfType<EventSystem>();
        if (eventSystem == null)
        {
            GameObject gameObject = new GameObject("EventSystem");
            eventSystem = gameObject.AddComponent<EventSystem>();
            gameObject.AddComponent<StandaloneInputModule>();
        }
    }
    // 显示页面
    public static void ShowView<T>()
        where T : UIView
    {
        string viewName = typeof(T).ToString();
        ShowView<T>(viewName);
    }
    // 显示指定名称页面
    public static void ShowView<T>(string viewName)
         where T : UIView
    {
        //没有加载页面先加载
        if (!Views.ContainsKey(viewName))
        {
            LoadView<T>(viewName);
        }
        Views[viewName].Show();
    }
    // 获取页面
    public static T GetView<T>()
        where T : UIView
    {
        string viewName = typeof(T).ToString();
        return GetView<T>(viewName);
    }
    // 获取指定名称页面
    public static T GetView<T>(string viewName)
        where T : UIView
    {
        //没有页面先加载
        if (!Views.ContainsKey(viewName))
        {
            LoadView<T>(viewName);
        }
        return Views[viewName] as T;
    }
    // 隐藏页面
    public static void HideView<T>()
        where T : UIView
    {
        string viewName = typeof(T).ToString();
        HideView<T>(viewName);
    }
    // 隐藏指定名称页面
    public static void HideView<T>(string viewName)
         where T : UIView
    {
        //没有加载页面先加载
        if (!Views.ContainsKey(viewName))
        {
            LoadView<T>(viewName);
        }
        Views[viewName].Hide();
    }
    // 隐藏页面
    public static void DestroyView<T>()
        where T : UIView
    {
        string viewName = typeof(T).ToString();
        DestroyView(viewName);
    }
    // 销毁页面
    public static void DestroyView(string viewName)
    {
        if (Views != null && Views.ContainsKey(viewName) && viewName != null)
        {
            Views.Remove(viewName);
        }
    }
    public static void ResertUIManager()
    {
        if (templates.Count > 0)
        {

            templates.Clear();
        }
        if (Views.Count > 0)
        {

            Views.Clear();
        }
        if (UIPath.Count > 0)
        {
            UIPath.Clear();
        }
    }
}