import { makeAppObjectRepo } from "@vived/core";
import { ParametricLine, Vector2, Vector3 } from "@vived/core";
import { makeMockPixelToSceneRayUC, makeMockScenePixelPickUC, } from "../../Babylon";
import { makeMockDispatchStateChange } from "../../Dispatcher/Mocks/MockDispatchStateChange";
import { makeTransform3D } from "../Entities";
import { makePinchTransformUC } from "./PinchTransform";
function makeTestRig() {
    const appObjects = makeAppObjectRepo();
    const ao = appObjects.getOrCreate("AO");
    const transform = makeTransform3D(ao);
    const pinchUC = makePinchTransformUC(ao);
    const mockPick = makeMockScenePixelPickUC(appObjects);
    const mockDispatch = makeMockDispatchStateChange(appObjects);
    const doDispatchMock = jest.fn();
    mockDispatch.doDispatch = doDispatchMock;
    const mockRay = makeMockPixelToSceneRayUC(appObjects);
    mockRay.pixelToSceneRay = mockPicker;
    return {
        appObjects,
        pinchUC,
        transform,
        mockPick,
        doDispatchMock,
        mockRay,
    };
}
function mockPicker(pixel) {
    return ParametricLine.FromPointDirection(new Vector3(pixel.x, pixel.y, 3), Vector3.Forward());
}
describe("Pinch Scene Root Use Case", () => {
    it("Move with no scaling adjusts the root as expected", () => {
        const { pinchUC, transform } = makeTestRig();
        transform.worldPosition = new Vector3(1, 2, 3);
        const touch1 = new Vector2(5, 8);
        const touch2 = new Vector2(5, 0);
        pinchUC.initializePinch(touch1, touch2);
        const touch3 = new Vector2(0, 8);
        const touch4 = new Vector2(0, 0);
        pinchUC.doPinch(touch3, touch4);
        const expected = new Vector3(-4, 2, 3); // -5 in the x
        const wPos = transform.worldPosition;
        expect(Vector3.Close(wPos, expected)).toEqual(true);
    });
    it("Plane pick is relative", () => {
        const { pinchUC, transform, mockPick } = makeTestRig();
        mockPick.scenePixelPick.mockReturnValue(new Vector3(10, 20, 60));
        transform.worldPosition = new Vector3(1, 2, 3);
        const touch1 = new Vector2(5, 8);
        const touch2 = new Vector2(5, 0);
        pinchUC.initializePinch(touch1, touch2);
        const touch3 = new Vector2(0, 8);
        const touch4 = new Vector2(0, 0);
        pinchUC.doPinch(touch3, touch4);
        const expected = new Vector3(-4, 2, 3); // -5 in the x
        const wPos = transform.worldPosition;
        expect(Vector3.Close(wPos, expected)).toEqual(true);
    });
    it("Scales smaller with a pinch that moves closer", () => {
        const { pinchUC, transform } = makeTestRig();
        transform.worldPosition = new Vector3(0, 0, 0);
        transform.worldScale = Vector3.One();
        const touch1 = new Vector2(0, 8);
        const touch2 = new Vector2(0, -8);
        pinchUC.initializePinch(touch1, touch2);
        const touch3 = new Vector2(0, 4);
        const touch4 = new Vector2(0, -4);
        pinchUC.doPinch(touch3, touch4);
        const expectedScaleDelta = pinchUC.sensitivity * 8;
        expect(transform.worldScale.x).toEqual(1 - expectedScaleDelta);
    });
    it("Scales larger with a pinch that moves further", () => {
        const { pinchUC, transform } = makeTestRig();
        transform.worldPosition = new Vector3(0, 0, 0);
        transform.worldScale = Vector3.One();
        const touch1 = new Vector2(0, 8);
        const touch2 = new Vector2(0, -8);
        pinchUC.initializePinch(touch1, touch2);
        const touch3 = new Vector2(0, 12);
        const touch4 = new Vector2(0, -12);
        pinchUC.doPinch(touch3, touch4);
        const expectedScaleDelta = pinchUC.sensitivity * 8;
        expect(transform.worldScale.x).toEqual(1 + expectedScaleDelta);
    });
    it("Dispatches a state change if the position has changed since init", () => {
        const { transform, pinchUC, doDispatchMock } = makeTestRig();
        transform.worldScale = new Vector3(5, 5, 5);
        const touch1 = new Vector2(0, 8);
        const touch2 = new Vector2(0, -8);
        pinchUC.initializePinch(touch1, touch2);
        transform.worldScale = new Vector3(6, 6, 6);
        pinchUC.finishPinch();
        expect(doDispatchMock).toHaveBeenCalled();
    });
    it("Does not dispatch a state change if the scale has not changed", () => {
        const { transform, pinchUC, doDispatchMock } = makeTestRig();
        transform.worldScale = new Vector3(5, 5, 5);
        const touch1 = new Vector2(0, 8);
        const touch2 = new Vector2(0, -8);
        pinchUC.initializePinch(touch1, touch2);
        pinchUC.finishPinch();
        expect(doDispatchMock).not.toHaveBeenCalled();
    });
    it("Does not update if not enabled", () => {
        const { pinchUC, transform } = makeTestRig();
        pinchUC.enabled = false;
        transform.worldPosition = Vector3.Zero();
        const touch1 = new Vector2(5, 8);
        const touch2 = new Vector2(5, 0);
        pinchUC.initializePinch(touch1, touch2);
        const touch3 = new Vector2(0, 8);
        const touch4 = new Vector2(0, 0);
        pinchUC.doPinch(touch3, touch4);
        expect(transform.worldPosition).toEqual(Vector3.Zero());
    });
});
//# sourceMappingURL=PinchTransform.test.js.map