import { Matrix, Ray, Vector3 } from '../loader/babylonjs-import';
import { copyVertex3ToRef, intersectsPlaneAtToRef } from '../math';
import { BimPointBase } from './BimPointBase';
/**
 * Represents result of a {@link DynamicPolygonPoint} move operation.
 */
export var PointMoveResult;
(function (PointMoveResult) {
    /** Result is unknown */
    PointMoveResult[PointMoveResult["Unknown"] = 0] = "Unknown";
    /** Points were moved successfully */
    PointMoveResult[PointMoveResult["Success"] = 1] = "Success";
    /** Points were not moved because the polygon would have become complex */
    PointMoveResult[PointMoveResult["ComplexPolygon"] = 2] = "ComplexPolygon";
    /** Could not move point because the ray (from mouse coordinate) did not intersect the polygon plane. */
    PointMoveResult[PointMoveResult["RayIntersectionFailed"] = 3] = "RayIntersectionFailed";
})(PointMoveResult || (PointMoveResult = {}));
export class Html2CanvasPoint extends BimPointBase {
    _api;
    plane;
    static _tmp = {
        identityMatrix: Matrix.Identity(),
        rayA: Ray.Zero(),
        vector3A: Vector3.Zero(),
        vector3B: Vector3.Zero(),
        counter: 0
    };
    /** When `true` then {@link DynamicPolygon.onPointTrackableScreen} will trigger for this instance. Otherwise it will not */
    isEnabled = true;
    _parent;
    recalculateOrGetWorldCoords(force = false) {
        if (this._recalculateWorldCoords || force) {
            Vector3.TransformCoordinatesFromFloatsToRef(this._localX, this._localY, this._localZ, this._parent.worldMatrix(), Html2CanvasPoint._tmp.vector3B);
            this._worldX = Html2CanvasPoint._tmp.vector3B.x;
            this._worldY = Html2CanvasPoint._tmp.vector3B.y;
            this._worldZ = Html2CanvasPoint._tmp.vector3B.z;
            this._recalculateWorldCoords = false;
        }
        return { x: this._worldX, y: this._worldY, z: this._worldZ };
    }
    recalculateOrGetLocalCoords(force = false) {
        if (this._recalculateLocalCoords || force) {
            Vector3.TransformCoordinatesFromFloatsToRef(this._worldX, this._worldY, this._worldZ, this._parent.worldMatrix().clone().invert(), Html2CanvasPoint._tmp.vector3B);
            this._localX = Html2CanvasPoint._tmp.vector3B.x;
            this._localY = Html2CanvasPoint._tmp.vector3B.y;
            this._localZ = Html2CanvasPoint._tmp.vector3B.z;
            this._recalculateLocalCoords = false;
        }
        return { x: this._localX, y: this._localY, z: this._localZ };
    }
    /**
     *
     * @param _api {@link BimCoreApi} API.
     * @param plane [Plane](https://doc.babylonjs.com/typedoc/classes/babylon.plane) that this point lies on.
     */
    constructor(_api, plane) {
        super();
        this._api = _api;
        this.plane = plane;
    }
    /**
     * Attempt to move a point to a new location on [Plane](https://doc.babylonjs.com/typedoc/classes/babylon.plane).
     * To find the location, a ray is shot from camera through `canvasCoordinate`
     * and then an intersection test is performed. If the ray intersects Plane, the point is moved to the coordinates
     * of the intersection. Otherwise nothing happens.
     * The point is assigned the same x,y,z values
     * as the coordinate where the ray intersects the plane.
     * @returns a {@link DynamicPolygonPointMoveResult}.
     */
    move(canvasCoordinate) {
        // If we get an intersection and if point is virtual then convert the virtual point to a real point.
        // and trigger the coordinate tracker. We also add two new virtual points to the coordinate tracker
        // otherwise we simply move it.
        const pickingRay = Html2CanvasPoint._tmp.rayA;
        this._api.viewer.scene.createPickingRayToRef(canvasCoordinate.x, canvasCoordinate.y, Html2CanvasPoint._tmp.identityMatrix, pickingRay, this._api.viewer.scene.activeCamera);
        // TODO If we move a point so it ends up perfectly on the line of the neighbour points then we could
        // convert the point to a virtual point. It no longer contributes to the polygon anyway.
        // If that happens then return DynamicPolygonPointMoveResult.ComplexPolygon
        const intersectionPoint = Html2CanvasPoint._tmp.vector3A;
        const distance = intersectsPlaneAtToRef(pickingRay, this.plane, intersectionPoint);
        if (distance > -1) {
            copyVertex3ToRef(intersectionPoint, this);
            return PointMoveResult.Success;
        }
        return PointMoveResult.RayIntersectionFailed;
    }
    scale(retainAspectRatio = true) {
        this._parent.scale(this, retainAspectRatio);
    }
    rotate() {
        this._parent.rotate(this);
    }
    tranlate() {
        this._parent.translate();
    }
}
//# sourceMappingURL=Html2CanvasPoint.js.map