"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 MockDispatchStateChange_1 = require("../../Dispatcher/Mocks/MockDispatchStateChange");
const Entities_1 = require("../Entities");
const ScaleTransform_1 = require("./ScaleTransform");
function makeTestRig() {
    const appObjects = (0, core_1.makeAppObjectRepo)();
    const ao = appObjects.getOrCreate("ao");
    const transform = (0, Entities_1.makeTransform3D)(ao);
    const mockDispatch = (0, MockDispatchStateChange_1.makeMockDispatchStateChange)(appObjects);
    const doDispatchMock = jest.fn();
    mockDispatch.doDispatch = doDispatchMock;
    const scaleUC = (0, ScaleTransform_1.makeScaleTransformUC)(ao);
    const mockRayPick = (0, Babylon_1.makeMockSceneRayPickUC)(appObjects);
    const mockPick = jest.fn().mockReturnValue({ appObjectID: "hideableObj" });
    mockRayPick.sceneRayPick = mockPick;
    const mockSceneRay = (0, Babylon_1.makeMockPixelToSceneRayUC)(appObjects);
    mockSceneRay.pixelToSceneRay = mockPixelToRay;
    return {
        scaleUC,
        appObjects,
        doDispatchMock,
        mockPick,
        transform,
    };
}
function mockPixelToRay(pix) {
    return core_2.ParametricLine.FromPointDirection(new core_2.Vector3(pix.x, pix.y, -5), core_2.Vector3.Forward());
}
describe("Scale Transform UC - Ray", () => {
    it("Decreases the scaleUC with forward movement", () => {
        const { scaleUC, transform } = makeTestRig();
        transform.worldScale = core_2.Vector3.One();
        scaleUC.initializeRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 4.5), core_2.Vector3.Forward()));
        scaleUC.updateRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 5), core_2.Vector3.Forward()));
        expect(transform.worldScale.x).toBeLessThan(1);
    });
    it("Increases the scaleUC with backwards movement", () => {
        const { scaleUC, transform } = makeTestRig();
        transform.worldScale = core_2.Vector3.One();
        scaleUC.initializeRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 5), core_2.Vector3.Forward()));
        scaleUC.updateRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 4.5), core_2.Vector3.Forward()));
        expect(transform.worldScale.x).toBeGreaterThan(1);
    });
    it("Scales around the origin if there is no pick", () => {
        const { scaleUC, mockPick, transform } = makeTestRig();
        transform.worldPosition = core_2.Vector3.Zero();
        const pick = {
            hit: false,
            sceneRay: core_2.ParametricLine.Forward(),
        };
        mockPick.mockReturnValue(pick);
        scaleUC.initializeRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 5), core_2.Vector3.Forward()));
        scaleUC.updateRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 4.5), core_2.Vector3.Forward()));
        expect(transform.worldPosition).toEqual(core_2.Vector3.Zero());
    });
    it("Scales around the pick point", () => {
        const { scaleUC, transform, mockPick } = makeTestRig();
        transform.worldPosition = core_2.Vector3.Zero();
        const pick = {
            hit: true,
            sceneRay: core_2.ParametricLine.Forward(),
            worldPickPoint: new core_2.Vector3(1, 2, 3),
        };
        mockPick.mockReturnValue(pick);
        scaleUC.initializeRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 5), core_2.Vector3.Forward()));
        scaleUC.updateRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 4), core_2.Vector3.Forward()));
        expect(transform.worldPosition).toEqual(new core_2.Vector3(-1, -2, -3));
    });
    it("Dispatches state change", () => {
        const { scaleUC, doDispatchMock } = makeTestRig();
        scaleUC.initializeRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 5), core_2.Vector3.Forward()));
        scaleUC.updateRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 4.5), core_2.Vector3.Forward()));
        scaleUC.finish();
        expect(doDispatchMock).toHaveBeenCalled();
    });
    it("Does not dispatches state change if the scale does not change", () => {
        const { scaleUC, doDispatchMock } = makeTestRig();
        scaleUC.initializeRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 5), core_2.Vector3.Forward()));
        scaleUC.finish();
        expect(doDispatchMock).not.toHaveBeenCalled();
    });
    it("Does not dispatches state change if it was not initialized", () => {
        const { scaleUC, doDispatchMock } = makeTestRig();
        scaleUC.finish();
        expect(doDispatchMock).not.toHaveBeenCalled();
    });
    it("Does not scale if it is not initialized", () => {
        const { scaleUC, transform } = makeTestRig();
        transform.worldScale = core_2.Vector3.One();
        scaleUC.updateRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 4.5), core_2.Vector3.Forward()));
        expect(transform.worldScale.x).toEqual(1);
    });
    it("Limits the minimum scale", () => {
        const { scaleUC, transform } = makeTestRig();
        scaleUC.minScale = 0.5;
        transform.worldScale = core_2.Vector3.One();
        scaleUC.initializeRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 4), core_2.Vector3.Forward()));
        scaleUC.updateRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 5), core_2.Vector3.Forward()));
        expect(transform.worldScale).toEqual(new core_2.Vector3(0.5, 0.5, 0.5));
    });
    it("Limits the maximum scale", () => {
        const { scaleUC, transform } = makeTestRig();
        scaleUC.maxScale = 1.5;
        transform.worldScale = core_2.Vector3.One();
        scaleUC.initializeRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 5), core_2.Vector3.Forward()));
        scaleUC.updateRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 4), core_2.Vector3.Forward()));
        expect(transform.worldScale).toEqual(new core_2.Vector3(1.5, 1.5, 1.5));
    });
    it("Does not update if disabled", () => {
        const { scaleUC, transform } = makeTestRig();
        scaleUC.enabled = false;
        transform.worldScale = core_2.Vector3.One();
        scaleUC.initializeRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 5), core_2.Vector3.Forward()));
        scaleUC.updateRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, 4.5), core_2.Vector3.Forward()));
        expect(transform.worldScale).toEqual(core_2.Vector3.One());
    });
    it("Ray scales around the pick point on the plane if the plane is supplied", () => {
        const { scaleUC, transform } = makeTestRig();
        transform.worldPosition = core_2.Vector3.Zero();
        const pickPlane = core_2.ParametricPlane.FromPointNormal(new core_2.Vector3(0, 0, -1), core_2.Vector3.Forward());
        scaleUC.pickPlane = pickPlane;
        scaleUC.initializeRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, -5), core_2.Vector3.Forward()));
        scaleUC.updateRay(core_2.ParametricLine.FromPointDirection(new core_2.Vector3(0, 0, -4), core_2.Vector3.Forward()));
        expect(transform.worldPosition.x).toBeCloseTo(0);
        expect(transform.worldPosition.y).toBeCloseTo(0);
        expect(transform.worldPosition.z).toBeCloseTo(-1);
    });
});
describe("Scale Transform UC - Pixel", () => {
    it("Decreases the scaleUC with down movement", () => {
        const { scaleUC, transform } = makeTestRig();
        transform.worldScale = core_2.Vector3.One();
        scaleUC.initializePixel(core_2.Vector2.Zero());
        scaleUC.updatePixel(new core_2.Vector2(0, -5));
        expect(transform.worldScale.x).toBeLessThan(1);
    });
    it("Increases the scaleUC with up movement", () => {
        const { scaleUC, transform } = makeTestRig();
        transform.worldScale = core_2.Vector3.One();
        scaleUC.initializePixel(core_2.Vector2.Zero());
        scaleUC.updatePixel(new core_2.Vector2(0, 5));
        expect(transform.worldScale.x).toBeGreaterThan(1);
    });
    it("Scales around the origin if there is no pick", () => {
        const { scaleUC, mockPick, transform } = makeTestRig();
        transform.worldPosition = core_2.Vector3.Zero();
        const pick = {
            hit: false,
            sceneRay: core_2.ParametricLine.Forward(),
        };
        mockPick.mockReturnValue(pick);
        scaleUC.initializePixel(core_2.Vector2.Zero());
        scaleUC.updatePixel(new core_2.Vector2(0, 10));
        expect(transform.worldPosition).toEqual(core_2.Vector3.Zero());
    });
    it("Scales around the pick point", () => {
        const { scaleUC, transform, mockPick } = makeTestRig();
        transform.worldPosition = core_2.Vector3.Zero();
        const pick = {
            hit: true,
            sceneRay: core_2.ParametricLine.Forward(),
            worldPickPoint: new core_2.Vector3(1, 2, 3),
        };
        mockPick.mockReturnValue(pick);
        scaleUC.initializePixel(core_2.Vector2.Zero());
        scaleUC.updatePixel(new core_2.Vector2(0, 10));
        expect(transform.worldPosition).toEqual(new core_2.Vector3(-1, -2, -3));
    });
    it("Dispatches state change", () => {
        const { scaleUC, doDispatchMock } = makeTestRig();
        scaleUC.initializePixel(core_2.Vector2.Zero());
        scaleUC.updatePixel(new core_2.Vector2(0, -5));
        scaleUC.finish();
        expect(doDispatchMock).toHaveBeenCalled();
    });
    it("Does not dispatches state change if the scale does not change", () => {
        const { scaleUC, doDispatchMock } = makeTestRig();
        scaleUC.initializePixel(core_2.Vector2.Zero());
        scaleUC.finish();
        expect(doDispatchMock).not.toHaveBeenCalled();
    });
    it("Does not dispatches state change if it was not initialized", () => {
        const { scaleUC, doDispatchMock } = makeTestRig();
        scaleUC.finish();
        expect(doDispatchMock).not.toHaveBeenCalled();
    });
    it("Does not scale if it is not initialized", () => {
        const { scaleUC, transform } = makeTestRig();
        transform.worldScale = core_2.Vector3.One();
        scaleUC.updatePixel(new core_2.Vector2(0, 10));
        expect(transform.worldScale.x).toEqual(1);
    });
    it("Limits the minimum scale", () => {
        const { scaleUC, transform } = makeTestRig();
        scaleUC.minScale = 0.5;
        transform.worldScale = core_2.Vector3.One();
        scaleUC.initializePixel(core_2.Vector2.Zero());
        scaleUC.updatePixel(new core_2.Vector2(0, -50));
        expect(transform.worldScale).toEqual(new core_2.Vector3(0.5, 0.5, 0.5));
    });
    it("Limits the maximum scale", () => {
        const { scaleUC, transform } = makeTestRig();
        scaleUC.maxScale = 1.5;
        transform.worldScale = core_2.Vector3.One();
        scaleUC.initializePixel(core_2.Vector2.Zero());
        scaleUC.updatePixel(new core_2.Vector2(0, 50));
        expect(transform.worldScale).toEqual(new core_2.Vector3(1.5, 1.5, 1.5));
    });
    it("Does not update if disabled", () => {
        const { scaleUC, transform } = makeTestRig();
        scaleUC.enabled = false;
        transform.worldScale = core_2.Vector3.One();
        scaleUC.initializePixel(core_2.Vector2.Zero());
        scaleUC.updatePixel(new core_2.Vector2(0, -5));
        expect(transform.worldScale).toEqual(core_2.Vector3.One());
    });
    it("Pixel scales around the pick point on the plane if the plane is supplied", () => {
        const { scaleUC, mockPick, transform } = makeTestRig();
        transform.worldPosition = core_2.Vector3.Zero();
        const pickPlane = core_2.ParametricPlane.FromPointNormal(new core_2.Vector3(0, 0, -1), // Offset forward, closer to the camera
        core_2.Vector3.Forward());
        scaleUC.pickPlane = pickPlane;
        scaleUC.initializePixel(core_2.Vector2.Zero());
        scaleUC.updatePixel(new core_2.Vector2(0, 10));
        expect(transform.worldPosition.x).toBeCloseTo(0);
        expect(transform.worldPosition.y).toBeCloseTo(0);
        expect(transform.worldPosition.z).toBeCloseTo(1); // Pushes it away
    });
});
//# sourceMappingURL=ScaleTransform.test.js.map