var _globalObject$documen, _MouseDrag;
import { globalObject } from '@skbkontur/global-object';
var MouseDragEventType = /*#__PURE__*/function (MouseDragEventType) {
  MouseDragEventType["Start"] = "mousedragstart";
  MouseDragEventType["Move"] = "mousedragmove";
  MouseDragEventType["End"] = "mousedragend";
  MouseDragEventType["Leave"] = "mousedragleave";
  return MouseDragEventType;
}(MouseDragEventType || {});
var items = new Map();
var documentHandleMouseUp = function documentHandleMouseUp(e) {
  return items.forEach(function (mouseDrag) {
    return mouseDrag.handleMouseUp(e);
  });
};
(_globalObject$documen = globalObject.document) == null || _globalObject$documen.documentElement.addEventListener('mouseup', documentHandleMouseUp);

/**
 * ## Класс для отслеживания эффекта перетаскивания мышкой
 *
 * _Публичный метод `handleMouseUp` нельзя использовать!_
 *
 * ### Начало прослушивания и добавление обработчиков:
 * ```
 *   MouseDrag.listen(HTMLElement_1)
 *     .onMouseDragStart(start)
 *     .onMouseDragMove(move)
 *     .onMouseDragLeave(leave)
 *     .onMouseDragEnd(end);
 *
 * - - ИЛИ - -
 *
 *  const mouseDrag_1 = MouseDrag.listen(HTMLElement)...
 * ```
 *
 * ### Остановка прослушивания:
 * ```
 *   MouseDrag.stop(HTMLElement_1)
 *
 * - - ИЛИ - -
 *
 *   mouseDrag_1.stop();
 * ```
 */
export var MouseDrag = function MouseDrag(elem) {
  var _this = this;
  this.clicked = false;
  this.dragging = false;
  this.stop = function () {
    if (_this.elem !== null) {
      _this.elem.removeEventListener('mousedown', _this.handleMouseDown);
      _this.elem.removeEventListener('mousemove', _this.handleMouseMove);
      _this.elem.removeEventListener('mouseleave', _this.handleMouseLeave);
      items["delete"](_this.elem);
    }
    _this.elem = null;
  };
  this.onMouseDragStart = function (handler) {
    return _this.on(MouseDragEventType.Start, handler);
  };
  this.onMouseDragMove = function (handler) {
    return _this.on(MouseDragEventType.Move, handler);
  };
  this.onMouseDragLeave = function (handler) {
    return _this.on(MouseDragEventType.Leave, handler);
  };
  this.onMouseDragEnd = function (handler) {
    return _this.on(MouseDragEventType.End, handler);
  };
  this.handleMouseUp = function (e) {
    _this.clicked = false;
    if (_this.dragging) {
      _this.dragging = false;
      _this.dispatchEvent(_this.createEvent(MouseDragEventType.End, e));
    }
  };
  this.on = function (type, handler) {
    if (_this.elem !== null) {
      _this.elem.removeEventListener(type, handler);
      _this.elem.addEventListener(type, handler);
    }
    return _this;
  };
  this.handleMouseDown = function (e) {
    if (!_this.clicked) {
      _this.clicked = true;
      _this.x1 = e.pageX;
      _this.y1 = e.pageY;
      _this.mouseDragStartEvent = _this.createEvent(MouseDragEventType.Start, e);
    }
  };
  this.handleMouseMove = function (e) {
    if (_this.dragging) {
      return _this.dispatchEvent(_this.createEvent(MouseDragEventType.Move, e));
    }
    if (_this.clicked && _this.getLength(e.pageX, e.pageY) > MouseDrag.RADIUS) {
      _this.dragging = true;
      _this.clicked = false;
      if (_this.mouseDragStartEvent) {
        _this.dispatchEvent(_this.mouseDragStartEvent);
      }
    }
  };
  this.handleMouseLeave = function (e) {
    if (_this.dragging) {
      _this.dispatchEvent(_this.createEvent(MouseDragEventType.Leave, e));
    }
  };
  this.getLength = function (x2, y2) {
    if (_this.x1 !== undefined && _this.y1 !== undefined) {
      return Math.sqrt(Math.pow(x2 - _this.x1, 2) + Math.pow(y2 - _this.y1, 2));
    }
    return 0;
  };
  this.createEvent = function (type, e) {
    var _globalObject$documen2;
    if (typeof globalObject.MouseEvent === 'function') {
      return new globalObject.MouseEvent(type, e);
    }
    // <=IE11
    var eIE11 = (_globalObject$documen2 = globalObject.document) == null ? void 0 : _globalObject$documen2.createEvent('MouseEvent');
    if (eIE11) {
      eIE11.initEvent(type, true, true);
      return eIE11;
    }
  };
  this.dispatchEvent = function (mouseDragEvent) {
    if (mouseDragEvent && _this.elem !== null) {
      _this.elem.dispatchEvent(mouseDragEvent);
    }
  };
  this.elem = elem;
  this.elem.addEventListener('mousedown', this.handleMouseDown);
  this.elem.addEventListener('mousemove', this.handleMouseMove);
  this.elem.addEventListener('mouseleave', this.handleMouseLeave);
  items.set(this.elem, this);
};
_MouseDrag = MouseDrag; // Радиус окружности, который необходимо преодолеть мышью, чтобы вызвалось событие `MouseDragStart`
MouseDrag.RADIUS = 5; // px
MouseDrag.listen = function (elem) {
  if (items.has(elem)) {
    var mouseDrag = items.get(elem);
    if (mouseDrag) {
      return mouseDrag;
    }
  }
  return new _MouseDrag(elem);
};
MouseDrag.stop = function (elem) {
  if (elem && items.has(elem)) {
    var mouseDrag = items.get(elem);
    if (mouseDrag) {
      mouseDrag.stop();
    }
  }
};