import Quaternion from "../../../core/geom/Quaternion.js";
import Vector3 from "../../../core/geom/Vector3.js";
import { Behavior } from "../../intelligence/behavior/Behavior.js";
import { BehaviorStatus } from "../../intelligence/behavior/BehaviorStatus.js";
import { CameraShake } from "./CameraShake.js";

export class CameraShakeBehavior extends Behavior {
    /**
     *
     * @param {number} maxPitch
     * @param {number} maxYaw
     * @param {number} maxRoll
     * @param {number} maxOffsetX
     * @param {number} maxOffsetY
     * @param {number} maxOffsetZ
     * @param {number} strength
     * @param {TopDownCameraController} controller
     */
    constructor(
        {
            maxPitch = 0,
            maxYaw = 0,
            maxRoll = 0,
            maxOffsetX = 0,
            maxOffsetY = 0,
            maxOffsetZ = 0,
            strength = 0,

            controller
        }
    ) {
        super();

        /**
         *
         * @type {TopDownCameraController}
         */
        this.controller = controller;

        this.time = 0;

        this.timeScale = 1;

        this.strength = strength;

        this.shake = new CameraShake();

        this.shake.limitsRotation.set(maxPitch, maxYaw, maxRoll);
        this.shake.limitsOffset.set(maxOffsetX, maxOffsetY, maxOffsetZ);

        this.__target = new Vector3();
        this.__rotation = new Vector3();
    }

    initialize() {
        super.initialize();

        //remember controller transform
        this.__rotation.set(this.controller.pitch, this.controller.yaw, this.controller.roll);
        this.__target.copy(this.controller.target);
    }

    tick(timeDelta) {
        this.time += timeDelta * this.timeScale;

        const offset = new Vector3();
        const rotation = new Vector3();

        //read out shake values
        this.shake.read(this.strength, this.time, offset, rotation);

        const q = new Quaternion();

        q.fromEulerAngles(this.__rotation.x, this.__rotation.y, this.__rotation.z);

        offset.applyQuaternion(q);

        //update controller
        this.controller.target.set(
            this.__target.x + offset.x,
            this.__target.y + offset.y,
            this.__target.z + offset.z,
        );

        this.controller.pitch = this.__rotation.x + rotation.x;
        this.controller.yaw = this.__rotation.y + rotation.y;
        this.controller.roll = this.__rotation.z + rotation.z;

        return BehaviorStatus.Running;
    }
}