"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@vived/core");
const core_2 = require("@vived/core");
const Babylon_1 = require("../../Babylon");
const MockTouchInput_1 = require("../../TouchController/Mock/MockTouchInput");
const TapToSelectAppObject_1 = require("./TapToSelectAppObject");
const SelectAppObjectUCMock_1 = require("../Mocks/SelectAppObjectUCMock");
function makeTestRig() {
    const appObjects = (0, core_1.makeAppObjectRepo)();
    const mockPixelToSceneUC = (0, Babylon_1.makeMockPixelToSceneRayUC)(appObjects);
    const mockPixelToRay = jest.fn().mockReturnValue(core_2.ParametricLine.Forward());
    mockPixelToSceneUC.pixelToSceneRay = mockPixelToRay;
    const appObj = appObjects.getOrCreate("appObj");
    const mockUC = new SelectAppObjectUCMock_1.SelectAppObjectUCMock(appObj);
    const mockTouchInput = new MockTouchInput_1.MockTouchInputEntity(appObj);
    const controller = new TapToSelectAppObject_1.TapToSelectAppObject(appObj);
    const mockAllow = jest.fn();
    mockAllow.mockReturnValue(true);
    controller.allow = mockAllow;
    return {
        appObjects,
        controller,
        mockUC,
        mockTouchInput,
        mockPixelToRay,
        mockAllow,
    };
}
function mockTouchInputEvent(touchPositions) {
    const mockEvt = new TouchEvent("");
    const touchCount = touchPositions.length;
    let sumPos = core_2.Vector2.Zero();
    const touches = touchPositions.map((pos, i) => {
        sumPos = core_2.Vector2.Add(sumPos, pos);
        return {
            id: i,
            position: pos,
        };
    });
    const avgPos = touchCount === 0
        ? core_2.Vector2.Zero()
        : new core_2.Vector2(sumPos.x / touchCount, sumPos.y / touchCount);
    return {
        event: mockEvt,
        touchCenter: avgPos,
        touchCount,
        touches,
    };
}
describe("Tap to select Scene Object Touch Controller", () => {
    it("Sends a ray to the UC on select", () => {
        const { mockUC, controller } = makeTestRig();
        const event = mockTouchInputEvent([new core_2.Vector2(1, 2)]);
        controller.onTouchStart(event);
        controller.onTouchEnd();
        expect(mockUC.trySelectAppObject).toHaveBeenCalledWith(core_2.ParametricLine.Forward());
    });
    it("Does not send a ray to the UC on select if not allowed", () => {
        const { mockUC, controller, mockAllow } = makeTestRig();
        const event = mockTouchInputEvent([new core_2.Vector2(1, 2)]);
        mockAllow.mockReturnValue(false);
        controller.onTouchStart(event);
        controller.onTouchEnd();
        expect(mockUC.trySelectAppObject).not.toHaveBeenCalled();
    });
    it("Warns if it is added to an app object that does not have a UC", () => {
        const { appObjects } = makeTestRig();
        const anotherAppObj = appObjects.getOrCreate("newAppObj");
        console.warn = jest.fn();
        new TapToSelectAppObject_1.TapToSelectAppObject(anotherAppObj);
        expect(console.warn).toHaveBeenCalled();
    });
    it("Does not register itself if the object does not have a UC", () => {
        const { appObjects, mockTouchInput } = makeTestRig();
        const anotherAppObj = appObjects.getOrCreate("newAppObj");
        console.warn = jest.fn();
        mockTouchInput.registerController.mockClear();
        new TapToSelectAppObject_1.TapToSelectAppObject(anotherAppObj);
        expect(mockTouchInput.registerController).not.toHaveBeenCalled();
    });
    it("Does not send a ray to the UC when a tap occurs with two touches", () => {
        const { mockUC, controller } = makeTestRig();
        const event = mockTouchInputEvent([new core_2.Vector2(1, 2), new core_2.Vector2(2, 3)]);
        controller.onTouchStart(event);
        controller.onTouchEnd();
        expect(mockUC.trySelectAppObject).not.toHaveBeenCalled();
    });
    it("Sends a ray to the UC when a one touch moves within limit", () => {
        const { controller, mockUC } = makeTestRig();
        const event = mockTouchInputEvent([new core_2.Vector2(0, 0)]);
        const event2 = mockTouchInputEvent([
            new core_2.Vector2(0, TapToSelectAppObject_1.TapToSelectAppObject.maxTapDistancePx - 1),
        ]);
        controller.onTouchStart(event);
        controller.onTouchMove(event2);
        controller.onTouchEnd();
        expect(mockUC.trySelectAppObject).toHaveBeenCalledWith(core_2.ParametricLine.Forward());
    });
    it("Doesn't send a ray to the UC when a one touch moves beyond limit", () => {
        const { controller, mockUC } = makeTestRig();
        const event = mockTouchInputEvent([new core_2.Vector2(0, 0)]);
        const event2 = mockTouchInputEvent([
            new core_2.Vector2(0, TapToSelectAppObject_1.TapToSelectAppObject.maxTapDistancePx + 1),
        ]);
        controller.onTouchStart(event);
        controller.onTouchMove(event2);
        controller.onTouchEnd();
        expect(mockUC.trySelectAppObject).not.toHaveBeenCalled();
    });
    it("Does not send a ray to the UC when a one touch starts but a second is added", () => {
        const { controller, mockUC } = makeTestRig();
        const touch = mockTouchInputEvent([new core_2.Vector2(0, 0)]);
        const touch2 = mockTouchInputEvent([new core_2.Vector2(1, 1), new core_2.Vector2(2, 2)]);
        controller.onTouchStart(touch);
        controller.onTouchMove(touch2);
        controller.onTouchEnd();
        expect(mockUC.trySelectAppObject).not.toHaveBeenCalled();
    });
});
//# sourceMappingURL=TapToSelectAppObject.test.js.map