
import { assetManager, AudioClip, director, ImageAsset, instantiate, JsonAsset, Node, Prefab, SkinnedMeshRenderer, Sprite, SpriteAtlas, SpriteFrame, Texture2D, TextureCube } from "cc"

import { AssetType } from "./Enums";
import { Global } from "./Global";
import { PoolMgr } from "./PoolMagr";

export default class ResMgr {
    private _abBundleMap: Object = {};
    private _atlasMap = {};
    public _jsonAssetMap = {};
    public _clipMap = {};
    public _loadStemp = null;
    private loadTime = 0;
    _totalTime = 0

    private static _ins: ResMgr = null;
    public static get ins() {
        if (!this._ins) {
            this._ins = new ResMgr();
        }

        return this._ins;
    }

    printTimer(name: string = "", end = false) {
        this.loadTime = Date.now() - this._loadStemp;
        this._loadStemp = Date.now();
        this._totalTime += this.loadTime
        console.log(name + "，load time===", this.loadTime, "ms")
        if (end) {
            console.log("Load finish, total time===", this._totalTime, "ms")
        }

    }

    public async loadBundle(index: number, ratio: number = 0): Promise<void> {
        if (!this._loadStemp) this._loadStemp = Date.now();
        const rate = Global.LoadingRate;
        const name = "Bundle" + index
        return new Promise<void>((resolve, reject) => {
            assetManager.loadBundle(name, (err: any, bundle: any) => {
                if (err) {
                    console.error("Bundle" + index + " load error, error==", err)
                } else {
                    if (index != 2) this._abBundleMap[index] = bundle;
                    this.printTimer("Bundle" + index + "__" + "load success")
                    Global.LoadingRate = rate + ratio;
                    resolve && resolve();
                }
            })
        })
    }

    public async loadRes(index: number, type: any, ratio: number = 0): Promise<void> {
        const rate = Global.LoadingRate;
        return new Promise<void>((resolve, reject) => {
            this._abBundleMap[index].loadDir(type.path, type.type, (finished: number, total: number) => {
                // this._loadTools.setValue(idx, finished / total); 
                if (ratio > 0) Global.LoadingRate = rate + ratio * finished / total
            }, (err: any, assets: any[]) => {
                if (err) {
                    console.error("Error===", err);
                    resolve && resolve();
                }
                let asset: any
                if (type == AssetType.Prefab) {
                    for (let i = 0; i < assets.length; i++) {
                        asset = assets[i];

                        //console.log("zh:prefab name==", asset.data.name);
                        //console.log("zh:prefab asset==",asset);
                        PoolMgr.ins.setPrefab(asset.data.name, asset);
                        // Global.Debug && console.log("prefab name==", asset.data.name)
                    }
                }
                if (type == AssetType.Sound) {
                    for (let i = 0; i < assets.length; i++) {
                        asset = assets[i];
                        // Global.Debug && console.log("clip name==", asset.name)
                        if (!this._clipMap[asset.name]) this._clipMap[asset.name] = asset
                    }
                }
                if (type == AssetType.Atlas) {
                    for (let i = 0; i < assets.length; i++) {
                        asset = assets[i];
                        // Global.Debug && console.log("atlas name==", asset.name)
                        if (!this._atlasMap[asset.name]) this._atlasMap[asset.name] = asset
                    }
                }
                if (type == AssetType.Json) {
                    for (let i = 0; i < assets.length; i++) {
                        asset = assets[i];
                        // Global.Debug && console.log("json name==", asset.name)
                        if (!this._jsonAssetMap[asset.name]) this._jsonAssetMap[asset.name] = asset.json
                    }
                }
                this.printTimer("Bundle" + index + "__" + type.path + "loaded success")
                resolve && resolve();
            })
        })
    }

    public async loadPrefab(info): Promise<void> {
        const rate = Global.LoadingRate;
        return new Promise<void>((resolve, reject) => {
            this._abBundleMap[info.bundle].load(info.path + info.name, function (err, Prefab) {
                if (err) {
                    console.error("Error info===", err);
                    resolve && resolve();
                }
                PoolMgr.ins.setPrefab(info.name, Prefab);
                // console.log("预制体名字===", info.name);
                resolve && resolve();
            })
        }
        )
    }


    public getClip(name: string) {
        return this._clipMap[name];
    }



}