import { closest, event } from "../../../../min-dom/dist/index.esm.mjs";
import { getStepSize, cap } from "./ZoomUtil.mjs";
import { log10 } from "../../util/Math.mjs";
import { bind } from "../../../../min-dash/dist/index.esm.mjs";
var sign = Math.sign || function(n) {
  return n >= 0 ? 1 : -1;
};
var RANGE = { min: 0.2, max: 4 }, NUM_STEPS = 10;
var DELTA_THRESHOLD = 0.1;
var DEFAULT_SCALE = 0.75;
function ZoomScroll(config, eventBus, canvas) {
  config = config || {};
  this._enabled = false;
  this._canvas = canvas;
  this._container = canvas._container;
  this._handleWheel = bind(this._handleWheel, this);
  this._totalDelta = 0;
  this._scale = config.scale || DEFAULT_SCALE;
  var self = this;
  eventBus.on("canvas.init", function(e) {
    self._init(config.enabled !== false);
  });
}
ZoomScroll.$inject = [
  "config.zoomScroll",
  "eventBus",
  "canvas"
];
ZoomScroll.prototype.scroll = function scroll(delta) {
  this._canvas.scroll(delta);
};
ZoomScroll.prototype.reset = function reset() {
  this._canvas.zoom("fit-viewport");
};
ZoomScroll.prototype.zoom = function zoom(delta, position) {
  var stepSize = getStepSize(RANGE, NUM_STEPS * 2);
  this._totalDelta += delta;
  if (Math.abs(this._totalDelta) > DELTA_THRESHOLD) {
    this._zoom(delta, position, stepSize);
    this._totalDelta = 0;
  }
};
ZoomScroll.prototype._handleWheel = function handleWheel(event2) {
  if (closest(event2.target, ".djs-scrollable", true)) {
    return;
  }
  var element = this._container;
  event2.preventDefault();
  var isZoom = event2.ctrlKey;
  var isHorizontalScroll = event2.shiftKey;
  var factor = -1 * this._scale, delta;
  if (isZoom) {
    factor *= event2.deltaMode === 0 ? 0.02 : 0.32;
  } else {
    factor *= event2.deltaMode === 0 ? 1 : 16;
  }
  if (isZoom) {
    var elementRect = element.getBoundingClientRect();
    var offset = {
      x: event2.clientX - elementRect.left,
      y: event2.clientY - elementRect.top
    };
    delta = Math.sqrt(
      Math.pow(event2.deltaY, 2) + Math.pow(event2.deltaX, 2)
    ) * sign(event2.deltaY) * factor;
    this.zoom(delta, offset);
  } else {
    if (isHorizontalScroll) {
      delta = {
        dx: factor * event2.deltaY,
        dy: 0
      };
    } else {
      delta = {
        dx: factor * event2.deltaX,
        dy: factor * event2.deltaY
      };
    }
    this.scroll(delta);
  }
};
ZoomScroll.prototype.stepZoom = function stepZoom(delta, position) {
  var stepSize = getStepSize(RANGE, NUM_STEPS);
  this._zoom(delta, position, stepSize);
};
ZoomScroll.prototype._zoom = function(delta, position, stepSize) {
  var canvas = this._canvas;
  var direction = delta > 0 ? 1 : -1;
  var currentLinearZoomLevel = log10(canvas.zoom());
  var newLinearZoomLevel = Math.round(currentLinearZoomLevel / stepSize) * stepSize;
  newLinearZoomLevel += stepSize * direction;
  var newLogZoomLevel = Math.pow(10, newLinearZoomLevel);
  canvas.zoom(cap(RANGE, newLogZoomLevel), position);
};
ZoomScroll.prototype.toggle = function toggle(newEnabled) {
  var element = this._container;
  var handleWheel2 = this._handleWheel;
  var oldEnabled = this._enabled;
  if (typeof newEnabled === "undefined") {
    newEnabled = !oldEnabled;
  }
  if (oldEnabled !== newEnabled) {
    event[newEnabled ? "bind" : "unbind"](element, "wheel", handleWheel2, false);
  }
  this._enabled = newEnabled;
  return newEnabled;
};
ZoomScroll.prototype._init = function(newEnabled) {
  this.toggle(newEnabled);
};
export {
  ZoomScroll as default
};
