"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const lifecycle = require("../../../../base/common/lifecycle.js");
const platform = require("../../../../base/common/platform.js");
require("./dnd.css.js");
const editorExtensions = require("../../../browser/editorExtensions.js");
const position = require("../../../common/core/position.js");
const range = require("../../../common/core/range.js");
const selection = require("../../../common/core/selection.js");
const textModel = require("../../../common/model/textModel.js");
const dragAndDropCommand = require("./dragAndDropCommand.js");
function hasTriggerModifier(e) {
  if (platform.isMacintosh) {
    return e.altKey;
  } else {
    return e.ctrlKey;
  }
}
class DragAndDropController extends lifecycle.Disposable {
  constructor(editor) {
    super();
    this._editor = editor;
    this._register(this._editor.onMouseDown((e) => this._onEditorMouseDown(e)));
    this._register(this._editor.onMouseUp((e) => this._onEditorMouseUp(e)));
    this._register(this._editor.onMouseDrag((e) => this._onEditorMouseDrag(e)));
    this._register(this._editor.onMouseDrop((e) => this._onEditorMouseDrop(e)));
    this._register(this._editor.onMouseDropCanceled(() => this._onEditorMouseDropCanceled()));
    this._register(this._editor.onKeyDown((e) => this.onEditorKeyDown(e)));
    this._register(this._editor.onKeyUp((e) => this.onEditorKeyUp(e)));
    this._register(this._editor.onDidBlurEditorWidget(() => this.onEditorBlur()));
    this._register(this._editor.onDidBlurEditorText(() => this.onEditorBlur()));
    this._dndDecorationIds = [];
    this._mouseDown = false;
    this._modifierPressed = false;
    this._dragSelection = null;
  }
  onEditorBlur() {
    this._removeDecoration();
    this._dragSelection = null;
    this._mouseDown = false;
    this._modifierPressed = false;
  }
  onEditorKeyDown(e) {
    if (!this._editor.getOption(
      31
      /* dragAndDrop */
    ) || this._editor.getOption(
      18
      /* columnSelection */
    )) {
      return;
    }
    if (hasTriggerModifier(e)) {
      this._modifierPressed = true;
    }
    if (this._mouseDown && hasTriggerModifier(e)) {
      this._editor.updateOptions({
        mouseStyle: "copy"
      });
    }
  }
  onEditorKeyUp(e) {
    if (!this._editor.getOption(
      31
      /* dragAndDrop */
    ) || this._editor.getOption(
      18
      /* columnSelection */
    )) {
      return;
    }
    if (hasTriggerModifier(e)) {
      this._modifierPressed = false;
    }
    if (this._mouseDown && e.keyCode === DragAndDropController.TRIGGER_KEY_VALUE) {
      this._editor.updateOptions({
        mouseStyle: "default"
      });
    }
  }
  _onEditorMouseDown(mouseEvent) {
    this._mouseDown = true;
  }
  _onEditorMouseUp(mouseEvent) {
    this._mouseDown = false;
    this._editor.updateOptions({
      mouseStyle: "text"
    });
  }
  _onEditorMouseDrag(mouseEvent) {
    let target = mouseEvent.target;
    if (this._dragSelection === null) {
      const selections = this._editor.getSelections() || [];
      let possibleSelections = selections.filter((selection2) => target.position && selection2.containsPosition(target.position));
      if (possibleSelections.length === 1) {
        this._dragSelection = possibleSelections[0];
      } else {
        return;
      }
    }
    if (hasTriggerModifier(mouseEvent.event)) {
      this._editor.updateOptions({
        mouseStyle: "copy"
      });
    } else {
      this._editor.updateOptions({
        mouseStyle: "default"
      });
    }
    if (target.position) {
      if (this._dragSelection.containsPosition(target.position)) {
        this._removeDecoration();
      } else {
        this.showAt(target.position);
      }
    }
  }
  _onEditorMouseDropCanceled() {
    this._editor.updateOptions({
      mouseStyle: "text"
    });
    this._removeDecoration();
    this._dragSelection = null;
    this._mouseDown = false;
  }
  _onEditorMouseDrop(mouseEvent) {
    if (mouseEvent.target && (this._hitContent(mouseEvent.target) || this._hitMargin(mouseEvent.target)) && mouseEvent.target.position) {
      let newCursorPosition = new position.Position(mouseEvent.target.position.lineNumber, mouseEvent.target.position.column);
      if (this._dragSelection === null) {
        let newSelections = null;
        if (mouseEvent.event.shiftKey) {
          let primarySelection = this._editor.getSelection();
          if (primarySelection) {
            const { selectionStartLineNumber, selectionStartColumn } = primarySelection;
            newSelections = [new selection.Selection(selectionStartLineNumber, selectionStartColumn, newCursorPosition.lineNumber, newCursorPosition.column)];
          }
        } else {
          newSelections = (this._editor.getSelections() || []).map((selection$1) => {
            if (selection$1.containsPosition(newCursorPosition)) {
              return new selection.Selection(newCursorPosition.lineNumber, newCursorPosition.column, newCursorPosition.lineNumber, newCursorPosition.column);
            } else {
              return selection$1;
            }
          });
        }
        this._editor.setSelections(
          newSelections || [],
          "mouse",
          3
          /* Explicit */
        );
      } else if (!this._dragSelection.containsPosition(newCursorPosition) || (hasTriggerModifier(mouseEvent.event) || this._modifierPressed) && (this._dragSelection.getEndPosition().equals(newCursorPosition) || this._dragSelection.getStartPosition().equals(newCursorPosition))) {
        this._editor.pushUndoStop();
        this._editor.executeCommand(DragAndDropController.ID, new dragAndDropCommand.DragAndDropCommand(this._dragSelection, newCursorPosition, hasTriggerModifier(mouseEvent.event) || this._modifierPressed));
        this._editor.pushUndoStop();
      }
    }
    this._editor.updateOptions({
      mouseStyle: "text"
    });
    this._removeDecoration();
    this._dragSelection = null;
    this._mouseDown = false;
  }
  showAt(position2) {
    let newDecorations = [{
      range: new range.Range(position2.lineNumber, position2.column, position2.lineNumber, position2.column),
      options: DragAndDropController._DECORATION_OPTIONS
    }];
    this._dndDecorationIds = this._editor.deltaDecorations(this._dndDecorationIds, newDecorations);
    this._editor.revealPosition(
      position2,
      1
      /* Immediate */
    );
  }
  _removeDecoration() {
    this._dndDecorationIds = this._editor.deltaDecorations(this._dndDecorationIds, []);
  }
  _hitContent(target) {
    return target.type === 6 || target.type === 7;
  }
  _hitMargin(target) {
    return target.type === 2 || target.type === 3 || target.type === 4;
  }
  dispose() {
    this._removeDecoration();
    this._dragSelection = null;
    this._mouseDown = false;
    this._modifierPressed = false;
    super.dispose();
  }
}
DragAndDropController.ID = "editor.contrib.dragAndDrop";
DragAndDropController.TRIGGER_KEY_VALUE = platform.isMacintosh ? 6 : 5;
DragAndDropController._DECORATION_OPTIONS = textModel.ModelDecorationOptions.register({
  description: "dnd-target",
  className: "dnd-target"
});
editorExtensions.registerEditorContribution(DragAndDropController.ID, DragAndDropController);
exports.DragAndDropController = DragAndDropController;
