import { makeAppObjectRepo } from "@vived/core";
import { Angle, Quaternion, Vector3 } from "@vived/core";
import { makeMockDispatchStateChange } from "../../Dispatcher/Mocks/MockDispatchStateChange";
import { makeStickableEntity } from "../../Stick/Entities/Stickable";
import { Transform3D } from "../../Transform3D/Entities/Transform3D";
import { makeUndoRedoEntity } from "../../UndoRedo/Entities/UndoRedoEntity";
import { makeChannelModelEntity } from "../Entities";
import { makeStickAllChannelModelObjectsUC } from "./StickAllChannelModelObjectsUC";
function makeTestRig() {
    const appObjects = makeAppObjectRepo();
    const mockDispatchStateChange = makeMockDispatchStateChange(appObjects);
    const doDispatchMock = jest.fn();
    mockDispatchStateChange.doDispatch = doDispatchMock;
    const ao = appObjects.getOrCreate("ChannelModel");
    const channelModel = makeChannelModelEntity(ao);
    const uc = makeStickAllChannelModelObjectsUC(ao);
    const modelObject1 = channelModel.addModelObject("modelId1");
    const modelObject2 = channelModel.addModelObject("modelId2");
    const sm1Transform = Transform3D.addIfMissing(modelObject1.appObject);
    const sm2Transform = Transform3D.addIfMissing(modelObject2.appObject);
    sm1Transform.localPosition = new Vector3(1, 2, 3);
    sm2Transform.localPosition = new Vector3(4, 5, 6);
    const stickableObject1 = makeStickableEntity(modelObject1.appObject);
    const stickableObject2 = makeStickableEntity(modelObject2.appObject);
    const mockSm1Stick = jest.fn();
    const mockSm2Stick = jest.fn();
    stickableObject1.doStick = mockSm1Stick;
    stickableObject2.doStick = mockSm2Stick;
    const undo = makeUndoRedoEntity(appObjects.getOrCreate("Undo"));
    return {
        uc,
        stickableObject1,
        stickableObject2,
        doDispatchMock,
        sm1Transform,
        sm2Transform,
        undo,
        mockSm1Stick,
        mockSm2Stick,
    };
}
describe("uc", () => {
    it("Sticks all channel model objects", () => {
        const { uc, mockSm1Stick, mockSm2Stick, doDispatchMock } = makeTestRig();
        uc.stickAll();
        expect(mockSm1Stick).toHaveBeenCalledWith(doDispatchMock);
        expect(mockSm2Stick).toHaveBeenCalledWith(doDispatchMock);
    });
    it("Submits an undo action", () => {
        const { uc, undo } = makeTestRig();
        uc.stickAll();
        expect(undo.hasUndo).toEqual(true);
    });
    it("Doesn't submit undo action when hidden dissectable meshes are not found", () => {
        const { uc, sm1Transform, sm2Transform, undo } = makeTestRig();
        sm1Transform.localPosition = Vector3.Zero();
        sm2Transform.localPosition = Vector3.Zero();
        uc.stickAll();
        expect(undo.hasUndo).toEqual(false);
    });
    it("Wires up the dispatch for undo redo", () => {
        const { uc, undo, doDispatchMock } = makeTestRig();
        uc.stickAll();
        doDispatchMock.mockClear();
        undo.doUndo();
        expect(doDispatchMock).toHaveBeenCalledTimes(1);
        undo.doRedo();
        expect(doDispatchMock).toHaveBeenCalledTimes(2);
    });
    it("Undo redo move", () => {
        const { uc, sm1Transform, undo, stickableObject1 } = makeTestRig();
        sm1Transform.localPosition = new Vector3(1, 2, 3);
        stickableObject1.stickPosition = new Vector3(4, 5, 6);
        uc.stickAll();
        sm1Transform.localPosition = new Vector3(4, 5, 6); // Fake the stick since we hijacked the lerp
        undo.doUndo();
        expect(sm1Transform.localPosition).toEqual(new Vector3(1, 2, 3));
        undo.doRedo();
        expect(sm1Transform.localPosition).toEqual(new Vector3(4, 5, 6));
    });
    it("Undo redo scale", () => {
        const { uc, sm1Transform, undo, stickableObject1 } = makeTestRig();
        sm1Transform.localScale = new Vector3(5, 5, 5);
        stickableObject1.stickScale = 3;
        uc.stickAll();
        sm1Transform.localScale = new Vector3(3, 3, 3); // Fake the stick since we hijacked the lerp
        undo.doUndo();
        expect(sm1Transform.localScale).toEqual(new Vector3(5, 5, 5));
        undo.doRedo();
        expect(sm1Transform.localScale).toEqual(new Vector3(3, 3, 3));
    });
    it("Undo redo rotation", () => {
        const { uc, sm1Transform, undo, stickableObject1 } = makeTestRig();
        sm1Transform.localRotation = Quaternion.Identity();
        const stickQuat = Quaternion.FromAngleAxis(new Vector3(3, 4, 5), Angle.FromDegrees(6));
        stickableObject1.stickRotation = stickQuat;
        uc.stickAll();
        sm1Transform.localRotation = stickQuat; // Fake the stick since we hijacked the lerp
        undo.doUndo();
        expect(sm1Transform.localRotation).toEqual(Quaternion.Identity());
        undo.doRedo();
        expect(Quaternion.Close(sm1Transform.localRotation, stickQuat)).toEqual(true);
    });
});
//# sourceMappingURL=StickAllChannelModelObjectsUC.test.js.map