import ResSpriteAtlas from "./ResSpriteAtlas";
import UEBase from "./UEBase";

const { ccclass, property } = cc._decorator;

export interface IAnimationInfo {
    bundle: string,
    atlasUrl: string,
    anim: {
        run: { name: string, frames: string[], wrapMode: cc.WrapMode, sample: number }
    }
}
export interface Params_SpriteAtlasAnim {
    [anim: string]: {
        frames: string[],
        wrapMode: cc.WrapMode,
        sample: number, // 动画帧率，单位为帧/秒
    }
}

@ccclass
export class SpriteAtlasAnim extends UEBase {
    private _anim: cc.Animation;
    private _resSpriteAtlas: ResSpriteAtlas;
    private _animCfg: Params_SpriteAtlasAnim;

    /**
     * @param url 动画 SpriteAtlas Url
     * @param animCfg 动画配置
     */
    protected LoadAnimAsync(bundleKey: string, url: string, animCfg: Params_SpriteAtlasAnim, defaultAnim: string): Promise<boolean> {
        const that = this;
        that._animCfg = animCfg;
        that._anim = that.node.getComponent(cc.Animation);
        if (!this._anim) {
            this.node.addComponent(cc.Animation);
        }
        that._resSpriteAtlas = that.node.getComponent(ResSpriteAtlas);
        if (!that._resSpriteAtlas) {
            that.node.addComponent(ResSpriteAtlas);
        }
        return new Promise((resolve) => {
            that._resSpriteAtlas.LoadSpriteAtlas(bundleKey, url, (atlas: cc.SpriteAtlas) => {
                if (atlas) {
                    that.RemoveAllClips();
                    let sp: cc.SpriteFrame;
                    for (let clipName in that._animCfg) {
                        let animSpriteFrames: cc.SpriteFrame[] = [];
                        that._animCfg[clipName].frames.forEach(frameKey => {
                            sp = atlas.getSpriteFrame(frameKey);
                            if (sp) {
                                animSpriteFrames.push(sp);
                            } else {
                                console.error(`图集(${url})中不存在动画帧: ${frameKey}`);
                            }
                        });
                        that.AddClip(clipName, animSpriteFrames, that._animCfg[clipName].wrapMode, that._animCfg[clipName].sample);
                    }
                    if (defaultAnim) this.PlayAnim(defaultAnim);
                    resolve(true);
                } else {
                    resolve(false);
                }
            });
        })
    }

    /**
     * 
     * @param clipName 
     * @param animSpriteFrames 
     * @param sample 动画帧率，单位为帧/秒
     * @param wrapMode 
     */
    private AddClip(clipName: string, animSpriteFrames: cc.SpriteFrame[], wrapMode: cc.WrapMode, sample: number) {
        // 创建一个动画
        let clip = cc.AnimationClip.createWithSpriteFrames(animSpriteFrames, sample);
        clip.name = clipName;
        clip.wrapMode = wrapMode;
        this._anim.addClip(clip);
    }

    private RemoveAllClips() {
        if (!this._anim || !this._anim.isValid) return;
        const clips = this._anim.getClips();
        for (let i = clips.length - 1; i >= 0; --i) {
            this._anim.removeClip(clips[i]);
        }
    }

    /**
     * 播放动画
     * @param clipName 
     */
    PlayAnim(clipName: string) {
        this._anim.play(clipName);
    }

    StopAllAnim() {
        this._anim.stop();
    }

    /**
     * 监听动画完成
     * @param complete 
     */
    OnAnimComplete(complete: Function) {
        this._anim.on(cc.Animation.EventType.FINISHED, (type: string, state: cc.AnimationState) => {
            complete && complete(type);
        }, this);
    }
}
