/*
 * @Author       : feifei.song
 * @Date         : 2023-11-08 14:20:21
 * @LastEditors  : feifei.song
 * @LastEditTime : 2023-12-26 16:09:50
 * @FilePath     : \demoTest\JavaScripts\MoveWay.ts
 * @Description  : 
 */

export class MoveWay {

    /** 当前是否移动中 */
    public isMoving: boolean = false;

    /** 移动的角色 */
    private character: mw.Character | mw.GameObject;

    /** 移动的路点 */
    private points: mw.Vector[];

    /** 移动的速度 */
    private speed: number;

    /** 移动完成回调 */
    private overCall: () => void;

    /** 当前通过的路点 */
    private curIndex: number = 0;

    /** 当前方向 */
    private dir: mw.Vector = new mw.Vector();

    /** 是否是角色 */
    private isChara: boolean = false;

    /** 上一帧的位置 */
    private orgVector: mw.Vector = new mw.Vector();

    /** 当前帧的位置 */
    private nowVector: mw.Vector = new mw.Vector();

    /** 临时向量 */
    private tmpVector: mw.Vector = new mw.Vector();

    /** 临时向量 */
    private tmpVector2: mw.Vector = new mw.Vector();


    /**
     * 初始化工具
     * @param character 角色
     * @param points 路径点
     * @param speed 当前速度
     * @param overCall 结束回调
     */
    public init(character: mw.Character | mw.GameObject, points: mw.Vector[], speed: number, overCall?: () => void) {
        this.character = character;
        this.points = points;
        this.speed = speed;
        this.overCall = overCall;

        this.isMoving = true;
        this.isChara = character instanceof mw.Character;
        this.setPointIndex(0);
        this.tmpVector2.set(points[0]);
    }

    /**
     * 停止移动
     */
    public stop() {
        this.isMoving = false;
    }

    /**
     * 帧更新
     * @param dt 帧时间
     * @returns 
     */
    public update(dt) {
        if (!this.isMoving) {
            return;
        }

        const pos = this.character.worldTransform.position
        this.nowVector.set(pos);
        if (this.isMid(this.nowVector, this.orgVector, this.points[this.curIndex + 1])) {
            this.orgVector.set(this.nowVector);
            this.tmpVector.set(this.dir).multiply(dt);
            // if (this.isChara) {
            //     (this.character as mw.Character).addMovement(this.tmpVector);
            // } else {
            this.tmpVector2.set(this.nowVector).add(this.tmpVector);
            this.tmpVector2.z = pos.z;
            this.character.worldTransform.position = this.tmpVector2;
            // }
            return;
        }

        this.setPointIndex(this.curIndex + 1);
    }


    /**
     * 当前位置是否在起点和终点之间
     * @param nowPos 当前位置
     * @param orgPos 起点
     * @param overPos 终点
     * @returns 
     */
    private isMid(nowPos: mw.Vector, orgPos: mw.Vector, overPos: mw.Vector): boolean {
        const x = (orgPos.x - nowPos.x) * (nowPos.x - overPos.x);
        const y = (orgPos.y - nowPos.y) * (nowPos.y - overPos.y);
        return x >= 0 && y >= 0 && (nowPos.x != overPos.x || nowPos.y != overPos.y);
    }

    /**
     * 设置路点序号，计算方向，设置角色朝向
     * @param curIndex 当前序号
     * @returns 
     */
    private setPointIndex(curIndex: number) {
        this.curIndex = curIndex;
        this.orgVector.set(this.points[this.curIndex]);
        const z = this.character.worldTransform.position.z;
        this.tmpVector2.set(this.points[curIndex]);
        this.tmpVector2.z = z;
        this.character.worldTransform.position = this.tmpVector2;

        if (curIndex + 1 >= this.points.length) {
            this.isMoving = false;
            this.overCall && this.overCall();
            return;
        }

        this.dir.set(this.points[this.curIndex + 1]);
        this.dir.subtract(this.points[this.curIndex]);
        this.dir.z = 0;
        this.dir.normalize().multiply(this.speed);

        this.tmpVector.set(this.dir);
        this.tmpVector.z = 0;
        this.character.worldTransform.rotation = this.tmpVector.toRotation();
    }

}
