import { jsx } from "react/jsx-runtime";
import {
  Circle2d,
  Polygon2d,
  SVGContainer,
  ShapeUtil,
  getColorValue,
  highlightShapeMigrations,
  highlightShapeProps,
  last,
  lerp,
  rng,
  useValue
} from "@tldraw/editor";
import { getHighlightFreehandSettings, getPointsFromDrawSegments } from "../draw/getPath.mjs";
import { FONT_SIZES } from "../shared/default-shape-constants.mjs";
import { getStrokeOutlinePoints } from "../shared/freehand/getStrokeOutlinePoints.mjs";
import { getStrokePoints } from "../shared/freehand/getStrokePoints.mjs";
import { setStrokePointRadii } from "../shared/freehand/setStrokePointRadii.mjs";
import { getSvgPathFromStrokePoints } from "../shared/freehand/svg.mjs";
import { interpolateSegments } from "../shared/interpolate-props.mjs";
import { useColorSpace } from "../shared/useColorSpace.mjs";
import { useDefaultColorTheme } from "../shared/useDefaultColorTheme.mjs";
class HighlightShapeUtil extends ShapeUtil {
  static type = "highlight";
  static props = highlightShapeProps;
  static migrations = highlightShapeMigrations;
  options = {
    maxPointsPerShape: 600,
    underlayOpacity: 0.82,
    overlayOpacity: 0.35
  };
  hideResizeHandles(shape) {
    return getIsDot(shape);
  }
  hideRotateHandle(shape) {
    return getIsDot(shape);
  }
  hideSelectionBoundsFg(shape) {
    return getIsDot(shape);
  }
  getDefaultProps() {
    return {
      segments: [],
      color: "black",
      size: "m",
      isComplete: false,
      isPen: false,
      scale: 1,
      scaleX: 1,
      scaleY: 1
    };
  }
  getGeometry(shape) {
    const strokeWidth = getStrokeWidth(shape);
    if (getIsDot(shape)) {
      return new Circle2d({
        x: -strokeWidth / 2,
        y: -strokeWidth / 2,
        radius: strokeWidth / 2,
        isFilled: true
      });
    }
    const { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, true);
    const opts = getHighlightFreehandSettings({ strokeWidth: sw, showAsComplete: true });
    setStrokePointRadii(strokePoints, opts);
    return new Polygon2d({
      points: getStrokeOutlinePoints(strokePoints, opts),
      isFilled: true
    });
  }
  component(shape) {
    const forceSolid = useHighlightForceSolid(this.editor, shape);
    const strokeWidth = getStrokeWidth(shape);
    return /* @__PURE__ */ jsx(SVGContainer, { children: /* @__PURE__ */ jsx(
      HighlightRenderer,
      {
        shape,
        forceSolid,
        strokeWidth,
        opacity: this.options.overlayOpacity
      }
    ) });
  }
  backgroundComponent(shape) {
    const forceSolid = useHighlightForceSolid(this.editor, shape);
    const strokeWidth = getStrokeWidth(shape);
    return /* @__PURE__ */ jsx(SVGContainer, { children: /* @__PURE__ */ jsx(
      HighlightRenderer,
      {
        shape,
        forceSolid,
        strokeWidth,
        opacity: this.options.underlayOpacity
      }
    ) });
  }
  indicator(shape) {
    const forceSolid = useHighlightForceSolid(this.editor, shape);
    const strokeWidth = getStrokeWidth(shape);
    const { strokePoints, sw } = getHighlightStrokePoints(shape, strokeWidth, forceSolid);
    const allPointsFromSegments = getPointsFromDrawSegments(
      shape.props.segments,
      shape.props.scaleX,
      shape.props.scaleY
    );
    let strokePath;
    if (strokePoints.length < 2) {
      strokePath = getIndicatorDot(allPointsFromSegments[0], sw);
    } else {
      strokePath = getSvgPathFromStrokePoints(strokePoints, false);
    }
    return /* @__PURE__ */ jsx("path", { d: strokePath });
  }
  toSvg(shape) {
    const strokeWidth = getStrokeWidth(shape);
    const forceSolid = strokeWidth < 1.5;
    const scaleFactor = 1 / shape.props.scale;
    return /* @__PURE__ */ jsx("g", { transform: `scale(${scaleFactor})`, children: /* @__PURE__ */ jsx(
      HighlightRenderer,
      {
        forceSolid,
        strokeWidth,
        shape,
        opacity: this.options.overlayOpacity
      }
    ) });
  }
  toBackgroundSvg(shape) {
    const strokeWidth = getStrokeWidth(shape);
    const forceSolid = strokeWidth < 1.5;
    const scaleFactor = 1 / shape.props.scale;
    return /* @__PURE__ */ jsx("g", { transform: `scale(${scaleFactor})`, children: /* @__PURE__ */ jsx(
      HighlightRenderer,
      {
        forceSolid,
        strokeWidth,
        shape,
        opacity: this.options.underlayOpacity
      }
    ) });
  }
  onResize(shape, info) {
    const { scaleX, scaleY } = info;
    return {
      props: {
        scaleX: scaleX * shape.props.scaleX,
        scaleY: scaleY * shape.props.scaleY
      }
    };
  }
  getInterpolatedProps(startShape, endShape, t) {
    return {
      ...(t > 0.5 ? endShape.props : startShape.props),
      ...endShape.props,
      segments: interpolateSegments(startShape.props.segments, endShape.props.segments, t),
      scale: lerp(startShape.props.scale, endShape.props.scale, t)
    };
  }
}
function getShapeDot(point) {
  const r = 0.1;
  return `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${r * 2},0`;
}
function getIndicatorDot(point, sw) {
  const r = sw / 2;
  return `M ${point.x} ${point.y} m -${r}, 0 a ${r},${r} 0 1,0 ${r * 2},0 a ${r},${r} 0 1,0 -${r * 2},0`;
}
function getHighlightStrokePoints(shape, strokeWidth, forceSolid) {
  const allPointsFromSegments = getPointsFromDrawSegments(
    shape.props.segments,
    shape.props.scaleX,
    shape.props.scaleY
  );
  const showAsComplete = shape.props.isComplete || last(shape.props.segments)?.type === "straight";
  let sw = strokeWidth;
  if (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {
    sw += rng(shape.id)() * (strokeWidth / 6);
  }
  const options = getHighlightFreehandSettings({
    strokeWidth: sw,
    showAsComplete
  });
  const strokePoints = getStrokePoints(allPointsFromSegments, options);
  return { strokePoints, sw };
}
function getStrokeWidth(shape) {
  return FONT_SIZES[shape.props.size] * 1.12 * shape.props.scale;
}
function getIsDot(shape) {
  return shape.props.segments.length === 1 && shape.props.segments[0].points.length < 16;
}
function HighlightRenderer({
  strokeWidth,
  forceSolid,
  shape,
  opacity
}) {
  const theme = useDefaultColorTheme();
  const allPointsFromSegments = getPointsFromDrawSegments(
    shape.props.segments,
    shape.props.scaleX,
    shape.props.scaleY
  );
  let sw = strokeWidth;
  if (!forceSolid && !shape.props.isPen && allPointsFromSegments.length === 1) {
    sw += rng(shape.id)() * (sw / 6);
  }
  const options = getHighlightFreehandSettings({
    strokeWidth: sw,
    showAsComplete: shape.props.isComplete || last(shape.props.segments)?.type === "straight"
  });
  const strokePoints = getStrokePoints(allPointsFromSegments, options);
  const solidStrokePath = strokePoints.length > 1 ? getSvgPathFromStrokePoints(strokePoints, false) : getShapeDot(allPointsFromSegments[0]);
  const colorSpace = useColorSpace();
  const color = getColorValue(
    theme,
    shape.props.color,
    colorSpace === "p3" ? "highlightP3" : "highlightSrgb"
  );
  return /* @__PURE__ */ jsx(
    "path",
    {
      d: solidStrokePath,
      strokeLinecap: "round",
      fill: "none",
      pointerEvents: "all",
      stroke: color,
      strokeWidth: sw,
      opacity
    }
  );
}
function useHighlightForceSolid(editor, shape) {
  return useValue(
    "forceSolid",
    () => {
      const sw = getStrokeWidth(shape);
      const zoomLevel = editor.getEfficientZoomLevel();
      if (sw / zoomLevel < 1.5) {
        return true;
      }
      return false;
    },
    [editor]
  );
}
export {
  HighlightShapeUtil
};
//# sourceMappingURL=HighlightShapeUtil.mjs.map
