import { makeAppObject, makeAppObjectRepo } from "@vived/core";
import { Angle, ParametricLine, Quaternion, Vector3 } from "@vived/core";
import { makeMockDispatchStateChange } from "../../Dispatcher/Mocks/MockDispatchStateChange";
import { makeUndoRedoEntity } from "../../UndoRedo";
import { makeTransform3D } from "../Entities";
import { makeMoveTransform, MoveTransformUC } from "./MoveTransformUC";
function makeTestRig() {
    const appObjects = makeAppObjectRepo();
    const appObj = makeAppObject("appObj", appObjects);
    const transform = makeTransform3D(appObj);
    const moveUC = makeMoveTransform(appObj);
    const helper = makeTransform3D(appObjects.getOrCreate("Helper"));
    const mockDispatch = makeMockDispatchStateChange(appObjects);
    const doDispatchMock = jest.fn();
    mockDispatch.doDispatch = doDispatchMock;
    const undo = makeUndoRedoEntity(appObjects.getOrCreate("Undo"));
    return {
        moveUC,
        appObj,
        appObjects,
        doDispatchMock,
        undo,
        helper,
        transform,
    };
}
describe("Move Transform UC", () => {
    it("Gets the UC by ID", () => {
        const { moveUC, appObjects } = makeTestRig();
        expect(MoveTransformUC.get("appObj", appObjects)).toEqual(moveUC);
    });
    it("Sets the helper to the world position and rotation of the local transform", () => {
        const { moveUC, transform, helper } = makeTestRig();
        transform.worldPosition = new Vector3(1, 2, 3);
        transform.worldRotation = Quaternion.FromAngleAxis(new Vector3(4, 5, 6), Angle.FromDegrees(7));
        helper.worldPosition = Vector3.Zero();
        helper.worldRotation = Quaternion.Identity();
        moveUC.initialize(helper);
        expect(helper.worldPosition).toEqual(transform.worldPosition);
        expect(helper.worldRotation).toEqual(transform.worldRotation);
    });
    it("Moves the transform to where the helper is", () => {
        const { moveUC, transform, helper } = makeTestRig();
        transform.worldPosition = new Vector3(1, 2, 3);
        transform.worldRotation = Quaternion.FromAngleAxis(new Vector3(4, 5, 6), Angle.FromDegrees(7));
        moveUC.initialize(helper);
        helper.worldPosition = Vector3.Zero();
        helper.worldRotation = Quaternion.Identity();
        moveUC.update(helper, ParametricLine.Forward());
        expect(transform.worldPosition).toEqual(helper.worldPosition);
        expect(transform.worldRotation).toEqual(helper.worldRotation);
    });
    it("Does not move the transform if it was not initialized", () => {
        const { moveUC, transform, helper } = makeTestRig();
        transform.worldPosition = new Vector3(1, 2, 3);
        transform.worldRotation = Quaternion.FromAngleAxis(new Vector3(4, 5, 6), Angle.FromDegrees(7));
        helper.worldPosition = Vector3.Zero();
        helper.worldRotation = Quaternion.Identity();
        moveUC.update(helper, ParametricLine.Forward());
        expect(transform.worldPosition).not.toEqual(helper.worldPosition);
        expect(transform.worldRotation).not.toEqual(helper.worldRotation);
    });
    it("Dispatches a state change on stop if moved", () => {
        const { moveUC, transform, helper, doDispatchMock } = makeTestRig();
        transform.worldPosition = new Vector3(1, 2, 3);
        transform.worldRotation = Quaternion.FromAngleAxis(new Vector3(4, 5, 6), Angle.FromDegrees(7));
        moveUC.initialize(helper);
        helper.worldPosition = Vector3.Zero();
        helper.worldRotation = Quaternion.Identity();
        moveUC.update(helper, ParametricLine.Forward());
        moveUC.finish();
        expect(doDispatchMock).toHaveBeenCalled();
    });
    it("Does not dispatch a state change on stop if not moved", () => {
        const { moveUC, transform, helper, doDispatchMock } = makeTestRig();
        transform.worldPosition = new Vector3(1, 2, 3);
        transform.worldRotation = Quaternion.FromAngleAxis(new Vector3(4, 5, 6), Angle.FromDegrees(7));
        moveUC.initialize(helper);
        moveUC.finish();
        expect(doDispatchMock).not.toHaveBeenCalled();
    });
    it("Does not dispatch a state change on stop if moved and told not to", () => {
        const { moveUC, transform, helper, doDispatchMock } = makeTestRig();
        moveUC.dispatchStateChangeOnComplete = false;
        transform.worldPosition = new Vector3(1, 2, 3);
        transform.worldRotation = Quaternion.FromAngleAxis(new Vector3(4, 5, 6), Angle.FromDegrees(7));
        moveUC.initialize(helper);
        helper.worldPosition = Vector3.Zero();
        helper.worldRotation = Quaternion.Identity();
        moveUC.update(helper, ParametricLine.Forward());
        moveUC.finish();
        expect(doDispatchMock).not.toHaveBeenCalled();
    });
    it("Submits an undo on stop", () => {
        const { moveUC, transform, helper, undo } = makeTestRig();
        transform.worldPosition = new Vector3(1, 2, 3);
        transform.worldRotation = Quaternion.FromAngleAxis(new Vector3(4, 5, 6), Angle.FromDegrees(7));
        moveUC.initialize(helper);
        helper.worldPosition = Vector3.Zero();
        helper.worldRotation = Quaternion.Identity();
        moveUC.update(helper, ParametricLine.Forward());
        moveUC.finish();
        expect(undo.hasUndo).toEqual(true);
    });
    it("Does not submit an undo on stop if flag is set to false", () => {
        const { moveUC, transform, helper, undo } = makeTestRig();
        moveUC.submitUndoOnComplete = false;
        transform.worldPosition = new Vector3(1, 2, 3);
        transform.worldRotation = Quaternion.FromAngleAxis(new Vector3(4, 5, 6), Angle.FromDegrees(7));
        moveUC.initialize(helper);
        helper.worldPosition = Vector3.Zero();
        helper.worldRotation = Quaternion.Identity();
        moveUC.update(helper, ParametricLine.Forward());
        moveUC.finish();
        expect(undo.hasUndo).toEqual(false);
    });
    it("Does not submit an undo on stop if there was no movement", () => {
        const { moveUC, transform, helper, undo } = makeTestRig();
        transform.worldPosition = new Vector3(1, 2, 3);
        transform.worldRotation = Quaternion.FromAngleAxis(new Vector3(4, 5, 6), Angle.FromDegrees(7));
        moveUC.initialize(helper);
        moveUC.finish();
        expect(undo.hasUndo).toEqual(false);
    });
    it("Wires up the dispatch for undo and redo", () => {
        const { transform, undo, doDispatchMock, helper, moveUC } = makeTestRig();
        transform.worldPosition = new Vector3(1, 2, 3);
        transform.worldRotation = Quaternion.FromAngleAxis(new Vector3(4, 5, 6), Angle.FromDegrees(7));
        moveUC.initialize(helper);
        helper.worldPosition = Vector3.Zero();
        helper.worldRotation = Quaternion.Identity();
        moveUC.update(helper, ParametricLine.Forward());
        moveUC.finish();
        doDispatchMock.mockClear();
        undo.doUndo();
        expect(doDispatchMock).toHaveBeenCalledTimes(1);
        undo.doRedo();
        expect(doDispatchMock).toHaveBeenCalledTimes(2);
    });
    it("Undoes and redoes the move", () => {
        const { transform, undo, helper, moveUC } = makeTestRig();
        const initialPos = new Vector3(1, 2, 3);
        const initialRot = Quaternion.FromAngleAxis(new Vector3(4, 5, 6), Angle.FromDegrees(7));
        transform.localPosition = initialPos;
        transform.localRotation = initialRot;
        moveUC.initialize(helper);
        const movedPos = Vector3.Zero();
        const movedRot = Quaternion.Identity();
        helper.localPosition = movedPos;
        helper.localRotation = movedRot;
        moveUC.update(helper, ParametricLine.Forward());
        moveUC.finish();
        expect(transform.localPosition).toEqual(movedPos);
        expect(Quaternion.Close(transform.localRotation, movedRot)).toEqual(true);
        undo.doUndo();
        expect(transform.localPosition).toEqual(initialPos);
        expect(Quaternion.Close(transform.localRotation, initialRot)).toEqual(true);
        undo.doRedo();
        expect(transform.localPosition).toEqual(movedPos);
        expect(Quaternion.Close(transform.localRotation, movedRot)).toEqual(true);
    });
});
//# sourceMappingURL=MoveTransformUC.test.js.map