import { AppObjectUC, getSingletonComponent, } from "@vived/core";
import { ParametricPlane, Vector3 } from "@vived/core";
import { pixelToSceneRay, scenePixelPick } from "../../Babylon";
import { dispatchStateChange } from "../../Dispatcher";
import { SceneRootEntity } from "../Entities/SceneRootEntity";
export class PanSceneRootUC extends AppObjectUC {
}
PanSceneRootUC.type = "PanSceneRootUC";
PanSceneRootUC.get = (appObjects) => getSingletonComponent(PanSceneRootUC.type, appObjects);
export function makePanSceneRootUC(appObject) {
    return new PanSceneRootImp(appObject);
}
class PanSceneRootImp extends PanSceneRootUC {
    constructor(appObject) {
        super(appObject, PanSceneRootUC.type);
        this.pickOffset = Vector3.Zero();
        this.initialPosition = Vector3.Zero();
        this.hasBeenInitialized = false;
        this.panPlane = ParametricPlane.XY();
        this.doPan = (pixelPosition) => {
            if (!this.transformNode)
                return;
            if (!this.hasBeenInitialized)
                return;
            const pickRay = pixelToSceneRay(pixelPosition, this.appObjects);
            const pick = this.panPlane.intersectLine(pickRay) ?? Vector3.Zero();
            this.transformNode.worldPosition = Vector3.Add(pick, this.pickOffset);
        };
        this.initializePan = (initialPixelPos) => {
            if (!this.transformNode)
                return;
            if (!this.sceneRoot)
                return;
            const scenePick = scenePixelPick(initialPixelPos, this.appObjects);
            if (!scenePick)
                return;
            const pickPlaneDirection = Vector3.Backward();
            const planePickPos = scenePick?.worldPickPoint ?? Vector3.Zero();
            this.panPlane = ParametricPlane.FromPointNormal(planePickPos, pickPlaneDirection);
            const pick = this.panPlane.intersectLine(scenePick.sceneRay) ?? Vector3.Zero();
            const rootPos = this.transformNode.worldPosition;
            this.pickOffset = Vector3.Subtract(rootPos, pick);
            this.hasBeenInitialized = true;
            this.initialPosition = this.sceneRoot.position;
        };
        this.finishPan = () => {
            if (!this.hasBeenInitialized)
                return;
            if (!this.sceneRoot)
                return;
            this.hasBeenInitialized = false;
            if (Vector3.Equal(this.initialPosition, this.sceneRoot.position))
                return;
            dispatchStateChange(this.appObjects);
        };
        this.cancelPan = () => {
            this.hasBeenInitialized = false;
        };
        this.sceneRoot = appObject.getComponent(SceneRootEntity.type);
        if (!this.sceneRoot) {
            this.warn("OrbitSceneRootImp UC has been added to an App Object that does not have a SceneRoot Entity");
            return;
        }
        this.transformNode = this.sceneRoot?.transform;
    }
}
//# sourceMappingURL=PanSceneRoot.js.map