import { Vec2 } from "cc";
import GRoleBase from "../../role/GRoleBase";
import GFSMBase, { GFSMProcessEnum, GFSMProcessInfo, GFSMProcessMode } from "../GFSMBase";
import { GRoleUtil } from "../../../entity/GRole";
import GRoleDefault from "../../role/GRoleDefault";


//流程枚举
enum ProcessEnum {
    //寻找敌人
    SeekEnemy = 0,
    //移动到可攻击范围
    MoveToAttackRange = 1,
    //攻击敌人
    AttackEnemy = 2,
    //回阵型
    MoveToTactical = 3,
    //释放技能
    ReleaseSkills = 4,
}

export default class GFSMDefault extends GFSMBase{

    _player:() => GRoleDefault;

    get player(): GRoleDefault {
        return this._player();
    }

    //锁定的敌人
    _enemy:() => GRoleBase<{}>;
    get enemy():GRoleBase<{}>{
        if(this._enemy)
            return this._enemy();
        return null;
    }

    //流程图
    process: { [key: number]: GFSMProcessInfo; } = {
        [ProcessEnum.SeekEnemy]:{
            title:"寻找敌人",
            execute: this.onSeekEnemyProcess.bind(this),
            // to:[ProcessEnum.MoveToAttackRange], //移动到可攻击范围
            to:[ProcessEnum.MoveToAttackRange,ProcessEnum.MoveToTactical], //移动到可攻击范围
        },
        [ProcessEnum.MoveToAttackRange]:{
            title:"移动到可攻击范围",
            mode:GFSMProcessMode.WaitExecute,
            execute: this.onMoveToAttackRangeProcess.bind(this),
            to:[ProcessEnum.AttackEnemy] //攻击敌人 回阵型
        },
        [ProcessEnum.AttackEnemy]:{
            title:"攻击敌人",
            mode:GFSMProcessMode.WaitExecute,
            execute: this.onAttackProcess.bind(this),
            to:[ProcessEnum.SeekEnemy,ProcessEnum.ReleaseSkills],//移动回阵型 释放技能
        },
        [ProcessEnum.MoveToTactical]:{
            title:"获取初始点",
            mode:GFSMProcessMode.WaitExecute,
            execute: this.onMoveToInitPosProcess.bind(this),
            to:[ProcessEnum.SeekEnemy],//移动回阵型
        },
        [ProcessEnum.ReleaseSkills]:{
            title:"释放技能",
            mode:GFSMProcessMode.WaitExecute,
            execute: this.onReleaseSkillsProcess.bind(this),
            to:[ProcessEnum.AttackEnemy],//继续攻击
        }
    }

    constructor(player:GRoleDefault){
        super();
        this._player = GRoleUtil.get(player);
    }


    //寻敌
    onSeekEnemy(): GRoleBase<{}> {
        return this.player.onQueryEunmy();
    }

    //寻敌流程
    onSeekEnemyProcess(dt:number):number{

        //播放等待
        this.player.fsmAnim.isMove = false;
        this.player.fsmAnim.isAttack = false;

        if(this.enemy){
            //如果有敌人 直接 攻击
            return ProcessEnum.MoveToAttackRange;
        }

        if((this._enemy = GRoleUtil.get(this.onSeekEnemy())) && this.enemy){
            //如果有敌人 直接 攻击
            return ProcessEnum.MoveToAttackRange;
        }else{
            //如果没有敌人则回去
            if(!(this.player.tacticalPos.equals(this.player.v2World))){
                return ProcessEnum.MoveToTactical
            }else{
                return GFSMProcessEnum.Reset;
            }
        }

    }

    //移动可攻击范围
    onMoveToAttackRangeProcess(dt:number){

        //播放移动
        this.player.fsmAnim.isMove = true;
        this.player.fsmAnim.isAttack = false;

        //如果没有敌人则重置
        if(!this.enemy) return GFSMProcessEnum.Reset;

        let distance = Vec2.distance(this.player.v2World,this.enemy.v2World);

        //如果在攻击范围则调用攻击 负责 靠近目标
        if(distance < this.player.range){
            return ProcessEnum.AttackEnemy;
        }else{
            //靠近目标
            this.player.onMoveTarget(this.enemy.v2World,dt);
            return GFSMProcessEnum.Wait;
        }

    }

    //移动回阵型
    onMoveToInitPosProcess(dt:number){

        //播放移动
        this.player.fsmAnim.isMove = true;
        this.player.fsmAnim.isAttack = false;

        if(this.player.onMoveTarget(this.player.tacticalPos,dt)){
            this.player.onRecoverTacticalTowards();
            //回到阵容 搜索敌人
            return ProcessEnum.SeekEnemy;
        }

        return GFSMProcessEnum.Wait;

    }
    
    //攻击敌人
    onAttackProcess(dt:number){
        //播放移动
        this.player.fsmAnim.isMove = false;
        this.player.fsmAnim.isAttack = true;
        //如果有敌人则攻击 没有 则 重置
        if(this.enemy){
            //朝向敌人
            this.player.onTowardsTarget(this.enemy);

            //是否可释放技能
            if(this.player.isReleaseSkill()){
                //则释放技能
                return ProcessEnum.ReleaseSkills;
            }else{
                return GFSMProcessEnum.Wait;
            }

        }else{
            return ProcessEnum.SeekEnemy;
        }
    }

    //释放技能
    onReleaseSkillsProcess(){

        //如果正在释放则等待
        if(this.player.isReleasingSkill()){
            return GFSMProcessEnum.Wait;
        }

        //释放技能
        if(this.player.isReleaseSkill()){
            //如果可以释放技能则释放
            this.player.onReleaseSkill();
            return GFSMProcessEnum.Wait;
        }else{
            //不可以则回到攻击
            return ProcessEnum.AttackEnemy;
        }

    }

    //获取 寻找敌人状态
    getSeekEnemyProcessEnum(){
        return ProcessEnum.SeekEnemy;
    }


}

