using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;

using System;
using System.Collections;
using System.Linq.Expressions;
using System.Collections.Generic;

using Object = UnityEngine.Object;

public enum Folder
{
    UI,
    Sprite,
    Object,
}

public enum ObjectPoolType
{
    Null,
    HUD,
}

public class ManagerResource : MonoBehaviour
{
    #region 变量

    #region 引用变量

    #region UI

    [NonSerialized] public Transform CanvasTra;

    //Log
    [NonSerialized] public Text LogLabel;
    [NonSerialized] public Image LogBk;
    [NonSerialized] public Image LogHandleBk;
    [NonSerialized] public ScrollRect LogScrollRect;

    //MainPanel
    [NonSerialized] public Text GoldTitle1;
    [NonSerialized] public Text GoldLabel1;
    [NonSerialized] public Text SettingLabel;
    [NonSerialized] public Text DiamondTitle1;
    [NonSerialized] public Text DiamondLabel1;
    [NonSerialized] public Text AchievementLabel;
    [NonSerialized] public Text OpenManageLabel;
    [NonSerialized] public Button SettingBtn;
    [NonSerialized] public Button AchievementBtn;
    [NonSerialized] public Button OpenManageBtn;
    [NonSerialized] public GameObject MainPanel;

    //GamePanel
    [NonSerialized] public Text ScoreTitle;
    [NonSerialized] public Text ScoreLabel;
    [NonSerialized] public Text RippingLabel;
    [NonSerialized] public Text WateringLabel;
    [NonSerialized] public Text FertilizingLabel;
    [NonSerialized] public Text GameBeginLabel;
    [NonSerialized] public Text GameStatusLabel;
    [NonSerialized] public Text RemainTimeLabel;
    [NonSerialized] public Image GamePanelBk;
    [NonSerialized] public Button RippingBtn;
    [NonSerialized] public Button WateringBtn;
    [NonSerialized] public Button FertilizingBtn;
    [NonSerialized] public Button GameBeginBtn;
    [NonSerialized] public GameObject OperatePanel;

    //ManagePanel
    [NonSerialized] public Text ElfTitle1;
    [NonSerialized] public Text ElfLabel1;
    [NonSerialized] public Text VisitTitle;
    [NonSerialized] public Text VisitLabel;
    [NonSerialized] public Text GoldTitle2;
    [NonSerialized] public Text GoldLabel2;
    [NonSerialized] public Text FlowerTitle1;
    [NonSerialized] public Text FlowerLabel1;
    [NonSerialized] public Text DiamondTitle2;
    [NonSerialized] public Text DiamondLabel2;
    [NonSerialized] public Image BarBk1;
    [NonSerialized] public Image BarBk2;
    [NonSerialized] public Image BarBk3;
    [NonSerialized] public Image ManagePanelBk;
    [NonSerialized] public GameObject ManagePanel;

    //ManagePanel
    [NonSerialized] public Text ElfLabel2;
    [NonSerialized] public Text ShopLabel;
    [NonSerialized] public Text InputLabel;
    [NonSerialized] public Text MagicLabel;
    [NonSerialized] public Text GardenLabel;
    [NonSerialized] public Text FlowerLabel2;
    [NonSerialized] public Text PlaceHolderLabel;
    [NonSerialized] public Text CloseManageLabel;
    [NonSerialized] public Image CommandBk;
    [NonSerialized] public Button ElfBtn2;
    [NonSerialized] public Button ShopBtn;
    [NonSerialized] public Button MagicBtn;
    [NonSerialized] public Button GardenBtn;
    [NonSerialized] public Button FlowerBtn2;
    [NonSerialized] public Button CloseManageBtn;

    [NonSerialized] public Text HintLabel;
    [NonSerialized] public Transform HudTra;

    #endregion

    [NonSerialized] public List<Flower> FlowerList;

    #endregion

    private Dictionary<ObjectPoolType, GameObject> PrefabDictionary;
    private Dictionary<ObjectPoolType, List<GameObject>> ObjectPool;

    public static ManagerResource Ins;

    #endregion

    private void Awake()
    {
        Ins = this;
        FlowerList = new List<Flower>();

        ObjectPool = new Dictionary<ObjectPoolType, List<GameObject>>();
        PrefabDictionary = new Dictionary<ObjectPoolType, GameObject>();

        #region 构造场景

        Get("MainCamera", Folder.Object);
        CreateUGUI();

        Get("GardenBk", Folder.Object, transform);

        GameObject player = Get("Player", Folder.Object, transform);
        player.AddComponent<Player>();

        Transform flowerTra1 = Get("FlowerTra1", Folder.Object, transform).transform;
        flowerTra1.gameObject.AddComponent<FlowerSlot>();

        Transform flowerTra2 = Get("FlowerTra2", Folder.Object, transform).transform;
        flowerTra2.gameObject.AddComponent<FlowerSlot>();

        Transform flowerTra3 = Get("FlowerTra3", Folder.Object, transform).transform;
        flowerTra3.gameObject.AddComponent<FlowerSlot>();

        #endregion
    }


    public void Save(GameObject go)
    {
        ObjectPoolRoot objectPoolRoot = go.GetComponent<ObjectPoolRoot>();
        if (objectPoolRoot == null)
        {
            throw new Exception();
        }

        List<GameObject> tempGoList;
        if (ObjectPool.TryGetValue(objectPoolRoot.ObjectPoolType, out tempGoList))
        {
            go.SetActive(false);

            tempGoList.Add(go);
        }
        else
        {
            throw new Exception();
        }
    }

    public GameObject Get(string name, Folder folder,  ObjectPoolType objectPoolType = ObjectPoolType.Null)
    {
        GameObject tempGo = Load<GameObject>(name, folder, objectPoolType);

        return Instantiate(tempGo, tempGo.transform.position, tempGo.transform.rotation);
    }

    public GameObject Get(string name, Folder folder, Vector3 position, Quaternion rotation, Transform parent = null, ObjectPoolType objectPoolType = ObjectPoolType.Null)
    {
        GameObject tempGo = Load<GameObject>(name, folder, objectPoolType);

        return Instantiate(tempGo, position, rotation, parent);
    }

    public GameObject Get(string name, Folder folder, Transform parent, bool worldSpace = false, ObjectPoolType objectPoolType = ObjectPoolType.Null)
    {
        GameObject tempGo = Load<GameObject>(name, folder, objectPoolType);
        
        return Instantiate(tempGo, parent, worldSpace);
    }


    public T Load<T>(string name, Folder folder, ObjectPoolType objectPoolType = ObjectPoolType.Null) where T : Object
    {
        GameObject tempGo;
        if (PrefabDictionary.TryGetValue(objectPoolType, out tempGo))
        {
            return (T) Convert.ChangeType(tempGo, typeof(T));
        }
        else
        {
            #region 加载Prefab

            T t;

            if (folder == Folder.UI)
            {
                t = Resources.Load<T>(@"Prefab\UI\" + name);
            }
            else if (folder == Folder.Sprite)
            {
                t = Resources.Load<T>(@"Sprite\" + name);
            }
            else if (folder == Folder.Object)
            {
                t = Resources.Load<T>(@"Prefab\Object\" + name);
            }
            else
            {
                throw new Exception();
            }

            if (objectPoolType != ObjectPoolType.Null)
            {
                ObjectPool.Add(objectPoolType, new List<GameObject>());
                PrefabDictionary.Add(objectPoolType, (GameObject) Convert.ChangeType(t, typeof(GameObject)));
            }

            return t;

            #endregion
        }
    }

    public  Text GetHUD(Color color, Vector3 position, bool permanent = false, string message = "", float speed = 0.5f, float stayTime = 0f)
    {
        HUD hud;
        GameObject tempGo;
        List<GameObject> tempGoList;
        if (ObjectPool.TryGetValue(ObjectPoolType.HUD, out tempGoList)) //从对象池中获得
        {
            if (tempGoList.Count > 0)
            {
                tempGo = tempGoList[0];
                tempGoList.RemoveAt(0);

                tempGo.SetActive(true);
                tempGo.transform.position = position;
                tempGo.transform.rotation = Quaternion.identity;

                hud = tempGo.GetComponent<HUD>();
                hud.Set(color, permanent, message, speed, stayTime);

                return tempGo.GetComponent<Text>();
            }
        }

        #region Instantiate

        tempGo = Get("HUD", Folder.UI, position, Quaternion.identity, HudTra, ObjectPoolType.HUD);

        hud = tempGo.AddComponent<HUD>();
        hud.Set(color, permanent, message, speed, stayTime);

        return tempGo.GetComponent<Text>();

        #endregion
    }

    private void CreateUGUI()
    {
        Language.Init(SystemLanguage.Chinese);

        CanvasTra = Get("Canvas", Folder.UI).transform; //实例化Canvas

        Get("EventSystem", Folder.UI); //实例化EventSystem

        #region 引用变量赋值

        Hashtable hashtable = new Hashtable();
        Transform[] transforms = CanvasTra.GetComponentsInChildren<Transform>(true);

        for (int i = 0; i < transforms.Length; i++)
        {
            hashtable.Add(transforms[i].name, transforms[i]);
        }

        //Log
        LogLabel = ((Transform) hashtable["LogLabel"]).GetComponent<Text>();
        LogBk = ((Transform) hashtable["LogScrollRectBk"]).GetComponent<Image>();
        LogHandleBk = ((Transform) hashtable["LogHandleBk"]).GetComponent<Image>();
        LogScrollRect = ((Transform) hashtable["LogScrollRectBk"]).GetComponent<ScrollRect>();

        //MainPanel
        GoldTitle1 = ((Transform) hashtable["GoldTitle1"]).GetComponent<Text>();
        GoldLabel1 = ((Transform) hashtable["GoldLabel1"]).GetComponent<Text>();
        SettingLabel = ((Transform) hashtable["SettingLabel"]).GetComponent<Text>();
        DiamondTitle1 = ((Transform) hashtable["DiamondTitle1"]).GetComponent<Text>();
        DiamondLabel1 = ((Transform) hashtable["DiamondLabel1"]).GetComponent<Text>();
        AchievementLabel = ((Transform) hashtable["AchievementLabel"]).GetComponent<Text>();
        OpenManageLabel = ((Transform) hashtable["OpenManageLabel"]).GetComponent<Text>();
        SettingBtn = ((Transform) hashtable["SettingBtn"]).GetComponent<Button>();
        AchievementBtn = ((Transform) hashtable["AchievementBtn"]).GetComponent<Button>();
        OpenManageBtn = ((Transform) hashtable["OpenManageBtn"]).GetComponent<Button>();
        MainPanel = ((Transform) hashtable["MainPanel"]).gameObject;

        //GamePanel
        ScoreTitle = ((Transform) hashtable["ScoreTitle"]).GetComponent<Text>();
        ScoreLabel = ((Transform)hashtable["ScoreLabel"]).GetComponent<Text>();
        RippingLabel = ((Transform) hashtable["RippingLabel"]).GetComponent<Text>();
        WateringLabel = ((Transform) hashtable["WateringLabel"]).GetComponent<Text>();
        FertilizingLabel = ((Transform) hashtable["FertilizingLabel"]).GetComponent<Text>();
        GameBeginLabel = ((Transform) hashtable["GameBeginLabel"]).GetComponent<Text>();
        GameStatusLabel = ((Transform) hashtable["GameStatusLabel"]).GetComponent<Text>();
        RemainTimeLabel = ((Transform) hashtable["RemainTimeLabel"]).GetComponent<Text>();
        GamePanelBk = ((Transform) hashtable["GamePanelBk"]).GetComponent<Image>();
        RippingBtn = ((Transform) hashtable["RippingBtn"]).GetComponent<Button>();
        WateringBtn = ((Transform) hashtable["WateringBtn"]).GetComponent<Button>();
        FertilizingBtn = ((Transform) hashtable["FertilizingBtn"]).GetComponent<Button>();
        GameBeginBtn = ((Transform) hashtable["GameBeginBtn"]).GetComponent<Button>();
        OperatePanel = ((Transform) hashtable["OperatePanel"]).gameObject;

        //ManagePanel
        ElfTitle1 = ((Transform) hashtable["ElfTitle1"]).GetComponent<Text>();
        ElfLabel1 = ((Transform) hashtable["ElfLabel1"]).GetComponent<Text>();
        VisitTitle = ((Transform) hashtable["VisitTitle"]).GetComponent<Text>();
        VisitLabel = ((Transform) hashtable["VisitLabel"]).GetComponent<Text>();
        GoldTitle2 = ((Transform) hashtable["GoldTitle2"]).GetComponent<Text>();
        GoldLabel2 = ((Transform) hashtable["GoldLabel2"]).GetComponent<Text>();
        FlowerTitle1 = ((Transform) hashtable["FlowerTitle1"]).GetComponent<Text>();
        FlowerLabel1 = ((Transform) hashtable["FlowerLabel1"]).GetComponent<Text>();
        DiamondTitle2 = ((Transform) hashtable["DiamondTitle2"]).GetComponent<Text>();
        DiamondLabel2 = ((Transform) hashtable["DiamondLabel2"]).GetComponent<Text>();
        BarBk1 = ((Transform) hashtable["BarBk1"]).GetComponent<Image>();
        BarBk2 = ((Transform) hashtable["BarBk2"]).GetComponent<Image>();
        BarBk3 = ((Transform) hashtable["BarBk3"]).GetComponent<Image>();
        ManagePanelBk = ((Transform) hashtable["ManagePanelBk"]).GetComponent<Image>();

        //ManagePanel
        ElfLabel2 = ((Transform) hashtable["ElfLabel2"]).GetComponent<Text>();
        ShopLabel = ((Transform) hashtable["ShopLabel"]).GetComponent<Text>();
        InputLabel = ((Transform) hashtable["InputLabel"]).GetComponent<Text>();
        MagicLabel = ((Transform) hashtable["MagicLabel"]).GetComponent<Text>();
        GardenLabel = ((Transform) hashtable["GardenLabel"]).GetComponent<Text>();
        FlowerLabel2 = ((Transform) hashtable["FlowerLabel2"]).GetComponent<Text>();
        PlaceHolderLabel = ((Transform) hashtable["PlaceHolderLabel"]).GetComponent<Text>();
        CloseManageLabel = ((Transform) hashtable["CloseManageLabel"]).GetComponent<Text>();
        CommandBk = ((Transform) hashtable["CommandBk"]).GetComponent<Image>();
        ElfBtn2 = ((Transform) hashtable["ElfBtn2"]).GetComponent<Button>();
        ShopBtn = ((Transform) hashtable["ShopBtn"]).GetComponent<Button>();
        MagicBtn = ((Transform) hashtable["MagicBtn"]).GetComponent<Button>();
        GardenBtn = ((Transform) hashtable["GardenBtn"]).GetComponent<Button>();
        FlowerBtn2 = ((Transform) hashtable["FlowerBtn2"]).GetComponent<Button>();
        CloseManageBtn = ((Transform) hashtable["CloseManageBtn"]).GetComponent<Button>();

        HintLabel = ((Transform) hashtable["HintLabel"]).GetComponent<Text>();
        HudTra = ((Transform) hashtable["HudTra"]);

        #endregion

        #region Image赋值

        

        #endregion

        #region Text赋值

        

        #endregion

        CloseManageBtn.onClick.AddListener(OnCloseManagePanel);
        OpenManageBtn.onClick.AddListener(OnOpenManagePanel);
    }


    private void OnCloseManagePanel()
    {
        MainPanel.SetActive(true);

        GamePanelBk.gameObject.SetActive(true);
        ManagePanelBk.gameObject.SetActive(false);
    }

    private void OnOpenManagePanel()
    {
        MainPanel.SetActive(false);

        GamePanelBk.gameObject.SetActive(false);
        ManagePanelBk.gameObject.SetActive(true);
    }
}