

export class BaseJoystick {

    moveHd: any = 0;
    startX = 0;
    startY = 0;
    moveX = 0;
    moveY = 0;
    lastMoveX = 0;
    lastMoveY = 0;

    backWidth = 0;
    backHeight = 0;
    handlerWidth = 0;
    handlerHeight = 0;
    handlerLeft = 0;
    handlerTop = 0;

    handlerCurrPos = { left: 0, top: 0 };

    /**改变方向时触发,如果持续的改变方向,则会有最低触发频率30ms的限制*/
    public onmove?: (dir: IMoveDirection) => void;
    /**停止改变方向时触发,体现在放开移动控制器上*/
    public onmoveend?: () => void;

    
    /**
     * 初始化UI计算的尺寸, 如果不用计算的尺寸,可以不用初始化
     * @date 2022/2/23 - 下午1:56:34
     *
     * @public
     * @param {number} backSize
     * @param {number} handlerSize
     */
    public initUISize(backSize: number, handlerSize: number) {
        this.backWidth = backSize;
        this.backHeight = backSize;
        this.handlerWidth = handlerSize;
        this.handlerHeight = handlerSize;
        this.handlerLeft = (this.backWidth - this.handlerWidth) / 2;
        this.handlerTop = (this.backHeight - this.handlerHeight) / 2;
    }

    public touchStart(x: number, y: number) {
        this.startX = x;
        this.startY = y;
        this.moveX = this.moveY = this.lastMoveX = this.lastMoveY = 0;
        this.moveHd = setInterval(this.onCheckMove.bind(this), 30);
        return false;
    }
    public touchMove(x: number, y: number): { left: number, top: number } | null {
        const moveX = x - this.startX;
        const moveY = y - this.startY;
        const move = this.normalize(moveX, moveY);
        this.moveX = move.x;
        this.moveY = move.y;
        this.handlerCurrPos.left = this.handlerLeft + this.moveX * this.handlerLeft;
        this.handlerCurrPos.top = this.handlerTop + this.moveY * this.handlerTop;
        return this.handlerCurrPos;
    }
    public touchEnd(): { left: number, top: number } | null {
        this.moveX = this.moveY = 0;
        this.handlerCurrPos.left = this.handlerLeft + this.moveX * this.handlerLeft;
        this.handlerCurrPos.top = this.handlerTop + this.moveY * this.handlerTop;
        clearInterval(this.moveHd);
        this.onmoveend?.call(this);
        return this.handlerCurrPos;
    }
    onCheckMove() {
        if ((this.moveX != 0 && this.moveY != 0)
            && (this.lastMoveX != this.moveX || this.lastMoveY != this.moveY)) {
            this.lastMoveX = this.moveX;
            this.lastMoveY = this.moveY;
            const dirX: -1 | 0 | 1 = this.moveX == 0 ? 0 : (this.moveX > 0 ? 1 : -1);
            const dirZ: -1 | 0 | 1 = this.moveY == 0 ? 0 : (this.moveY > 0 ? 1 : -1);
            let acuteRad = 0;
            if (dirX != 0 && dirZ != 0) {
                acuteRad = Math.atan(Math.abs(this.moveY / this.moveX));
            }
            this.onmove?.call(this, { dirX, dirZ, acuteRad });
        }
    }
    normalize(x: number, y: number) {
        const len = Math.sqrt(x * x + y * y);
        const inv = len == 0 ? 0 : 1 / len;
        return {
            x: x * inv,
            y: y * inv
        };
    }
}


/**
 * 表示移动方向
 * @date 2022/2/21 - 下午1:43:43
 *
 * @export
 * @interface IMoveDirection
 * @typedef {IMoveDirection}
 */
export interface IMoveDirection {
    /**移动方向的X轴,用-1,0,1表示, X和Z都为0时表示没有移动*/
    dirX: -1 | 0 | 1;
    /**移动方向的Z轴(朝下的数学Y轴,或者网页的Y轴),用-1,0,1表示, X和Z都为0时表示没有移动*/
    dirZ: -1 | 0 | 1;
    /**方向于X轴构成锐角的弧度,计算公式为: Math.Atan(Math.Abs(Y/X)),X为0时,传0*/
    acuteRad: number;
}