import { EnterLeaveCounter as S } from "./EnterLeaveCounter.es.js";
import { getNodeClientOffset as O, getEventClientOffset as h, getDragPreviewOffset as I } from "./OffsetUtils.es.js";
import { createNativeDragSource as L, matchNativeItemType as c } from "./NativeDragSources/index.es.js";
import * as f from "./NativeTypes.es.js";
import { OptionsReader as C } from "./OptionsReader.es.js";
function w(o, e, r) {
  return e in o ? Object.defineProperty(o, e, {
    value: r,
    enumerable: !0,
    configurable: !0,
    writable: !0
  }) : o[e] = r, o;
}
function p(o) {
  for (var e = 1; e < arguments.length; e++) {
    var r = arguments[e] != null ? arguments[e] : {}, s = Object.keys(r);
    typeof Object.getOwnPropertySymbols == "function" && (s = s.concat(Object.getOwnPropertySymbols(r).filter(function(t) {
      return Object.getOwnPropertyDescriptor(r, t).enumerable;
    }))), s.forEach(function(t) {
      w(o, t, r[t]);
    });
  }
  return o;
}
class F {
  profile() {
    var e, r;
    return {
      sourcePreviewNodes: this.sourcePreviewNodes.size,
      sourcePreviewNodeOptions: this.sourcePreviewNodeOptions.size,
      sourceNodeOptions: this.sourceNodeOptions.size,
      sourceNodes: this.sourceNodes.size,
      dragStartSourceIds: ((e = this.dragStartSourceIds) === null || e === void 0 ? void 0 : e.length) || 0,
      dropTargetIds: this.dropTargetIds.length,
      dragEnterTargetIds: this.dragEnterTargetIds.length,
      dragOverTargetIds: ((r = this.dragOverTargetIds) === null || r === void 0 ? void 0 : r.length) || 0
    };
  }
  get window() {
    return this.options.window;
  }
  get document() {
    return this.options.document;
  }
  get rootElement() {
    return this.options.rootElement;
  }
  setup() {
    const e = this.rootElement;
    if (e !== void 0) {
      if (e.__isReactDndBackendSetUp)
        throw new Error("Cannot have two HTML5 backends at the same time.");
      e.__isReactDndBackendSetUp = !0, this.addEventListeners(e);
    }
  }
  teardown() {
    const e = this.rootElement;
    if (e !== void 0 && (e.__isReactDndBackendSetUp = !1, this.removeEventListeners(this.rootElement), this.clearCurrentDragSourceNode(), this.asyncEndDragFrameId)) {
      var r;
      (r = this.window) === null || r === void 0 || r.cancelAnimationFrame(this.asyncEndDragFrameId);
    }
  }
  connectDragPreview(e, r, s) {
    return this.sourcePreviewNodeOptions.set(e, s), this.sourcePreviewNodes.set(e, r), () => {
      this.sourcePreviewNodes.delete(e), this.sourcePreviewNodeOptions.delete(e);
    };
  }
  connectDragSource(e, r, s) {
    this.sourceNodes.set(e, r), this.sourceNodeOptions.set(e, s);
    const t = (a) => this.handleDragStart(a, e), i = (a) => this.handleSelectStart(a);
    return r.setAttribute("draggable", "true"), r.addEventListener("dragstart", t), r.addEventListener("selectstart", i), () => {
      this.sourceNodes.delete(e), this.sourceNodeOptions.delete(e), r.removeEventListener("dragstart", t), r.removeEventListener("selectstart", i), r.setAttribute("draggable", "false");
    };
  }
  connectDropTarget(e, r) {
    const s = (a) => this.handleDragEnter(a, e), t = (a) => this.handleDragOver(a, e), i = (a) => this.handleDrop(a, e);
    return r.addEventListener("dragenter", s), r.addEventListener("dragover", t), r.addEventListener("drop", i), () => {
      r.removeEventListener("dragenter", s), r.removeEventListener("dragover", t), r.removeEventListener("drop", i);
    };
  }
  addEventListeners(e) {
    !e.addEventListener || (e.addEventListener("dragstart", this.handleTopDragStart), e.addEventListener("dragstart", this.handleTopDragStartCapture, !0), e.addEventListener("dragend", this.handleTopDragEndCapture, !0), e.addEventListener("dragenter", this.handleTopDragEnter), e.addEventListener("dragenter", this.handleTopDragEnterCapture, !0), e.addEventListener("dragleave", this.handleTopDragLeaveCapture, !0), e.addEventListener("dragover", this.handleTopDragOver), e.addEventListener("dragover", this.handleTopDragOverCapture, !0), e.addEventListener("drop", this.handleTopDrop), e.addEventListener("drop", this.handleTopDropCapture, !0));
  }
  removeEventListeners(e) {
    !e.removeEventListener || (e.removeEventListener("dragstart", this.handleTopDragStart), e.removeEventListener("dragstart", this.handleTopDragStartCapture, !0), e.removeEventListener("dragend", this.handleTopDragEndCapture, !0), e.removeEventListener("dragenter", this.handleTopDragEnter), e.removeEventListener("dragenter", this.handleTopDragEnterCapture, !0), e.removeEventListener("dragleave", this.handleTopDragLeaveCapture, !0), e.removeEventListener("dragover", this.handleTopDragOver), e.removeEventListener("dragover", this.handleTopDragOverCapture, !0), e.removeEventListener("drop", this.handleTopDrop), e.removeEventListener("drop", this.handleTopDropCapture, !0));
  }
  getCurrentSourceNodeOptions() {
    const e = this.monitor.getSourceId(), r = this.sourceNodeOptions.get(e);
    return p({
      dropEffect: this.altKeyPressed ? "copy" : "move"
    }, r || {});
  }
  getCurrentDropEffect() {
    return this.isDraggingNativeItem() ? "copy" : this.getCurrentSourceNodeOptions().dropEffect;
  }
  getCurrentSourcePreviewNodeOptions() {
    const e = this.monitor.getSourceId(), r = this.sourcePreviewNodeOptions.get(e);
    return p({
      anchorX: 0.5,
      anchorY: 0.5,
      captureDraggingState: !1
    }, r || {});
  }
  isDraggingNativeItem() {
    const e = this.monitor.getItemType();
    return Object.keys(f).some(
      (r) => f[r] === e
    );
  }
  beginDragNativeItem(e, r) {
    this.clearCurrentDragSourceNode(), this.currentNativeSource = L(e, r), this.currentNativeHandle = this.registry.addSource(e, this.currentNativeSource), this.actions.beginDrag([
      this.currentNativeHandle
    ]);
  }
  setCurrentDragSourceNode(e) {
    this.clearCurrentDragSourceNode(), this.currentDragSourceNode = e;
    const r = 1e3;
    this.mouseMoveTimeoutTimer = setTimeout(() => {
      var s;
      return (s = this.rootElement) === null || s === void 0 ? void 0 : s.addEventListener("mousemove", this.endDragIfSourceWasRemovedFromDOM, !0);
    }, r);
  }
  clearCurrentDragSourceNode() {
    if (this.currentDragSourceNode) {
      if (this.currentDragSourceNode = null, this.rootElement) {
        var e;
        (e = this.window) === null || e === void 0 || e.clearTimeout(this.mouseMoveTimeoutTimer || void 0), this.rootElement.removeEventListener("mousemove", this.endDragIfSourceWasRemovedFromDOM, !0);
      }
      return this.mouseMoveTimeoutTimer = null, !0;
    }
    return !1;
  }
  handleDragStart(e, r) {
    e.defaultPrevented || (this.dragStartSourceIds || (this.dragStartSourceIds = []), this.dragStartSourceIds.unshift(r));
  }
  handleDragEnter(e, r) {
    this.dragEnterTargetIds.unshift(r);
  }
  handleDragOver(e, r) {
    this.dragOverTargetIds === null && (this.dragOverTargetIds = []), this.dragOverTargetIds.unshift(r);
  }
  handleDrop(e, r) {
    this.dropTargetIds.unshift(r);
  }
  constructor(e, r, s) {
    this.sourcePreviewNodes = /* @__PURE__ */ new Map(), this.sourcePreviewNodeOptions = /* @__PURE__ */ new Map(), this.sourceNodes = /* @__PURE__ */ new Map(), this.sourceNodeOptions = /* @__PURE__ */ new Map(), this.dragStartSourceIds = null, this.dropTargetIds = [], this.dragEnterTargetIds = [], this.currentNativeSource = null, this.currentNativeHandle = null, this.currentDragSourceNode = null, this.altKeyPressed = !1, this.mouseMoveTimeoutTimer = null, this.asyncEndDragFrameId = null, this.dragOverTargetIds = null, this.lastClientOffset = null, this.hoverRafId = null, this.getSourceClientOffset = (t) => {
      const i = this.sourceNodes.get(t);
      return i && O(i) || null;
    }, this.endDragNativeItem = () => {
      !this.isDraggingNativeItem() || (this.actions.endDrag(), this.currentNativeHandle && this.registry.removeSource(this.currentNativeHandle), this.currentNativeHandle = null, this.currentNativeSource = null);
    }, this.isNodeInDocument = (t) => Boolean(t && this.document && this.document.body && this.document.body.contains(t)), this.endDragIfSourceWasRemovedFromDOM = () => {
      const t = this.currentDragSourceNode;
      t == null || this.isNodeInDocument(t) || this.clearCurrentDragSourceNode() && this.monitor.isDragging() && this.actions.endDrag();
    }, this.handleTopDragStartCapture = () => {
      this.clearCurrentDragSourceNode(), this.dragStartSourceIds = [];
    }, this.handleTopDragStart = (t) => {
      if (t.defaultPrevented)
        return;
      const { dragStartSourceIds: i } = this;
      this.dragStartSourceIds = null;
      const a = h(t);
      this.monitor.isDragging() && this.actions.endDrag(), this.actions.beginDrag(i || [], {
        publishSource: !1,
        getSourceClientOffset: this.getSourceClientOffset,
        clientOffset: a
      });
      const { dataTransfer: n } = t, d = c(n);
      if (this.monitor.isDragging()) {
        if (n && typeof n.setDragImage == "function") {
          const u = this.monitor.getSourceId(), l = this.sourceNodes.get(u), g = this.sourcePreviewNodes.get(u) || l;
          if (g) {
            const { anchorX: m, anchorY: T, offsetX: E, offsetY: N } = this.getCurrentSourcePreviewNodeOptions(), v = I(l, g, a, {
              anchorX: m,
              anchorY: T
            }, {
              offsetX: E,
              offsetY: N
            });
            n.setDragImage(g, v.x, v.y);
          }
        }
        try {
          n == null || n.setData("application/json", {});
        } catch {
        }
        this.setCurrentDragSourceNode(t.target);
        const { captureDraggingState: D } = this.getCurrentSourcePreviewNodeOptions();
        D ? this.actions.publishDragSource() : setTimeout(
          () => this.actions.publishDragSource(),
          0
        );
      } else if (d)
        this.beginDragNativeItem(d);
      else {
        if (n && !n.types && (t.target && !t.target.hasAttribute || !t.target.hasAttribute("draggable")))
          return;
        t.preventDefault();
      }
    }, this.handleTopDragEndCapture = () => {
      this.clearCurrentDragSourceNode() && this.monitor.isDragging() && this.actions.endDrag();
    }, this.handleTopDragEnterCapture = (t) => {
      if (this.dragEnterTargetIds = [], this.isDraggingNativeItem()) {
        var i;
        (i = this.currentNativeSource) === null || i === void 0 || i.loadDataTransfer(t.dataTransfer);
      }
      if (!this.enterLeaveCounter.enter(t.target) || this.monitor.isDragging())
        return;
      const { dataTransfer: n } = t, d = c(n);
      d && this.beginDragNativeItem(d, n);
    }, this.handleTopDragEnter = (t) => {
      const { dragEnterTargetIds: i } = this;
      if (this.dragEnterTargetIds = [], !this.monitor.isDragging())
        return;
      this.altKeyPressed = t.altKey, i.length > 0 && this.actions.hover(i, {
        clientOffset: h(t)
      }), i.some(
        (n) => this.monitor.canDropOnTarget(n)
      ) && (t.preventDefault(), t.dataTransfer && (t.dataTransfer.dropEffect = this.getCurrentDropEffect()));
    }, this.handleTopDragOverCapture = (t) => {
      if (this.dragOverTargetIds = [], this.isDraggingNativeItem()) {
        var i;
        (i = this.currentNativeSource) === null || i === void 0 || i.loadDataTransfer(t.dataTransfer);
      }
    }, this.handleTopDragOver = (t) => {
      const { dragOverTargetIds: i } = this;
      if (this.dragOverTargetIds = [], !this.monitor.isDragging()) {
        t.preventDefault(), t.dataTransfer && (t.dataTransfer.dropEffect = "none");
        return;
      }
      this.altKeyPressed = t.altKey, this.lastClientOffset = h(t), this.hoverRafId === null && typeof requestAnimationFrame < "u" && (this.hoverRafId = requestAnimationFrame(() => {
        this.monitor.isDragging() && this.actions.hover(i || [], {
          clientOffset: this.lastClientOffset
        }), this.hoverRafId = null;
      })), (i || []).some(
        (n) => this.monitor.canDropOnTarget(n)
      ) ? (t.preventDefault(), t.dataTransfer && (t.dataTransfer.dropEffect = this.getCurrentDropEffect())) : this.isDraggingNativeItem() ? t.preventDefault() : (t.preventDefault(), t.dataTransfer && (t.dataTransfer.dropEffect = "none"));
    }, this.handleTopDragLeaveCapture = (t) => {
      this.isDraggingNativeItem() && t.preventDefault(), !!this.enterLeaveCounter.leave(t.target) && this.isDraggingNativeItem() && setTimeout(
        () => this.endDragNativeItem(),
        0
      );
    }, this.handleTopDropCapture = (t) => {
      if (this.dropTargetIds = [], this.isDraggingNativeItem()) {
        var i;
        t.preventDefault(), (i = this.currentNativeSource) === null || i === void 0 || i.loadDataTransfer(t.dataTransfer);
      } else
        c(t.dataTransfer) && t.preventDefault();
      this.enterLeaveCounter.reset();
    }, this.handleTopDrop = (t) => {
      const { dropTargetIds: i } = this;
      this.dropTargetIds = [], this.actions.hover(i, {
        clientOffset: h(t)
      }), this.actions.drop({
        dropEffect: this.getCurrentDropEffect()
      }), this.isDraggingNativeItem() ? this.endDragNativeItem() : this.monitor.isDragging() && this.actions.endDrag();
    }, this.handleSelectStart = (t) => {
      const i = t.target;
      typeof i.dragDrop == "function" && (i.tagName === "INPUT" || i.tagName === "SELECT" || i.tagName === "TEXTAREA" || i.isContentEditable || (t.preventDefault(), i.dragDrop()));
    }, this.options = new C(r, s), this.actions = e.getActions(), this.monitor = e.getMonitor(), this.registry = e.getRegistry(), this.enterLeaveCounter = new S(this.isNodeInDocument);
  }
}
export {
  F as HTML5BackendImpl
};
//# sourceMappingURL=HTML5BackendImpl.es.js.map
