"use strict";

exports.__esModule = true;
exports["default"] = createSequenceInputPopup;
var _reactDom = require("react-dom");
var _rangeUtils = require("@teselagen/range-utils");
var _popper = _interopRequireDefault(require("popper.js"));
var _sequenceUtils = require("@teselagen/sequence-utils");
var _react = _interopRequireDefault(require("react"));
var _proteinUtils = require("../utils/proteinUtils");
require("./createSequenceInputPopupStyle.css");
var _core = require("@blueprintjs/core");
var _editorUtils = require("../utils/editorUtils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
var div;
var SequenceInputNoHotkeys = /*#__PURE__*/function (_React$Component) {
  _inheritsLoose(SequenceInputNoHotkeys, _React$Component);
  function SequenceInputNoHotkeys() {
    var _this;
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
    _defineProperty(_assertThisInitialized(_this), "state", {
      charsToInsert: "",
      hasTempError: false
    });
    _defineProperty(_assertThisInitialized(_this), "handleUnmountIfClickOustidePopup", function (e) {
      var n = (0, _reactDom.findDOMNode)(_assertThisInitialized(_this));
      if (!n) return;
      var node = n.parentNode;
      if (!node) return;
      if (node.contains(e.target)) {
        return;
      }
      _this.handleUnmount();
    });
    _defineProperty(_assertThisInitialized(_this), "handleUnmount", function () {
      setTimeout(function () {
        var n = (0, _reactDom.findDOMNode)(_assertThisInitialized(_this));
        if (!n) return;
        var node = n.parentNode;
        if (!node) return;
        (0, _reactDom.unmountComponentAtNode)(node);
        _this.props.nodeToReFocus && _this.props.nodeToReFocus.focus();
        document.getElementById("sequenceInputBubble").outerHTML = "";
      });
    });
    return _this;
  }
  var _proto = SequenceInputNoHotkeys.prototype;
  _proto.componentDidMount = function componentDidMount() {
    document.addEventListener("mousedown", this.handleUnmountIfClickOustidePopup);
  };
  _proto.componentWillUnmount = function componentWillUnmount() {
    document.removeEventListener("mousedown", this.handleUnmountIfClickOustidePopup);
  };
  _proto.handleInsert = function handleInsert() {
    var _this$props = this.props,
      _this$props$handleIns = _this$props.handleInsert,
      handleInsert = _this$props$handleIns === void 0 ? function () {} : _this$props$handleIns,
      isProtein = _this$props.isProtein;
    var charsToInsert = this.state.charsToInsert;
    if (!charsToInsert.length) {
      return;
    }
    var seqToInsert = isProtein ? {
      proteinSequence: charsToInsert
    } : {
      sequence: charsToInsert
    };
    handleInsert(seqToInsert);
  };
  _proto.render = function render() {
    var _this2 = this;
    var _this$props2 = this.props,
      isReplace = _this$props2.isReplace,
      selectionLayer = _this$props2.selectionLayer,
      sequenceLength = _this$props2.sequenceLength,
      isProtein = _this$props2.isProtein,
      replaceChars = _this$props2.replaceChars,
      caretPosition = _this$props2.caretPosition,
      acceptedChars = _this$props2.acceptedChars,
      maxInsertSize = _this$props2.maxInsertSize;
    var _this$state = this.state,
      charsToInsert = _this$state.charsToInsert,
      hasTempError = _this$state.hasTempError;
    var message;
    if (isReplace) {
      var betweenVals = (0, _sequenceUtils.getInsertBetweenVals)(-1, selectionLayer, sequenceLength);
      message = /*#__PURE__*/_react["default"].createElement("span", null, "Press ", /*#__PURE__*/_react["default"].createElement("span", {
        style: {
          fontWeight: "bolder"
        }
      }, "ENTER"), " to replace", " ", (0, _proteinUtils.divideBy3)((0, _rangeUtils.getRangeLength)(selectionLayer, sequenceLength), isProtein), " ", isProtein ? "AAs" : "base pairs", " between", " ", isProtein ? (0, _sequenceUtils.convertDnaCaretPositionOrRangeToAA)(betweenVals[0]) : betweenVals[0], " ", "and", " ", isProtein ? (0, _sequenceUtils.convertDnaCaretPositionOrRangeToAA)(betweenVals[1] + 2) : betweenVals[1]);
    } else {
      message = /*#__PURE__*/_react["default"].createElement("span", null, "Press ", /*#__PURE__*/_react["default"].createElement("span", {
        style: {
          fontWeight: "bolder"
        }
      }, "ENTER"), " to insert", " ", charsToInsert.length, " ", isProtein ? "AAs" : "base pairs", " after", " ", isProtein ? "AA" : "base", " ", isProtein ? (0, _sequenceUtils.convertDnaCaretPositionOrRangeToAA)(caretPosition) : caretPosition);
    }
    return /*#__PURE__*/_react["default"].createElement("div", {
      className: "sequenceInputBubble"
    }, /*#__PURE__*/_react["default"].createElement("input", {
      autoCorrect: "off",
      onKeyDown: function onKeyDown(e) {
        if (e.keyCode === 27) {
          _this2.handleUnmount();
        }
        if (e.keyCode === 13) {
          _this2.handleInsert();
          _this2.handleUnmount();
        }
      },
      className: _core.Classes.INPUT,
      value: charsToInsert,
      autoFocus: true,
      style: hasTempError ? {
        borderColor: "red"
      } : {},
      onChange: function onChange(e) {
        var sanitizedVal = "";
        e.target.value.split("").forEach(function (letter) {
          var lowerLetter = letter.toLowerCase();
          if (replaceChars && replaceChars[lowerLetter]) {
            var isUpper = lowerLetter !== letter;
            sanitizedVal += isUpper ? replaceChars[lowerLetter].toUpperCase() : replaceChars[lowerLetter];
          } else if (acceptedChars.includes(lowerLetter)) {
            sanitizedVal += letter;
          }
        });
        if (e.target.value.length !== sanitizedVal.length) {
          _this2.setState({
            hasTempError: true
          });
          setTimeout(function () {
            _this2.setState({
              hasTempError: false
            });
          }, 200);
        }
        if (maxInsertSize && sanitizedVal.lenth > maxInsertSize) {
          return window.toastr.error("Sorry, your insert is greater than ", maxInsertSize);
        }
        e.target.value = sanitizedVal;
        _this2.setState({
          charsToInsert: sanitizedVal
        });
      }
    }), /*#__PURE__*/_react["default"].createElement("div", {
      style: {
        marginTop: 10
      }
    }, message), /*#__PURE__*/_react["default"].createElement("div", {
      style: {
        marginTop: 10
      }
    }, "Press ", /*#__PURE__*/_react["default"].createElement("span", {
      style: {
        fontWeight: "bolder"
      }
    }, "ESC"), " to", " ", /*#__PURE__*/_react["default"].createElement("button", {
      className: "link-button",
      onClick: this.handleUnmount
    }, "cancel")));
  };
  return SequenceInputNoHotkeys;
}(_react["default"].Component);
function createSequenceInputPopup(props) {
  var useEventPositioning = props.useEventPositioning;
  var caretEl;
  if (useEventPositioning) {
    //we have to make a fake event here so that popper.js will position on the page correctly
    var e = useEventPositioning.e,
      nodeToReFocus = useEventPositioning.nodeToReFocus;
    // e.persist();
    var top = e.clientY;
    var right = e.clientX;
    var bottom = e.clientY;
    var left = e.clientX;
    caretEl = {
      nodeToRefocus: nodeToReFocus,
      getBoundingClientRect: function getBoundingClientRect() {
        return {
          top: top,
          right: right,
          bottom: bottom,
          left: left
        };
      },
      clientWidth: 0,
      clientHeight: 0
    };
  }
  if (!caretEl || !caretEl === 0 || !isElementInViewport(caretEl)) {
    var activeEl = getActiveElement();
    if (activeEl) {
      caretEl = activeEl.querySelector(".veCaret");
    }
  }
  if (!caretEl || !caretEl === 0 || !isElementInViewport(caretEl)) {
    caretEl = getActiveElement();
  }
  if (!caretEl || !caretEl === 0 || !isElementInViewport(caretEl)) {
    caretEl = document.querySelector(".veCaret");
  }
  if (document.body.classList.contains("sequenceDragging")) {
    window.toastr.warning("Can't insert new sequence while dragging");
    //don't allow this
    return;
  }

  // function closeInput() {
  //   sequenceInputBubble.remove();
  // }
  div = document.createElement("div");
  div.style.zIndex = "400000";
  div.id = "sequenceInputBubble";
  document.body.appendChild(div);
  var innerEl = /*#__PURE__*/_react["default"].createElement(SequenceInputNoHotkeys, _extends({
    nodeToReFocus: caretEl.nodeToRefocus || (0, _editorUtils.getNodeToRefocus)(caretEl)
  }, props));
  (0, _reactDom.render)(innerEl, div);
  if (!caretEl) {
    return console.error("there must be a caret element present in order to display the insertSequence popup");
  }
  new _popper["default"](caretEl, div, {
    placement: "bottom",
    modifiers: {
      offset: {
        offset: "94"
      }
    }
  });
}
var getActiveElement = function getActiveElement(document) {
  document = document || window.document;

  // Check if the active element is in the main web or iframe
  if (document.body === document.activeElement || /* eslint-disable eqeqeq*/

  document.activeElement.tagName == "IFRAME"
  /* eslint-enable eqeqeq*/) {
    // Get iframes
    var iframes = document.getElementsByTagName("iframe");
    for (var i = 0; i < iframes.length; i++) {
      // Recall
      var focused = getActiveElement(iframes[i].contentWindow.document);
      if (focused !== false) {
        return focused; // The focused
      }
    }
  } else return document.activeElement;
  return false;
};
function isElementInViewport(el) {
  var rect = el.getBoundingClientRect();
  return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) /*or $(window).height() */ && rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */;
}
module.exports = exports.default;