import AssetsBundleMgr from "../../utils/AssetsBundleMgr";

const { ccclass, disallowMultiple } = cc._decorator;
export enum EResType {
	UI,
	Prefab /** 直接加载预制的形式 */,
	SpriteFrame,
	SpriteAtlas,
	Spine,
	DragonBones,
	Texture2D,
	ImageAsset,
	Material,
	Audio,
	TTFFont /** TTF 字体 */,
	Text /** Txt 文件 */,
	ParticleAsset /** 粒子资源 */,
	FntFont /** Fnt 字体 */,
	Json,
}
/**
 * 精灵组件，自动管理资源的引用计数
 */
@ccclass
@disallowMultiple
export abstract class ResBaseAsset<T extends cc.Asset> extends cc.Component {
	// 动态加载的资源
	private m_Asset: T = undefined;
	private m_AssetUrl: string = undefined;

	get Asset(): T {
		return this.m_Asset;
	}

	protected onEnable(): void { }

	/**
	 * 加载 url 资源，只会回调最后一次加载
	 * @param bundle
	 * @param url
	 * @param cb
	 * @returns
	 */
	protected async loadAsset(bundle: string, url: string, type: any, cb?: (asset: T) => void) {
		let that = this;
		AssetsBundleMgr.loadBundle(bundle, (err, bundle) => {
			if (err) {
				console.log("SpineNode:bundle load failed:", url, err);
				cb(null);
				return;
			}
			let cacheAsset: T = bundle.get(url, type);
			if (cacheAsset) {
				if (that.m_Asset) {
					this.addDelayRelease(that.m_Asset);
				}
				cacheAsset.addRef();
				that.m_Asset = cacheAsset;
				cb(cacheAsset);
			} else {
				bundle.load(url, type, (err: Error, asset: T) => {
					if (err) {
						console.warn("asset not found:", url, err.message);
						cb(null);
						return;
					}
					if (that.m_Asset) {
						// that.m_Asset.decRef();
						this.addDelayRelease(that.m_Asset);
					}
					asset.addRef();
					that.m_Asset = asset;
					cb(asset);
				});
			}
		});
	}

	/**
	 * 重置资源
	 */
	public resetRes(): void {
		if (this.m_Asset) {
			// this.m_Asset.decRef();
			this.addDelayRelease(this.m_Asset);
			this.m_Asset = null;
			this.m_AssetUrl = null;
		}
	}

	protected onDestroy(): void {
		this.resetRes();
	}

	/** 10秒延迟释放资源 */
	protected addDelayRelease(asset: cc.Asset) {
		setTimeout(() => {
			asset.decRef();
		}, 30000);
	}
}
