import { addPointerEvent as m } from "../../events/add-pointer-event.es.js";
import { extractEventInfo as D } from "../../events/event-info.es.js";
import { distance2D as R } from "../../utils/distance.es.js";
import { frameData as y, frame as x, cancelFrame as k } from "../../../../../../../motion-dom@12.38.0/node_modules/motion-dom/dist/es/frameloop/frame.es.js";
import { isPrimaryPointer as U } from "../../../../../../../motion-dom@12.38.0/node_modules/motion-dom/dist/es/gestures/utils/is-primary-pointer.es.js";
import { pipe as X } from "../../../../../../../motion-utils@12.36.0/node_modules/motion-utils/dist/es/pipe.es.js";
import { secondsToMilliseconds as S, millisecondsToSeconds as Y } from "../../../../../../../motion-utils@12.36.0/node_modules/motion-utils/dist/es/time-conversion.es.js";
const M = /* @__PURE__ */ new Set(["auto", "scroll"]);
class z {
  constructor(t, s, { transformPagePoint: i, contextWindow: r = window, dragSnapToOrigin: o = !1, distanceThreshold: l = 3, element: u } = {}) {
    if (this.startEvent = null, this.lastMoveEvent = null, this.lastMoveEventInfo = null, this.lastRawMoveEventInfo = null, this.handlers = {}, this.contextWindow = window, this.scrollPositions = /* @__PURE__ */ new Map(), this.removeScrollListeners = null, this.onElementScroll = (e) => {
      this.handleScroll(e.target);
    }, this.onWindowScroll = () => {
      this.handleScroll(window);
    }, this.updatePoint = () => {
      if (!(this.lastMoveEvent && this.lastMoveEventInfo))
        return;
      this.lastRawMoveEventInfo && (this.lastMoveEventInfo = v(this.lastRawMoveEventInfo, this.transformPagePoint));
      const e = p(this.lastMoveEventInfo, this.history), a = this.startEvent !== null, c = R(e.offset, { x: 0, y: 0 }) >= this.distanceThreshold;
      if (!a && !c)
        return;
      const { point: f } = e, { timestamp: d } = y;
      this.history.push({ ...f, timestamp: d });
      const { onStart: h, onMove: P } = this.handlers;
      a || (h && h(this.lastMoveEvent, e), this.startEvent = this.lastMoveEvent), P && P(this.lastMoveEvent, e);
    }, this.handlePointerMove = (e, a) => {
      this.lastMoveEvent = e, this.lastRawMoveEventInfo = a, this.lastMoveEventInfo = v(a, this.transformPagePoint), x.update(this.updatePoint, !0);
    }, this.handlePointerUp = (e, a) => {
      this.end();
      const { onEnd: c, onSessionEnd: f, resumeAnimation: d } = this.handlers;
      if ((this.dragSnapToOrigin || !this.startEvent) && d && d(), !(this.lastMoveEvent && this.lastMoveEventInfo))
        return;
      const h = p(e.type === "pointercancel" ? this.lastMoveEventInfo : v(a, this.transformPagePoint), this.history);
      this.startEvent && c && c(e, h), f && f(e, h);
    }, !U(t))
      return;
    this.dragSnapToOrigin = o, this.handlers = s, this.transformPagePoint = i, this.distanceThreshold = l, this.contextWindow = r || window;
    const L = D(t), w = v(L, this.transformPagePoint), { point: T } = w, { timestamp: W } = y;
    this.history = [{ ...T, timestamp: W }];
    const { onSessionStart: E } = s;
    E && E(t, p(w, this.history)), this.removeListeners = X(m(this.contextWindow, "pointermove", this.handlePointerMove), m(this.contextWindow, "pointerup", this.handlePointerUp), m(this.contextWindow, "pointercancel", this.handlePointerUp)), u && this.startScrollTracking(u);
  }
  /**
   * Start tracking scroll on ancestors and window.
   */
  startScrollTracking(t) {
    let s = t.parentElement;
    for (; s; ) {
      const i = getComputedStyle(s);
      (M.has(i.overflowX) || M.has(i.overflowY)) && this.scrollPositions.set(s, {
        x: s.scrollLeft,
        y: s.scrollTop
      }), s = s.parentElement;
    }
    this.scrollPositions.set(window, {
      x: window.scrollX,
      y: window.scrollY
    }), window.addEventListener("scroll", this.onElementScroll, {
      capture: !0
    }), window.addEventListener("scroll", this.onWindowScroll), this.removeScrollListeners = () => {
      window.removeEventListener("scroll", this.onElementScroll, {
        capture: !0
      }), window.removeEventListener("scroll", this.onWindowScroll);
    };
  }
  /**
   * Handle scroll compensation during drag.
   *
   * For element scroll: adjusts history origin since pageX/pageY doesn't change.
   * For window scroll: adjusts lastMoveEventInfo since pageX/pageY would change.
   */
  handleScroll(t) {
    const s = this.scrollPositions.get(t);
    if (!s)
      return;
    const i = t === window, r = i ? { x: window.scrollX, y: window.scrollY } : {
      x: t.scrollLeft,
      y: t.scrollTop
    }, o = { x: r.x - s.x, y: r.y - s.y };
    o.x === 0 && o.y === 0 || (i ? this.lastMoveEventInfo && (this.lastMoveEventInfo.point.x += o.x, this.lastMoveEventInfo.point.y += o.y) : this.history.length > 0 && (this.history[0].x -= o.x, this.history[0].y -= o.y), this.scrollPositions.set(t, r), x.update(this.updatePoint, !0));
  }
  updateHandlers(t) {
    this.handlers = t;
  }
  end() {
    this.removeListeners && this.removeListeners(), this.removeScrollListeners && this.removeScrollListeners(), this.scrollPositions.clear(), k(this.updatePoint);
  }
}
function v(n, t) {
  return t ? { point: t(n.point) } : n;
}
function I(n, t) {
  return { x: n.x - t.x, y: n.y - t.y };
}
function p({ point: n }, t) {
  return {
    point: n,
    delta: I(n, g(t)),
    offset: I(n, O(t)),
    velocity: V(t, 0.1)
  };
}
function O(n) {
  return n[0];
}
function g(n) {
  return n[n.length - 1];
}
function V(n, t) {
  if (n.length < 2)
    return { x: 0, y: 0 };
  let s = n.length - 1, i = null;
  const r = g(n);
  for (; s >= 0 && (i = n[s], !(r.timestamp - i.timestamp > S(t))); )
    s--;
  if (!i)
    return { x: 0, y: 0 };
  i === n[0] && n.length > 2 && r.timestamp - i.timestamp > S(t) * 2 && (i = n[1]);
  const o = Y(r.timestamp - i.timestamp);
  if (o === 0)
    return { x: 0, y: 0 };
  const l = {
    x: (r.x - i.x) / o,
    y: (r.y - i.y) / o
  };
  return l.x === 1 / 0 && (l.x = 0), l.y === 1 / 0 && (l.y = 0), l;
}
export {
  z as PanSession
};
//# sourceMappingURL=PanSession.es.js.map
