import { makeAppObjectRepo } from "@vived/core";
import { Angle, Quaternion, Vector3 } from "@vived/core";
import { makeCameraEntity } from "../Entities/CameraEntity";
import { CameraPM, makeCameraPM } from "./CameraPM";
function makeTestRig() {
    const appObjects = makeAppObjectRepo();
    const appObject = appObjects.getOrCreate("AO");
    const camera = makeCameraEntity(appObject);
    camera.farClip = 10;
    camera.nearClip = 0.01;
    camera.fov = Angle.FromRadians(0.26);
    camera.transform.localPosition = Vector3.Zero();
    const pm = makeCameraPM(appObject);
    const observer = jest.fn();
    pm.addView(observer);
    return {
        camera,
        pm,
        observer,
        appObject,
        appObjects,
    };
}
describe("CameraPM Test", () => {
    it("Sets the last vm on construction", () => {
        const { pm } = makeTestRig();
        expect(pm.lastVM).not.toBeUndefined();
        expect(pm.lastVM?.nearClip).toEqual(0.01);
        expect(pm.lastVM?.farClip).toEqual(10);
        expect(pm.lastVM?.fov).toEqual(Angle.FromRadians(0.26));
        expect(pm.lastVM?.position).toEqual(Vector3.Zero());
        expect(pm.lastVM?.target).toEqual(Vector3.Forward());
    });
    it("Calculates the direction from the rotation of the transform", () => {
        const { pm, camera } = makeTestRig();
        camera.transform.localRotation = Quaternion.FromYawPitchRoll(Angle.FromDegrees(180), Angle.FromDegrees(0), Angle.FromDegrees(0));
        expect(Vector3.Close(pm.lastVM.target, Vector3.Backward())).toEqual(true);
    });
    it("Updates the view when camera changes", () => {
        const { observer, camera } = makeTestRig();
        camera.fov = Angle.FromRadians(0.5);
        observer.mockClear();
        camera.fov = Angle.FromRadians(1.5);
        expect(observer).toHaveBeenCalled();
    });
    it("Does not update when disposed", () => {
        const { observer, camera } = makeTestRig();
        camera.fov = Angle.FromRadians(0.5);
        observer.mockClear();
        camera.dispose();
        camera.fov = Angle.FromRadians(1.5);
        expect(observer).not.toHaveBeenCalled();
    });
    it("Disposed when entity disposed", () => {
        const { camera, appObject } = makeTestRig();
        expect(appObject.hasComponent(CameraPM.type)).toEqual(true);
        camera.dispose();
        expect(appObject.hasComponent(CameraPM.type)).toEqual(false);
    });
    it("Returns true if the VMs are the same", () => {
        const { pm } = makeTestRig();
        const vm1 = {
            nearClip: 0.01,
            farClip: 10,
            target: Vector3.Forward(),
            position: Vector3.Zero(),
            fov: Angle.FromRadians(0.26),
        };
        const vm2 = { ...vm1 };
        expect(pm.vmsAreEqual(vm1, vm2)).toEqual(true);
    });
    it("Returns false if nearClips are different", () => {
        const { pm } = makeTestRig();
        const vm1 = {
            nearClip: 0.01,
            farClip: 10,
            target: Vector3.Forward(),
            position: Vector3.Zero(),
            fov: Angle.FromRadians(0.26),
        };
        const vm2 = { ...vm1, nearClip: 0 };
        expect(pm.vmsAreEqual(vm1, vm2)).toEqual(false);
    });
    it("Returns false if farClips are different", () => {
        const { pm } = makeTestRig();
        const vm1 = {
            nearClip: 0.01,
            farClip: 10,
            target: Vector3.Forward(),
            position: Vector3.Zero(),
            fov: Angle.FromRadians(0.26),
        };
        const vm2 = { ...vm1, farClip: 0 };
        expect(pm.vmsAreEqual(vm1, vm2)).toEqual(false);
    });
    it("Returns false if targets are different", () => {
        const { pm } = makeTestRig();
        const vm1 = {
            nearClip: 0.01,
            farClip: 10,
            target: Vector3.Forward(),
            position: Vector3.Zero(),
            fov: Angle.FromRadians(0.26),
        };
        const vm2 = { ...vm1, target: new Vector3(1, 2, 3) };
        expect(pm.vmsAreEqual(vm1, vm2)).toEqual(false);
    });
    it("Returns false if positions are different", () => {
        const { pm } = makeTestRig();
        const vm1 = {
            nearClip: 0.01,
            farClip: 10,
            target: Vector3.Forward(),
            position: Vector3.Zero(),
            fov: Angle.FromRadians(0.26),
        };
        const vm2 = { ...vm1, position: new Vector3(1, 2, 3) };
        expect(pm.vmsAreEqual(vm1, vm2)).toEqual(false);
    });
    it("Returns false if angles are different", () => {
        const { pm } = makeTestRig();
        const vm1 = {
            nearClip: 0.01,
            farClip: 10,
            target: Vector3.Forward(),
            position: Vector3.Zero(),
            fov: Angle.FromRadians(0.26),
        };
        const vm2 = { ...vm1, fov: Angle.FromRadians(0) };
        expect(pm.vmsAreEqual(vm1, vm2)).toEqual(false);
        expect(pm.vmsAreEqual(vm1, vm2)).toEqual(false);
    });
    it("Gets the PM", () => {
        const { pm, appObjects } = makeTestRig();
        expect(CameraPM.get(appObjects)).toEqual(pm);
    });
});
//# sourceMappingURL=CameraPM.test.js.map