const { ccclass, property } = cc._decorator;

@ccclass
export default class PoolMgr {

    //单例模式---------------------------
    private static instance: PoolMgr = null;

    public static get Inst(): PoolMgr {
        if (!PoolMgr.instance) {
            PoolMgr.instance = new PoolMgr();
        }
        return PoolMgr.instance;
    }

    /**对象池预支体目录 */
    private nodePoolDir: string = "game/prefab/nodepool/"
    private className: string = "";

    /**
     * 对象池预制体字典
     * @param key:string 预制体名字
     * @param valuee:cc.Prefab 预制体
     */
    public prefabDic: { [key: string]: cc.Prefab } = {};

    /**
     * 对象池字典
     * @param key:string 预制体名字
     * @param valuee:cc.NodePool 对应的对象池
     */
    public nodePoolDic: { [key: string]: cc.NodePool } = {};

    // LIFE-CYCLE CALLBACKS:
    onLoad() {

    }

    start() {

    }

    /**初始化对象池的预制体 */
    initPoolPrefab() {
        let self = this;

        //FC:获取当前类名
        self.className = self["__proto__"]["constructor"].name;
        
        //LogUtil.log("Object.keys(POOLPREFABTYPE)", Object.keys(NODEPOOLPREFABTYPE));
        // LogUtil.log("POOLPREFABTYPE[key]", typeof (POOLPREFABTYPE[POOLPREFABTYPE.Dart]));

        for (var i = 0; i < Object.keys(NODEPOOLPREFABTYPE).length; i++) {
            let key = Object.keys(NODEPOOLPREFABTYPE)[i];
            let value = NODEPOOLPREFABTYPE[key];
            //LogUtil.log("key", key)

            //FC:注释
            // if (Number(key) || Number(key) == 0) {
            //     //LogUtil.log("key", key);
            //     // LogUtil.log("value", value);
            //     //初始化对象池
            //     if (!self.nodePoolDic[value]) {
            //         self.nodePoolDic[value] = new cc.NodePool();
            //     }
            //     LogUtil.log("加载预制体啦啦啦啦啦啦啦啦啦啦啦啦")
            //     //加载预制体
            //     cc.loader.loadRes(`${this.nodePoolDir}${value}`, function (err, prefab: cc.Prefab) {
            //         if (err) {
            //             LogUtil.log(`[${self.className}]加载预制体失败：${value}`, err);
            //         }
            //         else {
            //             LogUtil.log(`[${self.className}]加载预制体成功：${value}`,prefab);

            //             //初始化预制体
            //             self.prefabDic[value] = prefab;
            //             //实例化预制体
            //             let nodePoolPrefab = cc.instantiate(prefab);
            //             self.nodePoolDic[value].put(nodePoolPrefab);
            //         }
            //     }.bind(this));
            // }
            // else {
            //     continue;
            // }

            //FC:应对遍历不到数字型Key值问题
            if (Number(key) || Number(key) == 0) {
                continue;
            }
            else {
                //LogUtil.log("[PoolMgr] key", key);
                // LogUtil.log("value", value);
                //初始化对象池
                if (!self.nodePoolDic[key]) {
                    self.nodePoolDic[key] = new cc.NodePool();
                }
                //LogUtil.log("加载预制体啦啦啦啦啦啦啦啦啦啦啦啦")
                //加载预制体
                cc.loader.loadRes(`${this.nodePoolDir}${key}`, function (err, prefab: cc.Prefab) {
                    if (err) {
                        mk.console.log(`[${self.className}]加载预制体失败：${key}`, err);
                    }
                    else {
                        //LogUtil.log(`[${self.className}]加载预制体成功：${key}`, prefab);

                        //初始化预制体
                        self.prefabDic[key] = prefab;
                        //实例化预制体
                        let nodePoolPrefab = cc.instantiate(prefab);
                        self.nodePoolDic[key].put(nodePoolPrefab);
                    }
                }.bind(this));
            }
        }

        //也可以遍历
        // for (var e in POOLPREFABTYPE) {
        //     LogUtil.log("e String", String(e));
        //     LogUtil.log("e Number", Number(e));
        // }
    }

    /**初始化预制体根据数目(有些可能需要初始生成大量的预制体)
     * @param poolPrefabType 对象池预制体的类型
     * @param initNum        需要的数量
     */
    initPoolPrefabByNum(poolPrefabType: NODEPOOLPREFABTYPE, initNum: number) {
        let prefabName = NODEPOOLPREFABTYPE[poolPrefabType];
        let prefab = this.prefabDic[prefabName];
        //可能有些一开始要生成大量的预制体
        for (let i = 0; i < initNum; ++i) {
            let nodePoolPrefab = cc.instantiate(prefab); // 创建节点
            this.nodePoolDic[prefabName].put(nodePoolPrefab); // 通过 put 接口放入对象池
        }
    }

    /**获取对象池的预制体
     * @param poolPrefabType 对象池预制体的类型
     */
    getPoolPrefab(poolPrefabType: NODEPOOLPREFABTYPE) {

        let prefabName = NODEPOOLPREFABTYPE[poolPrefabType];
        let nodePoolPrefab: cc.Node = null;

        let prefab: cc.Prefab = this.prefabDic[prefabName];
        //如果有加载好的预制体
        if (prefab) {
            let nodePool: cc.NodePool = this.nodePoolDic[prefabName];

            if (nodePool.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
                nodePoolPrefab = nodePool.get();
            } else { // 如果没有空闲对象，也就是对象池中备用对象不够时，我们就用 cc.instantiate 重新创建
                nodePoolPrefab = cc.instantiate(prefab);
            }
            //LogUtil.log("hairPrefab",hairPrefab);
            return nodePoolPrefab;
        }
        else {
            let value = NODEPOOLPREFABTYPE[poolPrefabType];
            mk.console.log("poolPrefabType", poolPrefabType, value);
            cc.loader.loadRes(`${this.nodePoolDir}${value}`, function (err, prefab: cc.Prefab) {
                if (err) {
                    mk.console.log("加载预制体失败level", err);
                }
                else {
                    nodePoolPrefab = cc.instantiate(prefab);
                    mk.console.log(" nodePoolPrefab ", nodePoolPrefab);
                    return nodePoolPrefab;
                }
            }.bind(this));
        }
    }

    /**回收对象池的预制体
     * @param poolPrefabType 对象池预制体的类型
     * @param nodePoolPrefab 预制体对象
     */
    recyclePoolPrefab(poolPrefabType: NODEPOOLPREFABTYPE, nodePoolPrefab: cc.Node) {
        let prefabName = NODEPOOLPREFABTYPE[poolPrefabType];
        let nodePool: cc.NodePool = this.nodePoolDic[prefabName];
        nodePool.put(nodePoolPrefab);
    }
}

/**对象池预制体的枚举值(对应枚举名数组) */
export enum NODEPOOLPREFABTYPE {
    /**金币 */
    CellItem = 0,
    /**选择CellItem按钮 */
    SelectCellItemBtn = 1,
    /**爆炸 */
    Baozha = 2,
    /**方块背景 */
    CellBg = 3,
    /**消除得分 */
    EliminateScore = 4,
    /**Bonus提示 */
    BonusTip = 5,
    /**得分能量 */
    ScoreEnergy = 6,
    /**锤子特效 */
    Hammer = 7,
    /**变化特效 */
    Change = 8,
    /**提示item */
    TipItemUI = 10,
    /**目标达成 */
    GetTargetScoreTip = 11,
    /**得分 */
    GetScore = 13,
    /**图片提示item */
    TipSpriteItemUI = 14,
}
