import { assetManager, Prefab, ImageAsset, resources, sp, SpriteAtlas, SpriteFrame, Texture2D } from "cc";
import Singleton from "../plugin/Singleton";
import { GameConst } from "../Config";
import LogMgr from "./LogMgr";
import EventManager from "./EventManager";

export default class ResManger extends Singleton {
    private static _res: { [key: string]: any } = {};
    private static comAtlas: SpriteAtlas = null;//通用图集
    private static mineAtlas: SpriteAtlas = null;//地砖矿石图集
    private static artAtlas: SpriteAtlas = null;//文物图集
    private static tileAtlas: SpriteAtlas = null;//文物图集
    private static _cardFrames: { [key: string]: SpriteFrame } = {};//远程图片挂载
    private static _spine: { [key: string]: any } = {};//spine动画挂载

    static init() {
        this._res = {};
        resources.load('plist/tile', SpriteAtlas, (err: Error, res: SpriteAtlas) => {
            if (err) {
                LogMgr.error(`load commonAtlas error:${err}`);
                return;
            }
            this.tileAtlas = res;
        });
        LogMgr.log(`资源管理器初始化成功`);
    }
    /**加载本地有的资源图片
     * @param imgPath 图片路径
     * @param cb 回调函数
     */
    static loadImg(imgPath: string, cb: Function) {
        if (this._res[imgPath]) {
            cb(this._res[imgPath]);
            return;
        }

        resources.load(`${imgPath}/spriteFrame`, SpriteFrame, (err: Error, res: SpriteFrame) => {
            if (err) {
                LogMgr.error(`load ${imgPath} err:${err}`);
                return;
            }
            this._res[imgPath] = res;
            cb(this._res[imgPath]);
        });
    }
    /**加载远程图片：卡牌内容素材
     * @param imgName 图片名一般是指卡牌的cardId
     * @param imgUrl 图片网址，没有主域名的url
     * @param cb 回调函数
     */
    static loadRemoteImg(imgName: string | number, imgUrl: string, cb: Function) {
        //本地cocos网页调试环境不加载远程图片
        if (GameConst.ignoreRemoteImg) {
            cb(null);
            //LogMgr.warn(`cocos网页调试环境不加载远程图片:${imgName} => ${imgUrl}`);
            return;
        }
        if (this._cardFrames[imgName]) {
            cb(this._cardFrames[imgName]);
            return;
        }
        if (imgUrl.indexOf('http://') == -1) {
            //imgUrl = GameConst.serverIp + imgUrl;
            imgUrl = 'https://h5tg.yszdata.cn' + imgUrl;
        }
        assetManager.loadRemote<ImageAsset>(imgUrl, (error: Error, imageAsset: ImageAsset) => {
            if (error) {
                LogMgr.error(`ResManger loadRemoteImg ${imgUrl} error:`, error);
                return;
            }
            //LogMgr.log('loadRemoteImg,imgName:', imgName,imgUrl);
            const spriteFrame = new SpriteFrame();
            const texture = new Texture2D();
            texture.image = imageAsset;
            spriteFrame.texture = texture;
            this._cardFrames[imgName] = spriteFrame;
            cb(this._cardFrames[imgName]);
        });
    }
    static getTileSP(imgKey: string | number) {
        if (!this.tileAtlas) {
            LogMgr.error(`tileAtlas is null,imgKey:${imgKey}`);
            return null;
        } else {
            return this.tileAtlas.getSpriteFrame('' + imgKey);
        }
    }
    /**获取文物图集里面的图片
         * @param imgKey 图片名称
         */
    static getArtSP(imgKey: string) {
        if (!this.artAtlas) {
            LogMgr.error(`artAtlas is null,imgKey:${imgKey}`);
            return null;
        } else {
            return this.artAtlas.getSpriteFrame(imgKey);
        }
    }
    //加载spine骨骼动画
    public static loadSpine(spKey: string, animKey: string, spCom: sp.Skeleton) {
        if (!this._spine[spKey]) {
            resources.load('spine/' + spKey + '/skeleton', sp.SkeletonData, (err, data) => {
                if (err) {
                    LogMgr.error('loadSpine', err);
                    return;
                }
                spCom.skeletonData = data;
                if (animKey) {
                    spCom.setAnimation(0, animKey, animKey == 'idle' ? true : false);
                }
            })
        } else {
            spCom.skeletonData = this._spine[spKey];
            if (animKey) {
                spCom.setAnimation(0, animKey, animKey == 'idle' ? true : false);
            }
        }
    }
    //加载远程spine文件json格式 spKey : https://h5tg.yszdata.cn/tgImages/pet/spine/hero_tengtengshe
    public static loadRemoteSpine(url: string, cb: Function) {
        let strArr: string[] = url.split('/'), spKey = strArr[strArr.length - 1];
        if (this._spine[spKey]) {
            cb(this._spine[spKey]);
            return;
        }
        //console.log('spKey:', spKey);
        let imageUrl: string = url + ".png";
        let skeUrl: string = url + ".json";
        let atlasUrl: string = url + ".atlas";
        assetManager.loadAny([{ url: atlasUrl, ext: '.txt' }, { url: skeUrl, ext: '.txt' }], (error, assets) => {
            if (error) {
                console.log("加载远程骨骼动画失败，atlasUrl：" + atlasUrl + "  skeUrl:" + skeUrl);
                return;
            }
            assetManager.loadRemote(imageUrl, (error, imageAsset: ImageAsset) => {
                if (error) {
                    console.log("加载远程骨骼动画图片失败，imageUrl：" + imageUrl);
                    EventManager.emit('showHideLoading', false);
                    return;
                }
                let asset = new sp.SkeletonData();
                asset.skeletonJson = assets[1];
                asset.atlasText = assets[0];
                let texture = new Texture2D();
                texture.image = imageAsset;
                asset.textures = [texture];
                asset.textureNames = [spKey + '.png'];
                this._spine[spKey] = asset;
                cb(asset);
            });
        });
    }
    public static loadPetSpine(spKey: string, cb: Function) {
        resources.load('spine/' + spKey, sp.SkeletonData, (err, data) => {
            if (err) {
                LogMgr.error('loadPetSpine', err);
                return;
            }
            cb && cb(data);
        });
    }
    public static loadRemotePetSpine(url: string, cb: Function) {
        let strArr: string[] = url.split('/'), spKey = strArr[strArr.length - 1];
        if (this._spine[spKey]) {
            cb(this._spine[spKey]);
            return;
        }
        let imageUrl: string = url + ".png";
        let skeUrl: string = url + ".skel";
        let atlasUrl: string = url + ".atlas";
        assetManager.loadAny([{ url: atlasUrl, ext: '.txt' }, { url: skeUrl, ext: '.bin' }], (skelErr: Error, skeAssets) => {
            if (skelErr) {
                LogMgr.error(`loadRemotePetSpine ：${url}，err:${skelErr}`);
                return;
            }
            //LogMgr.warn(`loadRemotePetSpine spKey：${spKey}，skeAssets:${skeAssets}`);
            assetManager.loadRemote(imageUrl, (imgErr: Error, img: ImageAsset) => {
                if (imgErr) {
                    LogMgr.error(`loadRemotePetSpine imgUrl：${url}，err:${imgErr}`);
                    return;
                }
                let texture = new Texture2D();
                texture.image = img;
                let asset = new sp.SkeletonData();
                asset._nativeAsset = skeAssets[1];//若出错改成 skeAssets[1]._buffer
                asset.atlasText = skeAssets[0];//若出错改成 skeAssets[0].text
                asset.textures = [texture];
                asset.textureNames = [spKey + '.png'];
                asset._uuid = spKey; // 可以传入任意字符串，但不能为空
                asset._nativeUrl = skeUrl; // 传入一个二进制路径用作 initSkeleton 时的 filePath 参数使用
                this._spine[spKey] = asset;
                cb(asset);
            });
        });
    }
    public static loadRemoteSkillSpine(url: string, cb: Function) {
        let strArr: string[] = url.split('/'), spKey = strArr[strArr.length - 1];
        if (this._spine[spKey]) {
            cb(this._spine[spKey]);
            return;
        }
        let imageUrl: string = url + ".png";
        let skeUrl: string = url + ".skel";
        let atlasUrl: string = url + ".atlas";
        assetManager.loadAny([{ url: atlasUrl, ext: '.txt' }, { url: skeUrl, ext: '.bin' }], (skelErr: Error, skeAssets) => {
            if (skelErr) {
                LogMgr.error(`loadRemotePetSpine ：${url}，err:${skelErr}`);
                cb(null);
                return;
            }
            //LogMgr.warn(`loadRemotePetSpine spKey：${spKey}，skeAssets:${skeAssets}`);
            assetManager.loadRemote(imageUrl, (imgErr: Error, img: ImageAsset) => {
                if (imgErr) {
                    LogMgr.error(`loadRemotePetSpine imgUrl：${url}，err:${imgErr}`);
                    return;
                }
                let texture = new Texture2D();
                texture.image = img;
                let asset = new sp.SkeletonData();
                asset._nativeAsset = skeAssets[1];//若出错改成 skeAssets[1]._buffer
                asset.atlasText = skeAssets[0];//若出错改成 skeAssets[0].text
                asset.textures = [texture];
                asset.textureNames = [spKey + '.png'];
                asset._uuid = spKey; // 可以传入任意字符串，但不能为空
                asset._nativeUrl = skeUrl; // 传入一个二进制路径用作 initSkeleton 时的 filePath 参数使用
                this._spine[spKey] = asset;
                cb(asset);
            });
        });
    }
    public static loadRemoteMonsterSpine(url: string, cb: Function) {
        let strArr: string[] = url.split('/'), spKey = strArr[strArr.length - 1];
        if (this._spine[spKey]) {
            cb(this._spine[spKey]);
            return;
        }
        let imageUrl: string = url + ".png";
        let skeUrl: string = url + ".skel";
        let atlasUrl: string = url + ".atlas";
        assetManager.loadAny([{ url: atlasUrl, ext: '.txt' }, { url: skeUrl, ext: '.bin' }], (skelErr: Error, skeAssets) => {
            if (skelErr) {
                LogMgr.error(`loadRemotePetSpine ：${url}，err:${skelErr}`);
                return;
            }
            //LogMgr.warn(`loadRemotePetSpine spKey：${spKey}，skeAssets:${skeAssets}`);
            assetManager.loadRemote(imageUrl, (imgErr: Error, img: ImageAsset) => {
                if (imgErr) {
                    LogMgr.error(`loadRemotePetSpine imgUrl：${url}，err:${imgErr}`);
                    return;
                }
                let texture = new Texture2D();
                texture.image = img;
                let asset = new sp.SkeletonData();
                asset._nativeAsset = skeAssets[1];//若出错改成 skeAssets[1]._buffer
                asset.atlasText = skeAssets[0];//若出错改成 skeAssets[0].text
                asset.textures = [texture];
                asset.textureNames = [spKey + '.png'];
                asset._uuid = spKey; // 可以传入任意字符串，但不能为空
                asset._nativeUrl = skeUrl; // 传入一个二进制路径用作 initSkeleton 时的 filePath 参数使用
                this._spine[spKey] = asset;
                cb(asset);
            });
        });
    }
    public static getSpine() {
        LogMgr.warn('资源管理器getSpine:', this._spine)
        return this._spine;
    }
    /**
    * 预加载资源
    * @param pageName 页面名称
    * @param params 
    */
    public static preloadPage(pageName: string) {
        resources.load(`page/${pageName}`, Prefab, (error: Error, Prefab: Prefab) => {
            if (error) {
                LogMgr.error(`showPage,load page:${pageName} err:${error}`);
                return;
            }
            LogMgr.log(`预加载页面:${pageName} success`);
        });
    }

}