using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

public class PoolManager : MonoBehaviour
{
    //obj pool
    private Dictionary<string, Pool> m_poolDict = new Dictionary<string, Pool>();

    private static PoolManager m_instance = null;

    public static PoolManager Instance
    {
        get
        {
            if (m_instance == null)
            {
                GameObject GO = new GameObject("ResourceManager", typeof(PoolManager));
                // Kanglai: if we have `GO.hideFlags |= HideFlags.DontSave;`, we will encounter Destroy problem when exit playing
                // However we should keep using this in Play mode only!
                m_instance = GO.GetComponent<PoolManager>();
                if (Application.isPlaying)
                {
                    //DontDestroyOnLoad(mInstance.gameObject);
                }
                else
                {
                    Debug.LogWarning("[ResourceManager] You'd better ignore ResourceManager in Editor mode");
                }
            }

            return m_instance;
        }
    }

    private Pool GetPool(GameObject go)
    {
        if (!m_poolDict.ContainsKey(go.name))
        {
            m_poolDict[go.name] = new Pool(go);
        }
        return m_poolDict[go.name];
    }

    /// <summary>
    /// Returns an available object from the pool 
    /// OR null in case the pool does not have any object available & can grow size is false.
    /// </summary>
    /// <param name="poolName"></param>
    /// <returns></returns>
    public GameObject GetObjectFromPool(GameObject go)
    {
        GameObject varGo = null;

        Pool pool = GetPool(go);
        if (pool != null)
        {
            varGo = pool.GetPoolObject();
        }
        return varGo;
    }

    /// <summary>
    /// Return obj to the pool
    /// </summary>
    /// <param name="go"></param>
    public void ReturnObjectToPool(GameObject go)
    {
        //PoolObject po = go.GetComponent<PoolObject>();
        if (go != null)
        {
            Pool pool = null;
            if (m_poolDict.TryGetValue(go.name, out pool))
            {
                pool.ReturnObjectToPool(go);
            }
        }
    }

    void OnDestroy()
    {
        for (int i = 0; i < m_poolDict.Count; i++)
        {
            var item = m_poolDict.ElementAt(i);
            if(item.Value != null)
            {
                item.Value.DestroyObj();
            }
        }
        m_poolDict.Clear();
        m_poolDict = null;
    }
}