using System;
using System.Collections.Generic;

using FLogger = UnityEngine.Gonbest.MagicCube.FLogger;

namespace Thousandto.Core.Base
{
    public class SimplePool<T> where T : class
    {
        #region //静态处理
        public static MyFunc<object,T> CreateInstanceWithParam = null;
        public static MyFunc<T> CreateInstance = null;
        public static MyAction<T> CtorFunc = null;
        public static MyAction<T,int> DtorFunc = null;
        public static MyAction<T> ReleaseFunc = null;
        public static MyFunc<T, int> ElementSizeFunc = null;
        

        private static SimplePool<T> _sharedInstance = null;

        public static SimplePool<T> SharedInstance
        {
            get
            {
                return _sharedInstance;
            }
        }

        static SimplePool()
        {
            _sharedInstance = new SimplePool<T>();
            SimplePoolSweeper.Register(() => _sharedInstance.Sweep());
        }
        #endregion


        private SetStack<T> m_stack = new SetStack<T>();

        public List<T> Stack
        {
            get
            {
                return m_stack.Items;
            }
        }


        public void Sweep()
        {
            try
            {
                if (ReleaseFunc != null)
                {
                    for (int i = 0; i < m_stack.Count; ++i)
                    {
                        ReleaseFunc(m_stack[i]);
                    }
                }
            }
            finally
            {
                m_stack.Clear();
                m_stack.TrimExcess();
            }
        }

        public void TrimExcess()
        {
            m_stack.TrimExcess();
        }

        public T Allocate()
        {
            T ret = null;
            if (m_stack.Count == 0)
            {
                if (CreateInstance == null)
                {
                    ret = Activator.CreateInstance(typeof(T)) as T;
                    FLogger.DebugLogWarning("SimplePool: there is no public parameterless ctor. you should specify a ctor for this pool.");
                }
                else
                {
                    ret = CreateInstance();
                }
            }
            else
            {
                ret = m_stack.Pop();
            }
            if (CtorFunc != null)
            {
                CtorFunc(ret);
            }
            return ret;
        }
        //通过参数创建
        public T Allocate(object param)
        {
            T ret = null;
            if (m_stack.Count == 0)
            {
                if (CreateInstanceWithParam == null)
                {
                    ret = Activator.CreateInstance(typeof(T), param) as T;
                    FLogger.DebugLogWarning("SimplePool: there is no public parameterless ctor. you should specify a ctor for this pool.");
                }
                else
                {
                    ret = CreateInstanceWithParam(param);
                }
            }
            else
            {
                ret = m_stack.Pop();
            }
            if (CtorFunc != null)
            {
                CtorFunc(ret);
            }
            return ret;
        }

        public void Free(ref T o,int param)
        {
            if (o != null)
            {
                if (m_stack.Push(o))
                {
                    if (DtorFunc != null)
                    {
                        DtorFunc(o, param);
                    }
                }
                o = null;
            }
        }

        public int GetTotalSize()
        {
            int size = 0;
            if (ElementSizeFunc != null)
            {
                for (int i = 0; i < m_stack.Count; ++i)
                {
                    size += ElementSizeFunc(m_stack[i]);
                }
            }
            return size;
        }

        public void Preload(int count)
        {
            var c = m_stack.Count + count;           
            if (CreateInstance != null)
            {
                for (int i = 0; i < count; ++i)
                {
                    var ret = CreateInstance();
                    if (ret != null)
                    {
                        m_stack.PushFast(ret);
                    }
                }
            }
            else
            {
                FLogger.DebugLogWarning("SimplePool: there is no public parameterless ctor. you should specify a ctor for this pool.");
                for (int i = 0; i < count; ++i)
                {
                    var ret = Activator.CreateInstance(typeof(T)) as T;
                    if (ret != null)
                    {
                        m_stack.PushFast(ret);
                    }
                }
            }
        }

        
    }
}