import { JNFrameInfo } from "../../../../../extensions/ngame/assets/ngame/sync/frame/JNSyncFrame";

//流程模式
export enum GFSMProcessMode{
    Execute,//正常运行
    WaitExecute,//等待执行
}

//流程信息
export interface GFSMProcessInfo{
    //备注
    title:string;
    //模式
    mode?:GFSMProcessMode;
    //执行方法
    execute?:(dt:number,info:GFSMProcessInfo,frame:JNFrameInfo) => number;
    //前往
    to?:number[];
}

//流程枚举
export enum GFSMProcessEnum{
    Reset = -1,//重置
    Wait = -2,//等待
}

//状态机基类
export default class GFSMBase{

    //是否关闭
    isClose:boolean = false;

    //状态流程图
    process:{[key:number]:GFSMProcessInfo} = {};

    //开始流程Id
    start:number = 0;

    //当前流程
    current:number = 0;

    //状态机刷新
    onUpdate(dt:number,frame:JNFrameInfo){

        if(this.isClose) return;

        if(!this.start) this.start = 0;
        if(!this.current) this.current = 0;
        //运行流程
        this.execute(this.process[this.current],dt,frame);

    }

    close(){
        this.isClose = true;
    }

    open(){
        this.current = 0;
        this.isClose = false;
    }

    //执行流程
    execute(process:GFSMProcessInfo,dt:number,frame:JNFrameInfo){
        if(!process) return;

        process.mode = process.mode || GFSMProcessMode.Execute;
        process.to = process.to || [];

        let next:number;
        let isReset:boolean = true;

        //执行流程
        switch(process.mode){
            case GFSMProcessMode.Execute:
                //执行方法
                next = process.execute(dt,process,frame);
                break;
            case GFSMProcessMode.WaitExecute:
                //执行等待方法
                next = process.execute(dt,process,frame);
                //如果 状态 Wait 则 不重置 下一次状态从当前开始流程执行
                if(next == GFSMProcessEnum.Wait){
                    isReset = false;
                }
                break;
        }

        if(process.to.indexOf(next) == -1 && next != GFSMProcessEnum.Wait && next != GFSMProcessEnum.Reset){
            console.log(`[GFSM]: 流程To中没有这个流程 请检查代码`,process,next);
            return;
        }
        if(!this.process[next]) next = null;

        if(next){
            this.current = next;
            //运行下一个流程
            this.execute(this.process[next],dt,frame);
        }else{
            if(isReset){
                //重置
                this.current = this.start;
            }
        }

    }

}
