import { BLOCK_BATCH } from '../../../surface-block/batch.js';
import { Bound, getBoundsWithRotation, getPointsFromBoundsWithRotation, linePolygonIntersects, PointLocation, polygonGetPointTangent, polygonNearestPoint, rotatePoints, } from '../../../surface-block/index.js';
export function selectable(SuperClass) {
    class DerivedSelectableInEdgelessClass extends SuperClass {
        constructor() {
            super(...arguments);
            this.connectable = true;
            this.batch = BLOCK_BATCH;
            this.rotate = 0;
        }
        get elementBound() {
            const bound = Bound.deserialize(this.xywh);
            return Bound.from(getBoundsWithRotation({ ...bound, rotate: this.rotate }));
        }
        hitTest(x, y) {
            const bound = Bound.deserialize(this.xywh);
            return bound.isPointInBound([x, y], 0);
        }
        containedByBounds(bounds) {
            const bound = Bound.deserialize(this.xywh);
            const points = getPointsFromBoundsWithRotation({
                x: bound.x,
                y: bound.y,
                w: bound.w,
                h: bound.h,
                rotate: this.rotate,
            });
            return points.some(point => bounds.containsPoint(point));
        }
        getNearestPoint(point) {
            const bound = Bound.deserialize(this.xywh);
            return polygonNearestPoint(rotatePoints(bound.points, bound.center, this.rotate ?? 0), point);
        }
        intersectWithLine(start, end) {
            const bound = Bound.deserialize(this.xywh);
            return linePolygonIntersects(start, end, rotatePoints(bound.points, bound.center, this.rotate ?? 0));
        }
        getRelativePointLocation(relativePoint) {
            const bound = Bound.deserialize(this.xywh);
            const point = bound.getRelativePoint(relativePoint);
            const rotatePoint = rotatePoints([point], bound.center, this.rotate ?? 0)[0];
            const points = rotatePoints(bound.points, bound.center, this.rotate ?? 0);
            const tangent = polygonGetPointTangent(points, rotatePoint);
            return new PointLocation(rotatePoint, tangent);
        }
        boxSelect(bound) {
            return (this.containedByBounds(bound) ||
                bound.points.some((point, i, points) => this.intersectWithLine(point, points[(i + 1) % points.length])));
        }
        get group() {
            const surfaceModel = this.page.getBlockByFlavour('affine:surface');
            return surfaceModel[0]?.getGroup(this.id) ?? null;
        }
    }
    return DerivedSelectableInEdgelessClass;
}
//# sourceMappingURL=edgeless-selectable.js.map