import { Asset, AssetManager, Prefab, resources, SpriteAtlas, SpriteFrame, TiledMapAsset } from "cc";

class ResourcesMgr{

    static instance: ResourcesMgr = null;

    private _spriteFrames: Map<string,SpriteFrame> = new Map();
    private _prefabs: Map<string, Prefab> = new Map();
    private _tmxAsset: Map<string,TiledMapAsset> = new Map();
    async loadAllRes(path: string, onProgress:(
        (finish: number,total: number, item: AssetManager.RequestItem)=>void) = null){
        //下载resources文件夹下的所有资源
        //异步函数
        const assets: Asset[] = await new Promise<Asset[]>((value, reject)=>{
            resources.loadDir(path, onProgress, (err:Error,assets: Asset[])=>{
                //完成回调 assets就是那些所有资源的数组
                if(err){
                    reject(err);
                }
                else{
                    value(assets);
                }
                
            })
        })
       //遍历所有资源 分门别类存储到对应的容器中
       for(const asset of assets){
          this.addRes(asset, asset.name);
          //console.log(asset)
       }
    }

    async load(path: string, name?: string, atlas: boolean = false){
        const asset: Asset = await new Promise((value, reject)=>{
            resources.load(path, (err: Error, asset: Asset)=>{
                if(err){
                    reject(err);
                }
                else{
                    value(asset);
                }
            })
        });
        this.addRes(asset, name, atlas)
    }

    protected addRes(asset: Asset, name: string,  contactName: boolean = false){
        if(asset instanceof SpriteFrame){
            this._spriteFrames.set(String(name), asset);
        }
        else if(asset instanceof Prefab){
            this._prefabs.set(String(name), asset);
            //console.log(this._prefabs)
        }
        else if(asset instanceof TiledMapAsset){
            this._tmxAsset.set((name), asset)
            //console.log(this._tmxAsset)
        }
        else if(asset instanceof SpriteAtlas){
            for(const frame of asset.getSpriteFrames()){
                let n: string = frame.name;
                if(contactName){
                    n = name + n;    
                }
                this._spriteFrames.set(n, frame);
            }
        }
    }

    getSpriteFrame(name: string): SpriteFrame{
        return this._spriteFrames.get(name);
    }

    getPrefab(name: string): Prefab{
        return this._prefabs.get(name);
    }
    getTmxAsset(name: string): TiledMapAsset{
        return this._tmxAsset.get(name);
    }
}

export const resMgr: ResourcesMgr = ResourcesMgr.instance = new ResourcesMgr();

