import { Asset, assetManager, AssetManager } from "cc";

export class resManager {

    private static _instance: resManager;
    private constructor() { }
    public static get instance(): resManager {
        if (!this._instance) {
            this._instance = new resManager();
        }
        return this._instance;
    }

    /**
     * 从bundle中加载某个资源，优先使用缓存中的
     * @param bundleName bundle名称
     * @param path 资源路径
     * @param assetType 资源类型
     * @param onProgress 加载进度回调
     * @param onComplete 加载成功回调
     */
    loadAsset(bundleName: string, path: string, assetType: any, onProgress?: Function, onComplete?: Function) {
        let bundle = assetManager.getBundle(bundleName);
        if (bundle && bundle.get(path, assetType)) {
            if (onComplete) {
                onComplete(null, bundle.get(path, assetType));
            }
            return;
        }

        let loadAssetFunc = () => {
            bundle.load(path, assetType, (finish: number, total: number) => {
                if (onProgress) {
                    onProgress(finish, total);
                }
            }, (err, asset) => {
                if (err) {
                    console.log("ResManager.loadAsset error:" + err.message, bundleName, path, err);
                    if (onComplete) {
                        onComplete(err);
                    }
                    return;
                }
                if (onComplete) {
                    onComplete(null, asset);
                }
            });
        };

        if (!bundle) {
            assetManager.loadBundle(bundleName, (err, retBundle) => {
                if (err) {
                    if (onComplete) {
                        onComplete(err);
                    }
                    return;
                }
                bundle = retBundle;
                loadAssetFunc();
            });
            return;
        }

        loadAssetFunc();
    }

    /**
     * 加载某个bundle中的批量资源
     * @param bundleName bundle名称
     * @param pathArr 资源路径数组
     * @param assetType 资源类型
     * @param onProgress 进度回调
     * @param onComplete 结束回调
     */
    loadAssetByPathArr(bundleName: string, pathArr: string[], assetType: any, onProgress?: Function, onComplete?: Function) {
        let total = pathArr.length;
        if (total <= 0) {
            if (onComplete) {
                onComplete();
            }
            return;
        }
        let count = 0;
        let arr = [];
        for (let i = 0; i < total; i++) {
            let path = pathArr[i];
            this.loadAsset(bundleName, path, assetType, null, (err, asset) => {
                count++;
                arr.push(asset);
                if (onProgress) {
                    onProgress(count, total, asset);
                }
                if (count >= total) {
                    if (onComplete) {
                        onComplete(arr);
                    }
                }
            });
        }
    }

    /**
     * 预加载某个bundle中的批量资源
     * @param bundleName bundle名称
     * @param pathArr 资源路径数组
     * @param assetType 资源类型
     * @param onProgress 进度回调
     * @param onComplete 结束回调
     */
    preloadAssetByPathArr(bundleName: string, pathArr: string[], assetType: any, onProgress?: Function, onComplete?: Function) {
        let total = pathArr.length;
        if (total <= 0) {
            if (onComplete) {
                onComplete();
            }
            return;
        }
        let count = 0;
        let arr = [];
        for (let i = 0; i < total; i++) {
            let path = pathArr[i];
            this.loadAsset(bundleName, path, assetType, null, (err, asset) => {
                count++;
                arr.push(asset);
                if (onProgress) {
                    onProgress(count, total, asset);
                }
                if (count >= total) {
                    if (onComplete) {
                        onComplete(arr);
                    }
                }
            });
        }
    }

    /**
     * 加载bundle某个目录下的所有资源，目录中不要包含子目录，因为回调中拿不到资源的相对路径
     * @param bundleName bundle名称
     * @param dir 目录
     * @param assetType 资源类型
     * @param onProgress 进度回调
     * @param onComplete 成功回调
     */
    loadAssetByBundleDir(bundleName: string, dir: string, assetType: any, onProgress?: Function, onComplete?: Function) {
        let bundle = assetManager.getBundle(bundleName);

        let loadAssetFunc = () => {
            bundle.loadDir(dir, assetType, (finish: number, total: number, item: AssetManager.RequestItem) => {
                if (onProgress) {
                    onProgress(finish, total, item);
                }
            }, (err, assetArr) => {
                if (err) {
                    console.log("ResManager.loadAssetByBundleDir loadDir error:" + err.message, err);
                }
                if (onComplete) {
                    onComplete(assetArr);
                }
            });
        };

        if (!bundle) {
            assetManager.loadBundle(bundleName, (err, retBundle) => {
                if (err) {
                    console.log("ResManager.loadAssetByBundleDir loadBundle error:" + err.message, err);
                    return;
                }
                bundle = retBundle;
                loadAssetFunc();
            });
            return;
        }

        loadAssetFunc();
    }

    /**
     * 直接从缓存中获取资源
     * @param bundleName bundle名称
     * @param path 资源路径
     */
    getAsset(bundleName: string, path: string): any {
        let bundle = assetManager.getBundle(bundleName);
        if (bundle) {
            return bundle.get(path);
        }
        return null;
    }

    releaseAsset(asset: Asset) {
        assetManager.releaseAsset(asset);
    }

}