import Vector3 from "../../../core/geom/Vector3.js";
import { create_simplex_noise_2d } from "../../../core/math/noise/create_simplex_noise_2d.js";
import { seededRandom } from "../../../core/math/random/seededRandom.js";

/**
 * Based on a 2016 GDC talk by Squirrel Eiserloh "Math for Game Programmers: Juicing Your Cameras With Math"
 */
export class CameraShake {
    constructor() {


        this.time = 0;

        /**
         * Shake rotational limits, yaw, pitch and roll
         * @type {Vector3}
         */
        this.limitsRotation = new Vector3();

        /**
         * Shake offset limits
         * @type {Vector3}
         */
        this.limitsOffset = new Vector3();


        const r = seededRandom(1);

        this.noiseRotataionX = create_simplex_noise_2d(r);
        this.noiseRotataionY = create_simplex_noise_2d(r);
        this.noiseRotataionZ = create_simplex_noise_2d(r);

        this.noiseOffsetX = create_simplex_noise_2d(r);
        this.noiseOffsetY = create_simplex_noise_2d(r);
        this.noiseOffsetZ = create_simplex_noise_2d(r);

    }

    /**
     *
     * @param {number} value between 0 and 1
     * @param {number} time
     * @param {Vector3} offset
     * @param {Vector3} rotation
     */
    read(value, time, offset, rotation) {

        const t = time;

        const nRX = this.noiseRotataionX;
        const nRY = this.noiseRotataionY;
        const nRZ = this.noiseRotataionZ;

        rotation.set(
            this.limitsRotation.x * value * nRX(t, 1),
            this.limitsRotation.y * value * nRY(t, 2),
            this.limitsRotation.z * value * nRZ(t, 3),
        );

        const nOX = this.noiseOffsetX;
        const nOY = this.noiseOffsetY;
        const nOZ = this.noiseOffsetZ;

        offset.set(
            this.limitsOffset.x * value * nOX(t, 1),
            this.limitsOffset.y * value * nOY(t, 2),
            this.limitsOffset.z * value * nOZ(t, 3)
        );
    }


}
