
import { ResConst } from "../ConstDefine/ResConst"
import Manager from "./Manager"


export default class AssetMgr extends Manager {
    static get TypeName(): string { return "AssetMgr" }

    private preProgress: number = 0
    public get PreProgress(): number { return this.preProgress }

    public async start() {
        console.log("AssetMgr onStart")
    }

    public release() {
        console.log("AssetMgr onRelease")
    }

    public async startPreLoad() {
        let promises = []
        for (let v of ResConst.AwaitLoadAssets) {
            promises.push(this.preLoadAsset(v[0], v[1]))
        }
        await Promise.all(promises)
        this.preProgress = 1
        // this.startNoAwaitLoad()
    }

    // private startNoAwaitLoad() {
    //     this.preLoadAsset(ResConst.UiABName, "Scene/SceneObj/Player", cc.Prefab)
    //     this.preLoadAsset(ResConst.UiABName, "Menu/MenuView", cc.Prefab)
    //     this.preLoadAsset(ResConst.UiABName, "Bg/BgView", cc.Prefab)
    // }

    // private allProgress() {
    //     return ResConst.AwaitLoadAssets.length
    // }

    /**
     * 预加载不需要等待
    */
    public async preLoadAsset(abName: string, resName: string, type?: typeof cc.Asset) {
        return new Promise<void>((resolve, reject) => {
            cc.assetManager.loadBundle(abName, (err, bundle: cc.AssetManager.Bundle) => {
                if (!err) {
                    bundle.preload(resName, type, (err, items) => {
                        resolve()
                    })
                } else {
                    reject()
                }
            })
        })
    }

    /**
     * 预加载不需要等待
     * ""表示整个目录
    */
    public preLoadAssetDir(abName: string, dir: string = "", type: typeof cc.Asset) {
        cc.assetManager.loadBundle(abName, (err, bundle: cc.AssetManager.Bundle) => {
            if (!err) {
                bundle.preloadDir(dir, type, (err, items) => { })
            }
        })
    }

    //读取目录下所有类型文件
    public loadAssetDirAsync<T extends cc.Asset>(abName: string, type: typeof cc.Asset = cc.Asset): Promise<T[]> {
        return new Promise((resolve, reject) => {
            cc.assetManager.loadBundle(abName, (err, bundle) => {
                if (err) {
                    cc.error("loadBundleAsync error", abName, err)
                    reject(err)
                } else {
                    bundle.loadDir("./",type,(err,assets)=>{
                        if (err) {
                            cc.error("loadAssetAsync error")
                            reject(err)
                        }
                        else {
                            // assets?.addRef()
                            resolve(<T[]>assets)
                        }
                    })
                }
            })
        })

    }

    public loadAssetAsync<T extends cc.Asset>(abName: string, resName: string, type: typeof cc.Asset = cc.Asset): Promise<T> {
        return new Promise((resolve, reject) => {
            cc.assetManager.loadBundle(abName, (err, bundle) => {
                if (err) {
                    cc.error("loadBundleAsync error", abName, resName, err)
                    reject(err)
                } else {
                    bundle.load(resName, type,
                        //complete
                        (err, assets) => {
                            if (err) {
                                cc.error("loadAssetAsync error", resName)
                                reject(err)
                            }
                            else {
                                // assets?.addRef()
                                resolve(<T>assets)
                            }
                        })
                }
            })
        })
    }

    public releaseAsset(asset: cc.Asset, _?)
    public releaseAsset(abName: string, resName: string)
    public releaseAsset(a1: any, a2: any) {
        if (a1 instanceof cc.Asset) {
            if (cc.isValid(a1)) {
                a1?.decRef()
            }
        } else {
            if (!a1 || !a2) return
            let ab = cc.assetManager.getBundle(a1)
            let info: Record<string, any> = ab.getInfoWithPath(a2)
            let uuid = info?.uuid
            let asset = cc.assetManager.assets?.get(uuid)
            asset?.decRef()
            if (asset?.refCount <= 0) {
                // console.log("释放",asset?.name,cc.assetManager.assets?.count)
            }
        }

    }

}