"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 Translating_exports = {};
__export(Translating_exports, {
  Translating: () => Translating,
  moveShapesToPoint: () => moveShapesToPoint
});
module.exports = __toCommonJS(Translating_exports);
var import_editor = require("@tldraw/editor");
var import_noteHelpers = require("../../../shapes/note/noteHelpers");
var import_DragAndDropManager = require("../DragAndDropManager");
var import_selectHelpers = require("../selectHelpers");
class Translating extends import_editor.StateNode {
  static id = "translating";
  info = {};
  selectionSnapshot = {};
  snapshot = {};
  markId = "";
  isCloning = false;
  isCreating = false;
  onCreate = () => void 0;
  dragAndDropManager = new import_DragAndDropManager.DragAndDropManager(this.editor);
  onEnter = (info) => {
    const { isCreating = false, onCreate = () => void 0 } = info;
    this.info = info;
    this.parent.setCurrentToolIdMask(info.onInteractionEnd);
    this.isCreating = isCreating;
    this.onCreate = onCreate;
    if (isCreating) {
      this.markId = `creating:${this.editor.getOnlySelectedShape().id}`;
    } else {
      this.markId = "translating";
      this.editor.mark(this.markId);
    }
    this.isCloning = false;
    this.info = info;
    this.editor.setCursor({ type: "move", rotation: 0 });
    this.selectionSnapshot = getTranslatingSnapshot(this.editor);
    if (!this.isCreating) {
      if (this.editor.inputs.altKey) {
        this.startCloning();
        return;
      }
    }
    this.snapshot = this.selectionSnapshot;
    this.handleStart();
    this.updateShapes();
  };
  onExit = () => {
    this.parent.setCurrentToolIdMask(void 0);
    this.selectionSnapshot = {};
    this.snapshot = {};
    this.editor.snaps.clearIndicators();
    this.editor.setCursor({ type: "default", rotation: 0 });
    this.dragAndDropManager.clear();
  };
  onTick = () => {
    this.dragAndDropManager.updateDroppingNode(
      this.snapshot.movingShapes,
      this.updateParentTransforms
    );
    (0, import_editor.moveCameraWhenCloseToEdge)(this.editor);
  };
  onPointerMove = () => {
    this.updateShapes();
  };
  onKeyDown = () => {
    if (this.editor.inputs.altKey && !this.isCloning) {
      this.startCloning();
      return;
    }
    this.updateShapes();
  };
  onKeyUp = () => {
    if (!this.editor.inputs.altKey && this.isCloning) {
      this.stopCloning();
      return;
    }
    this.updateShapes();
  };
  onPointerUp = () => {
    this.complete();
  };
  onComplete = () => {
    this.complete();
  };
  onCancel = () => {
    this.cancel();
  };
  startCloning() {
    if (this.isCreating)
      return;
    this.isCloning = true;
    this.reset();
    this.markId = "translating";
    this.editor.mark(this.markId);
    this.editor.duplicateShapes(Array.from(this.editor.getSelectedShapeIds()));
    this.snapshot = getTranslatingSnapshot(this.editor);
    this.handleStart();
    this.updateShapes();
  }
  stopCloning() {
    this.isCloning = false;
    this.snapshot = this.selectionSnapshot;
    this.reset();
    this.markId = "translating";
    this.editor.mark(this.markId);
    this.updateShapes();
  }
  reset() {
    this.editor.bailToMark(this.markId);
  }
  complete() {
    this.updateShapes();
    this.dragAndDropManager.dropShapes(this.snapshot.movingShapes);
    (0, import_selectHelpers.kickoutOccludedShapes)(
      this.editor,
      this.snapshot.movingShapes.map((s) => s.id)
    );
    this.handleEnd();
    if (this.editor.getInstanceState().isToolLocked && this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd);
    } else {
      if (this.isCreating) {
        this.onCreate?.(this.editor.getOnlySelectedShape());
      } else {
        this.parent.transition("idle");
      }
    }
  }
  cancel() {
    this.reset();
    if (this.info.onInteractionEnd) {
      this.editor.setCurrentTool(this.info.onInteractionEnd);
    } else {
      this.parent.transition("idle", this.info);
    }
  }
  handleStart() {
    const { movingShapes } = this.snapshot;
    const changes = [];
    movingShapes.forEach((shape) => {
      const util = this.editor.getShapeUtil(shape);
      const change = util.onTranslateStart?.(shape);
      if (change) {
        changes.push(change);
      }
    });
    if (changes.length > 0) {
      this.editor.updateShapes(changes);
    }
    this.editor.setHoveredShape(null);
  }
  handleEnd() {
    const { movingShapes } = this.snapshot;
    if (this.isCloning && movingShapes.length > 0) {
      const currentAveragePagePoint = import_editor.Vec.Average(
        movingShapes.map((s) => this.editor.getShapePageTransform(s.id).point())
      );
      const offset = import_editor.Vec.Sub(currentAveragePagePoint, this.selectionSnapshot.averagePagePoint);
      if (!import_editor.Vec.IsNaN(offset)) {
        this.editor.updateInstanceState({
          duplicateProps: {
            shapeIds: movingShapes.map((s) => s.id),
            offset: { x: offset.x, y: offset.y }
          }
        });
      }
    }
    const changes = [];
    movingShapes.forEach((shape) => {
      const current = this.editor.getShape(shape.id);
      const util = this.editor.getShapeUtil(shape);
      const change = util.onTranslateEnd?.(shape, current);
      if (change) {
        changes.push(change);
      }
    });
    if (changes.length > 0) {
      this.editor.updateShapes(changes);
    }
  }
  handleChange() {
    const { movingShapes } = this.snapshot;
    const changes = [];
    movingShapes.forEach((shape) => {
      const current = this.editor.getShape(shape.id);
      const util = this.editor.getShapeUtil(shape);
      const change = util.onTranslate?.(shape, current);
      if (change) {
        changes.push(change);
      }
    });
    if (changes.length > 0) {
      this.editor.updateShapes(changes);
    }
  }
  updateShapes() {
    const { snapshot } = this;
    this.dragAndDropManager.updateDroppingNode(snapshot.movingShapes, this.updateParentTransforms);
    moveShapesToPoint({
      editor: this.editor,
      snapshot
    });
    this.handleChange();
  }
  updateParentTransforms = () => {
    const {
      editor,
      snapshot: { shapeSnapshots }
    } = this;
    const movingShapes = [];
    shapeSnapshots.forEach((shapeSnapshot) => {
      const shape = editor.getShape(shapeSnapshot.shape.id);
      if (!shape)
        return null;
      movingShapes.push(shape);
      const parentTransform = (0, import_editor.isPageId)(shape.parentId) ? null : import_editor.Mat.Inverse(editor.getShapePageTransform(shape.parentId));
      shapeSnapshot.parentTransform = parentTransform;
    });
  };
}
function getTranslatingSnapshot(editor) {
  const movingShapes = [];
  const pagePoints = [];
  const selectedShapeIds = editor.getSelectedShapeIds();
  const shapeSnapshots = (0, import_editor.compact)(
    selectedShapeIds.map((id) => {
      const shape = editor.getShape(id);
      if (!shape)
        return null;
      movingShapes.push(shape);
      const pageTransform = editor.getShapePageTransform(id);
      const pagePoint = pageTransform.point();
      const pageRotation = pageTransform.rotation();
      pagePoints.push(pagePoint);
      const parentTransform = import_editor.PageRecordType.isId(shape.parentId) ? null : import_editor.Mat.Inverse(editor.getShapePageTransform(shape.parentId));
      return {
        shape,
        pagePoint,
        pageRotation,
        parentTransform
      };
    })
  );
  const onlySelectedShape = editor.getOnlySelectedShape();
  let initialSnapPoints = [];
  if (onlySelectedShape) {
    initialSnapPoints = editor.snaps.shapeBounds.getSnapPoints(onlySelectedShape.id);
  } else {
    const selectionPageBounds = editor.getSelectionPageBounds();
    if (selectionPageBounds) {
      initialSnapPoints = selectionPageBounds.cornersAndCenter.map((p, i) => ({
        id: "selection:" + i,
        x: p.x,
        y: p.y
      }));
    }
  }
  let noteAdjacentPositions;
  let noteSnapshot;
  const { originPagePoint } = editor.inputs;
  const allHoveredNotes = shapeSnapshots.filter(
    (s) => editor.isShapeOfType(s.shape, "note") && editor.isPointInShape(s.shape, originPagePoint)
  );
  if (allHoveredNotes.length === 0) {
  } else if (allHoveredNotes.length === 1) {
    noteSnapshot = allHoveredNotes[0];
  } else {
    const allShapesSorted = editor.getCurrentPageShapesSorted();
    noteSnapshot = allHoveredNotes.map((s) => ({
      snapshot: s,
      index: allShapesSorted.findIndex((shape) => shape.id === s.shape.id)
    })).sort((a, b) => b.index - a.index)[0]?.snapshot;
  }
  if (noteSnapshot) {
    noteAdjacentPositions = (0, import_noteHelpers.getAvailableNoteAdjacentPositions)(
      editor,
      noteSnapshot.pageRotation,
      noteSnapshot.shape.props.growY ?? 0
    );
  }
  return {
    averagePagePoint: import_editor.Vec.Average(pagePoints),
    movingShapes,
    shapeSnapshots,
    initialPageBounds: editor.getSelectionPageBounds(),
    initialSnapPoints,
    noteAdjacentPositions,
    noteSnapshot
  };
}
function moveShapesToPoint({
  editor,
  snapshot
}) {
  const { inputs } = editor;
  const {
    noteSnapshot,
    noteAdjacentPositions,
    initialPageBounds,
    initialSnapPoints,
    shapeSnapshots,
    averagePagePoint
  } = snapshot;
  const isGridMode = editor.getInstanceState().isGridMode;
  const gridSize = editor.getDocumentSettings().gridSize;
  const delta = import_editor.Vec.Sub(inputs.currentPagePoint, inputs.originPagePoint);
  const flatten = editor.inputs.shiftKey ? Math.abs(delta.x) < Math.abs(delta.y) ? "x" : "y" : null;
  if (flatten === "x") {
    delta.x = 0;
  } else if (flatten === "y") {
    delta.y = 0;
  }
  editor.snaps.clearIndicators();
  const isSnapping = editor.user.getIsSnapMode() ? !inputs.ctrlKey : inputs.ctrlKey;
  if (isSnapping && editor.inputs.pointerVelocity.len() < 0.5) {
    const { nudge } = editor.snaps.shapeBounds.snapTranslateShapes({
      dragDelta: delta,
      initialSelectionPageBounds: initialPageBounds,
      lockedAxis: flatten,
      initialSelectionSnapPoints: initialSnapPoints
    });
    delta.add(nudge);
  } else {
    if (noteSnapshot && noteAdjacentPositions) {
      let min = import_noteHelpers.NOTE_PIT_RADIUS / editor.getZoomLevel();
      let offset = new import_editor.Vec(0, 0);
      const pageCenter = import_editor.Vec.Add(
        import_editor.Vec.Add(noteSnapshot.pagePoint, delta),
        new import_editor.Vec(import_noteHelpers.NOTE_SIZE / 2, import_noteHelpers.NOTE_SIZE / 2).rot(noteSnapshot.pageRotation)
      );
      for (const pit of noteAdjacentPositions) {
        const deltaToPit = import_editor.Vec.Sub(pageCenter, pit);
        const dist = deltaToPit.len();
        if (dist < min) {
          min = dist;
          offset = deltaToPit;
        }
      }
      delta.sub(offset);
    }
  }
  const averageSnappedPoint = import_editor.Vec.Add(averagePagePoint, delta);
  if (isGridMode && !inputs.ctrlKey) {
    averageSnappedPoint.snapToGrid(gridSize);
  }
  const averageSnap = import_editor.Vec.Sub(averageSnappedPoint, averagePagePoint);
  editor.updateShapes(
    (0, import_editor.compact)(
      shapeSnapshots.map(({ shape, pagePoint, parentTransform }) => {
        const newPagePoint = import_editor.Vec.Add(pagePoint, averageSnap);
        const newLocalPoint = parentTransform ? import_editor.Mat.applyToPoint(parentTransform, newPagePoint) : newPagePoint;
        return {
          id: shape.id,
          type: shape.type,
          x: newLocalPoint.x,
          y: newLocalPoint.y
        };
      })
    )
  );
}
//# sourceMappingURL=Translating.js.map
