import { AppObjectUC } from "@vived/core";
import { ParametricPlane, Vector2, Vector3 } from "@vived/core";
import { pixelToSceneRay, scenePixelPick } from "../../Babylon";
import { dispatchStateChange } from "../../Dispatcher";
import { Transform3D } from "../Entities";
export class PinchTransformUC extends AppObjectUC {
}
PinchTransformUC.type = "PinchTransformUC";
export function makePinchTransformUC(appObject) {
    return new PinchTransformUCImp(appObject);
}
class PinchTransformUCImp extends PinchTransformUC {
    getTouchCenter(t1, t2) {
        const delta = Vector2.Subtract(t2, t1);
        const halfDelta = Vector2.NewVectorOfLength(delta.unit, 0.5 * delta.magnitued);
        return Vector2.Add(t1, halfDelta);
    }
    getTouchDistance(t1, t2) {
        const delta = Vector2.Subtract(t2, t1);
        return delta.magnitued;
    }
    constructor(appObject) {
        super(appObject, PinchTransformUC.type);
        this.sensitivity = 0.01;
        this.enabled = true;
        this.previousDistanceBetweenTouches = 0;
        this._panPlane = ParametricPlane.XY();
        this.pickOffset = Vector3.Zero();
        this.initialScale = 0;
        this.initializePinch = (touchPos1, touchPos2) => {
            if (!this.transform)
                return;
            this.previousDistanceBetweenTouches = this.getTouchDistance(touchPos1, touchPos2);
            const touchCenter = this.getTouchCenter(touchPos1, touchPos2);
            const scenePick = scenePixelPick(touchCenter, this.appObjects);
            if (this.pickPlane) {
                this._panPlane = this.pickPlane;
            }
            else {
                const pickPoint = scenePick?.worldPickPoint ?? Vector3.Zero();
                const pickPlaneDirection = Vector3.Backward();
                this._panPlane = ParametricPlane.FromPointNormal(pickPoint, pickPlaneDirection);
            }
            const pickRay = pixelToSceneRay(touchCenter, this.appObjects);
            const planePick = this._panPlane.intersectLine(pickRay) ?? Vector3.Zero();
            this.pickOffset = this.transform.worldPointToLocal(planePick);
            this.initialScale = this.transform.worldScale.x;
        };
        this.doPinch = (touchPos1, touchPos2) => {
            if (!this.enabled)
                return;
            if (!this.transform)
                return;
            const currentTouchDist = this.getTouchDistance(touchPos1, touchPos2);
            const touchDelta = currentTouchDist - this.previousDistanceBetweenTouches;
            const currentScale = this.transform.worldScale.x;
            const scaleDelta = touchDelta * this.sensitivity * currentScale;
            let newScale = currentScale + scaleDelta;
            if (this.minScale !== undefined && newScale < this.minScale) {
                newScale = this.minScale;
            }
            if (this.maxScale !== undefined && newScale > this.maxScale) {
                newScale = this.maxScale;
            }
            this.transform.worldScale = new Vector3(newScale, newScale, newScale);
            const touchCenter = this.getTouchCenter(touchPos1, touchPos2);
            const pickRay = pixelToSceneRay(touchCenter, this.appObjects);
            const planePick = this._panPlane.intersectLine(pickRay) ?? Vector3.Zero();
            const globalOffset = this.transform.localPointToWorld(this.pickOffset);
            const delta = Vector3.Subtract(planePick, globalOffset);
            const currentWorldPos = this.transform.worldPosition;
            const newWorldPos = Vector3.Add(currentWorldPos, delta);
            this.transform.worldPosition = newWorldPos;
            this.previousDistanceBetweenTouches = currentTouchDist;
        };
        this.finishPinch = () => {
            if (this.initialScale === this.transform?.worldScale.x)
                return;
            dispatchStateChange(this.appObjects);
        };
        this.transform = appObject.getComponent(Transform3D.type);
        if (!this.transform) {
            this.warn("PinchSceneRootUC UC has been added to an App Object that does not have a Transform3D");
            return;
        }
    }
}
//# sourceMappingURL=PinchTransform.js.map