import { makeAppObjectRepo } from "@vived/core";
import { Angle, Quaternion, Vector3 } from "@vived/core";
import { makeMockDispatchStateChange } from "../../Dispatcher/Mocks/MockDispatchStateChange";
import { makeTransform3D } from "../../Transform3D/Entities/Transform3D";
import { makeUndoRedoEntity } from "../../UndoRedo/Entities/UndoRedoEntity";
import { makeStickableEntity } from "../Entities/Stickable";
import { makeStickUC, StickUC } from "./StickUC";
function makeTestRig() {
    const appObjects = makeAppObjectRepo();
    const ao = appObjects.getOrCreate("AO");
    const transform = makeTransform3D(ao);
    const stickEntity = makeStickableEntity(ao);
    const uc = makeStickUC(ao);
    const stickSpy = jest.spyOn(stickEntity, "doStick");
    const mockDispatch = makeMockDispatchStateChange(appObjects);
    const doDispatchMock = jest.fn();
    mockDispatch.doDispatch = doDispatchMock;
    const undo = makeUndoRedoEntity(appObjects.getOrCreate("Undo"));
    return {
        stickEntity,
        uc,
        appObjects,
        transform,
        doDispatchMock,
        stickSpy,
        undo,
    };
}
describe("Stick UC", () => {
    it("Gets the UC", () => {
        const { appObjects, uc } = makeTestRig();
        expect(StickUC.get("AO", appObjects)).toEqual(uc);
    });
    it("Triggers do stick if the transform is out of place", () => {
        const { stickSpy, uc, transform, doDispatchMock } = makeTestRig();
        transform.localPosition = new Vector3(1, 2, 3);
        uc.doStick();
        expect(stickSpy).toHaveBeenCalledWith(doDispatchMock);
    });
    it("Does not trigger the lerp if it is not stickable", () => {
        const { stickSpy, uc, stickEntity } = makeTestRig();
        expect(stickEntity.canBeStuck).toEqual(false);
        uc.doStick();
        expect(stickSpy).not.toHaveBeenCalled();
    });
    it("Does not submit an undo if it is not stickable", () => {
        const { uc, stickEntity, undo } = makeTestRig();
        expect(stickEntity.canBeStuck).toEqual(false);
        uc.doStick();
        expect(undo.hasUndo).toEqual(false);
    });
    it("Submit an undo", () => {
        const { uc, transform, undo } = makeTestRig();
        transform.localPosition = new Vector3(1, 2, 3);
        uc.doStick();
        expect(undo.hasUndo).toEqual(true);
    });
    it("Dispatches on undo and redo", () => {
        const { uc, transform, undo, doDispatchMock } = makeTestRig();
        transform.localPosition = new Vector3(1, 2, 3);
        uc.doStick();
        doDispatchMock.mockClear();
        undo.doUndo();
        expect(doDispatchMock).toHaveBeenCalledTimes(1);
        undo.doRedo();
        expect(doDispatchMock).toHaveBeenCalledTimes(2);
    });
    it("Undo redo move", () => {
        const { uc, transform, undo, stickEntity } = makeTestRig();
        transform.localPosition = new Vector3(1, 2, 3);
        stickEntity.stickPosition = new Vector3(4, 5, 6);
        uc.doStick();
        transform.localPosition = new Vector3(4, 5, 6); // Fake the stick since we hijacked the lerp
        undo.doUndo();
        expect(transform.localPosition).toEqual(new Vector3(1, 2, 3));
        undo.doRedo();
        expect(transform.localPosition).toEqual(new Vector3(4, 5, 6));
    });
    it("Undo redo scale", () => {
        const { uc, transform, undo, stickEntity } = makeTestRig();
        transform.localScale = new Vector3(5, 5, 5);
        stickEntity.stickScale = 3;
        uc.doStick();
        transform.localScale = new Vector3(3, 3, 3); // Fake the stick since we hijacked the lerp
        undo.doUndo();
        expect(transform.localScale).toEqual(new Vector3(5, 5, 5));
        undo.doRedo();
        expect(transform.localScale).toEqual(new Vector3(3, 3, 3));
    });
    it("Undo redo rotation", () => {
        const { uc, transform, undo, stickEntity } = makeTestRig();
        transform.localRotation = Quaternion.Identity();
        const stickQuat = Quaternion.FromAngleAxis(new Vector3(3, 4, 5), Angle.FromDegrees(6));
        stickEntity.stickRotation = stickQuat;
        uc.doStick();
        transform.localRotation = stickQuat; // Fake the stick since we hijacked the lerp
        undo.doUndo();
        expect(transform.localRotation).toEqual(Quaternion.Identity());
        undo.doRedo();
        expect(Quaternion.Close(transform.localRotation, stickQuat)).toEqual(true);
    });
});
//# sourceMappingURL=StickUC.test.js.map