"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 MouseInput_1 = require("../../MouseInput");
const TouchController_1 = require("../../TouchController");
const StylusEntity_1 = require("../Entity/StylusEntity");
const EmulateStylusUC_1 = require("./EmulateStylusUC");
function makeTestRig() {
    const appObjects = (0, core_1.makeAppObjectRepo)();
    const registerSingletonSpy = jest.spyOn(appObjects, "registerSingleton");
    const mouseInput = (0, MouseInput_1.makeMouseInput)(appObjects.getOrCreate("Mouse"));
    const inputElement = document.createElement("div");
    mouseInput.setEventElement(inputElement);
    const touchInout = (0, TouchController_1.makeTouchInput)(appObjects.getOrCreate("Touch"));
    touchInout.setEventElement(inputElement);
    const ao = appObjects.getOrCreate("Stylus");
    const stylus = (0, StylusEntity_1.makeStylusEntity)(ao);
    const uc = (0, EmulateStylusUC_1.makeEmulateStylusUC)(ao);
    const mockSceneRay = (0, Babylon_1.makeMockPixelToSceneRayUC)(appObjects);
    mockSceneRay.pixelToSceneRay.mockReturnValue(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(1, 1, -1), core_2.Vector3.Forward()));
    return {
        uc,
        appObjects,
        registerSingletonSpy,
        mouseInput,
        inputElement,
        stylus,
        touchInout,
    };
}
describe("Emulate Stylus UC", () => {
    it("Registers as a singleton", () => {
        const { uc, registerSingletonSpy } = makeTestRig();
        expect(registerSingletonSpy).toHaveBeenCalledWith(uc);
    });
    it("Gets the singleton", () => {
        const { uc, appObjects } = makeTestRig();
        expect(EmulateStylusUC_1.EmulateStylusUC.get(appObjects)).toEqual(uc);
    });
    it("Can be started and stopped", () => {
        const { uc } = makeTestRig();
        expect(uc.isEmulating).toEqual(false);
        uc.startEmulating();
        expect(uc.isEmulating).toEqual(true);
        uc.stopEmulating();
        expect(uc.isEmulating).toEqual(false);
    });
    it("Steals the input element from the mouse input", () => {
        const { uc, mouseInput } = makeTestRig();
        const clearInputElementSpy = jest.spyOn(mouseInput, "clearInputElement");
        uc.startEmulating();
        expect(clearInputElementSpy).toHaveBeenCalled();
    });
    it("Only steals once", () => {
        const { uc, mouseInput } = makeTestRig();
        const clearInputElementSpy = jest.spyOn(mouseInput, "clearInputElement");
        uc.startEmulating();
        uc.startEmulating();
        uc.startEmulating();
        expect(clearInputElementSpy).toHaveBeenCalledTimes(1);
    });
    it("Clears the input element from the touch input", () => {
        const { uc, touchInout } = makeTestRig();
        const clearInputElementSpy = jest.spyOn(touchInout, "clearInputElement");
        uc.startEmulating();
        expect(clearInputElementSpy).toHaveBeenCalled();
    });
    it("Only clears once", () => {
        const { uc, touchInout } = makeTestRig();
        const clearInputElementSpy = jest.spyOn(touchInout, "clearInputElement");
        uc.startEmulating();
        uc.startEmulating();
        uc.startEmulating();
        expect(clearInputElementSpy).toHaveBeenCalledTimes(1);
    });
    it("Returns the mouse input element when stopped", () => {
        const { uc, mouseInput, inputElement } = makeTestRig();
        const setElementSpy = jest.spyOn(mouseInput, "setEventElement");
        uc.startEmulating();
        uc.stopEmulating();
        expect(setElementSpy).toHaveBeenCalledWith(inputElement);
    });
    it("Only returns to the mouse once", () => {
        const { uc, mouseInput } = makeTestRig();
        const setElementSpy = jest.spyOn(mouseInput, "setEventElement");
        uc.startEmulating();
        uc.stopEmulating();
        uc.stopEmulating();
        uc.stopEmulating();
        uc.stopEmulating();
        expect(setElementSpy).toHaveBeenCalledTimes(1);
    });
    it("Returns the touch input element when stopped", () => {
        const { uc, touchInout, inputElement } = makeTestRig();
        const setElementSpy = jest.spyOn(touchInout, "setEventElement");
        uc.startEmulating();
        uc.stopEmulating();
        expect(setElementSpy).toHaveBeenCalledWith(inputElement);
    });
    it("Only returns to the touch once", () => {
        const { uc, touchInout } = makeTestRig();
        const setElementSpy = jest.spyOn(touchInout, "setEventElement");
        uc.startEmulating();
        uc.stopEmulating();
        uc.stopEmulating();
        uc.stopEmulating();
        uc.stopEmulating();
        expect(setElementSpy).toHaveBeenCalledTimes(1);
    });
    it("Sends mouse down to the stylus", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        stylus.updateButtonState = jest.fn();
        uc.startEmulating();
        const e = new MouseEvent("mousedown", { button: 1 });
        inputElement.dispatchEvent(e);
        expect(stylus.updateButtonState).toHaveBeenCalledWith(1, true);
    });
    it("Stops sending mouse down after stopped", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        stylus.updateButtonState = jest.fn();
        uc.startEmulating();
        uc.stopEmulating();
        const e = new MouseEvent("mousedown", { button: 1 });
        inputElement.dispatchEvent(e);
        expect(stylus.updateButtonState).not.toHaveBeenCalled();
    });
    it("Sends mouse up to the stylus", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        stylus.updateButtonState = jest.fn();
        uc.startEmulating();
        const e = new MouseEvent("mouseup", { button: 1 });
        inputElement.dispatchEvent(e);
        expect(stylus.updateButtonState).toHaveBeenCalledWith(1, false);
    });
    it("Stops sending mouse up after stopped", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        stylus.updateButtonState = jest.fn();
        uc.startEmulating();
        uc.stopEmulating();
        const e = new MouseEvent("mouseup", { button: 1 });
        inputElement.dispatchEvent(e);
        expect(stylus.updateButtonState).not.toHaveBeenCalled();
    });
    it("Rotates the stylus on mouse move", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        stylus.transform.worldRotation = core_2.Quaternion.Identity();
        uc.startEmulating();
        const e = new MouseEvent("mousemove", { clientX: 10, clientY: 10 });
        inputElement.dispatchEvent(e);
        expect(stylus.transform.worldRotation).not.toEqual(core_2.Quaternion.Identity());
    });
    it("Stops rotating the stylus on mouse move", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        stylus.transform.worldRotation = core_2.Quaternion.Identity();
        uc.startEmulating();
        uc.stopEmulating();
        const e = new MouseEvent("mousemove", { clientX: 10, clientY: 10 });
        inputElement.dispatchEvent(e);
        inputElement.dispatchEvent(e);
        inputElement.dispatchEvent(e);
        expect(stylus.transform.worldRotation).toEqual(core_2.Quaternion.Identity());
    });
    it("Bumps to the left when A is pressed", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        uc.startEmulating();
        stylus.transform.worldPosition = core_2.Vector3.Zero();
        stylus.transform.worldRotation = core_2.Quaternion.Identity();
        const downEvent = new KeyboardEvent("keydown", { code: "KeyA" });
        inputElement.dispatchEvent(downEvent);
        expect(stylus.transform.worldPosition.x).toBeLessThan(0);
        expect(stylus.transform.worldRotation).not.toEqual(core_2.Quaternion.Identity());
    });
    it("Stops bumping to the left when A is pressed", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        uc.startEmulating();
        stylus.transform.worldPosition = core_2.Vector3.Zero();
        uc.stopEmulating();
        const downEvent = new KeyboardEvent("keydown", { code: "KeyA" });
        inputElement.dispatchEvent(downEvent);
        expect(stylus.transform.worldPosition.x).toEqual(0);
    });
    it("Bumps to the right when D is pressed", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        uc.startEmulating();
        stylus.transform.worldPosition = core_2.Vector3.Zero();
        stylus.transform.worldRotation = core_2.Quaternion.Identity();
        const downEvent = new KeyboardEvent("keydown", { code: "KeyD" });
        inputElement.dispatchEvent(downEvent);
        expect(stylus.transform.worldPosition.x).toBeGreaterThan(0);
        expect(stylus.transform.worldRotation).not.toEqual(core_2.Quaternion.Identity());
    });
    it("Stops bumping to the right when D is pressed", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        uc.startEmulating();
        stylus.transform.worldPosition = core_2.Vector3.Zero();
        uc.stopEmulating();
        const downEvent = new KeyboardEvent("keydown", { code: "KeyD" });
        inputElement.dispatchEvent(downEvent);
        expect(stylus.transform.worldPosition.x).toEqual(0);
    });
    it("Bumps down when S is pressed", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        uc.startEmulating();
        stylus.transform.worldPosition = core_2.Vector3.Zero();
        stylus.transform.worldRotation = core_2.Quaternion.Identity();
        const downEvent = new KeyboardEvent("keydown", { code: "KeyS" });
        inputElement.dispatchEvent(downEvent);
        expect(stylus.transform.worldPosition.z).toBeLessThan(0);
        expect(stylus.transform.worldRotation).not.toEqual(core_2.Quaternion.Identity());
    });
    it("Stops bumping when S is pressed", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        uc.startEmulating();
        stylus.transform.worldPosition = core_2.Vector3.Zero();
        uc.stopEmulating();
        const downEvent = new KeyboardEvent("keydown", { code: "KeyS" });
        inputElement.dispatchEvent(downEvent);
        expect(stylus.transform.worldPosition.z).toEqual(0);
    });
    it("Bumps up when W is pressed", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        uc.startEmulating();
        stylus.transform.worldPosition = core_2.Vector3.Zero();
        stylus.transform.worldRotation = core_2.Quaternion.Identity();
        const downEvent = new KeyboardEvent("keydown", { code: "KeyW" });
        inputElement.dispatchEvent(downEvent);
        expect(stylus.transform.worldPosition.z).toBeGreaterThan(0);
        expect(stylus.transform.worldRotation).not.toEqual(core_2.Quaternion.Identity());
    });
    it("Stops bumping when W is pressed", () => {
        const { uc, inputElement, stylus } = makeTestRig();
        uc.startEmulating();
        stylus.transform.worldPosition = core_2.Vector3.Zero();
        uc.stopEmulating();
        const downEvent = new KeyboardEvent("keydown", { code: "KeyW" });
        inputElement.dispatchEvent(downEvent);
        expect(stylus.transform.worldPosition.z).toEqual(0);
    });
});
//# sourceMappingURL=EmulateStylusUC.test.js.map