"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var svgInk_exports = {};
__export(svgInk_exports, {
  renderPartition: () => renderPartition,
  svgInk: () => svgInk
});
module.exports = __toCommonJS(svgInk_exports);
var import_editor = require("@cmpd/editor");
var import_getStrokeOutlinePoints = require("./getStrokeOutlinePoints");
var import_getStrokePoints = require("./getStrokePoints");
var import_setStrokePointRadii = require("./setStrokePointRadii");
function svgInk(rawInputPoints, options = {}) {
  const { start = {}, end = {} } = options;
  const { cap: capStart = true } = start;
  const { cap: capEnd = true } = end;
  (0, import_editor.assert)(!start.taper && !end.taper, "cap taper not supported here");
  (0, import_editor.assert)(!start.easing && !end.easing, "cap easing not supported here");
  (0, import_editor.assert)(capStart && capEnd, "cap must be true");
  const points = (0, import_getStrokePoints.getStrokePoints)(rawInputPoints, options);
  (0, import_setStrokePointRadii.setStrokePointRadii)(points, options);
  const partitions = partitionAtElbows(points);
  let svg = "";
  for (const partition of partitions) {
    svg += renderPartition(partition, options);
  }
  return svg;
}
function partitionAtElbows(points) {
  if (points.length <= 2)
    return [points];
  const result = [];
  let currentPartition = [points[0]];
  for (let i = 1; i < points.length - 1; i++) {
    const prevPoint = points[i - 1];
    const thisPoint = points[i];
    const nextPoint = points[i + 1];
    const prevAngle = import_editor.Vec2d.Angle(prevPoint.point, thisPoint.point);
    const nextAngle = import_editor.Vec2d.Angle(thisPoint.point, nextPoint.point);
    const acuteness = Math.abs((0, import_editor.shortAngleDist)(prevAngle, nextAngle)) / Math.PI;
    if (acuteness > 0.8) {
      const elbowPoint = {
        ...thisPoint,
        point: thisPoint.input
      };
      currentPartition.push(elbowPoint);
      result.push(cleanUpPartition(currentPartition));
      currentPartition = [elbowPoint];
      continue;
    }
    currentPartition.push(thisPoint);
    if (acuteness < 0.25) {
      continue;
    }
    const avgRadius = (prevPoint.radius + thisPoint.radius + nextPoint.radius) / 3;
    const incomingNormalizedDist = import_editor.Vec2d.Dist(prevPoint.point, thisPoint.point) / avgRadius;
    const outgoingNormalizedDist = import_editor.Vec2d.Dist(thisPoint.point, nextPoint.point) / avgRadius;
    const angularDist = incomingNormalizedDist + outgoingNormalizedDist;
    if (angularDist < 1.5) {
      currentPartition.push(thisPoint);
      result.push(cleanUpPartition(currentPartition));
      currentPartition = [thisPoint];
      continue;
    }
  }
  currentPartition.push(points[points.length - 1]);
  result.push(cleanUpPartition(currentPartition));
  return result;
}
function cleanUpPartition(partition) {
  const startPoint = partition[0];
  while (partition.length > 2) {
    const nextPoint = partition[1];
    const dist = import_editor.Vec2d.Dist(startPoint.point, nextPoint.point);
    const avgRadius = (startPoint.radius + nextPoint.radius) / 2;
    if (dist < avgRadius * 0.5) {
      partition.splice(1, 1);
    } else {
      break;
    }
  }
  const endPoint = partition[partition.length - 1];
  while (partition.length > 2) {
    const prevPoint = partition[partition.length - 2];
    const dist = import_editor.Vec2d.Dist(endPoint.point, prevPoint.point);
    const avgRadius = (endPoint.radius + prevPoint.radius) / 2;
    if (dist < avgRadius * 0.5) {
      partition.splice(partition.length - 2, 1);
    } else {
      break;
    }
  }
  if (partition.length > 1) {
    partition[0] = {
      ...partition[0],
      vector: import_editor.Vec2d.FromAngle(import_editor.Vec2d.Angle(partition[1].point, partition[0].point))
    };
    partition[partition.length - 1] = {
      ...partition[partition.length - 1],
      vector: import_editor.Vec2d.FromAngle(
        import_editor.Vec2d.Angle(partition[partition.length - 1].point, partition[partition.length - 2].point)
      )
    };
  }
  return partition;
}
function circlePath(cx, cy, r) {
  return "M " + cx + " " + cy + " m -" + r + ", 0 a " + r + "," + r + " 0 1,1 " + r * 2 + ",0 a " + r + "," + r + " 0 1,1 -" + r * 2 + ",0";
}
function renderPartition(strokePoints, options = {}) {
  if (strokePoints.length === 0)
    return "";
  if (strokePoints.length === 1) {
    return circlePath(strokePoints[0].point.x, strokePoints[0].point.y, strokePoints[0].radius);
  }
  const { left, right } = (0, import_getStrokeOutlinePoints.getStrokeOutlineTracks)(strokePoints, options);
  right.reverse();
  let svg = `M${(0, import_editor.precise)(left[0])}T`;
  for (let i = 1; i < left.length; i++) {
    svg += (0, import_editor.average)(left[i - 1], left[i]);
  }
  {
    const point = strokePoints[strokePoints.length - 1];
    const radius = point.radius;
    const direction = point.vector.clone().per().neg();
    const arcStart = import_editor.Vec2d.Add(point.point, import_editor.Vec2d.Mul(direction, radius));
    const arcEnd = import_editor.Vec2d.Add(point.point, import_editor.Vec2d.Mul(direction, -radius));
    svg += `${(0, import_editor.precise)(arcStart)}A${(0, import_editor.toDomPrecision)(radius)},${(0, import_editor.toDomPrecision)(
      radius
    )} 0 0 1 ${(0, import_editor.precise)(arcEnd)}T`;
  }
  for (let i = 1; i < right.length; i++) {
    svg += (0, import_editor.average)(right[i - 1], right[i]);
  }
  {
    const point = strokePoints[0];
    const radius = point.radius;
    const direction = point.vector.clone().per();
    const arcStart = import_editor.Vec2d.Add(point.point, import_editor.Vec2d.Mul(direction, radius));
    const arcEnd = import_editor.Vec2d.Add(point.point, import_editor.Vec2d.Mul(direction, -radius));
    svg += `${(0, import_editor.precise)(arcStart)}A${(0, import_editor.toDomPrecision)(radius)},${(0, import_editor.toDomPrecision)(
      radius
    )} 0 0 1 ${(0, import_editor.precise)(arcEnd)}Z`;
  }
  return svg;
}
//# sourceMappingURL=svgInk.js.map
