import GameMgr from "../Mgr/GameMgr";
import { DataMgr } from "../Mgr/DataMgr";
import {getTexture} from "../utils";

/* type AltaData = {
    key: string,
    frameRate: number,
    frames: {
        x: number,  //x,y,w,h为图集上的切图位置数据
        y: number,
        w: number,
        h: number
    }[]
} */

interface Frame {
    x: number,
    y: number,
    texture: engine.Texture
}

export class FrameAnimationMgr extends GameMgr {
    constructor() { super("FrameAnimationMgr") }
    public playingAnimations: FrameAnimation[] = [];
    protected onUpdate() {
        if (this.pause) return;
        const filters: FrameAnimation[] = [];
        let anim: FrameAnimation = null;
        for (let i = 0; i < this.playingAnimations.length; i++) {
            anim = this.playingAnimations[i];
            anim.onUpdate();

            if (anim.curPos >= anim.frameCount) {
                anim.onCompleted && anim.onCompleted();
            } else {
                filters.push(anim);
            }
        }

        this.playingAnimations = filters;
    }
}

export default class FrameAnimation extends engine.Container {
    private frames: Frame[] = [];
    public frameCount: number = 0;
    public curPos: number = 0;
    private frameTimer: number = 0;
    private frameRate: number = 60;
    private sprite: engine.Sprite = new engine.Sprite;

    private static caches: {
        [key: string]: {
            frameCount: number,
            frameRate: number,
            frames: Frame[]
        }
    } = {};

    public static loadRes(texture: engine.Texture, egretData: any) {
        let name: string = null;
        const mc = egretData.mc;
        for (let key in mc) { name = key; break; }

        if (!FrameAnimation.caches[name]) {

            let altaData = {};
            for (let i in egretData.res) {
                altaData[name + "_" + i] = egretData.res[i];
            }
            engine.createTextureSheet(texture.baseTexture, altaData);

            let frames: Frame[] = [];

            const framesData = mc[name].frames;
            for (let i in framesData) {
                frames[i] = {
                    x: framesData[i].x,
                    y: framesData[i].y,
                    texture: getTexture(name + "_" + framesData[i].res)
                }
            }

            FrameAnimation.caches[name] = {
                frameRate: mc[name].frameRate,
                frameCount: Object.keys(altaData).length,
                frames: frames
            }
        }
    }

    constructor(key: string) {
        super();
        if (!FrameAnimation.caches[key]) {
            console.error("unloaded animation:" + key);
            return;
        }

        this.frames = FrameAnimation.caches[key].frames;
        this.frameCount = Object.keys(this.frames).length;
        this.frameRate = FrameAnimation.caches[key].frameRate;
        this.addChild(this.sprite);
    }

    onUpdate() {
        if (this.frameTimer >= 60 / this.frameRate) {
            if (this.curPos >= this.frameCount) {
                return;
            } else {
                const frameData = this.frames[this.curPos];
                this.sprite.texture = frameData.texture;
                this.sprite.x = frameData.x;
                this.sprite.y = frameData.y;
            }
            this.curPos++;
            this.frameTimer = 0;
        } else {
            this.frameTimer++;
        }
    }

    play() {
        DataMgr.game._animationMgr.playingAnimations.push(this);
    }

    onCompleted: () => void;
}