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); }
import React from "react";
import { Button, InputGroup, Switch, Popover, Position, HTMLSelect, TextArea, Tooltip } from "@blueprintjs/core";
import withEditorProps from "../withEditorProps";
import { MAX_MATCHES_DISPLAYED } from "../constants/findToolConstants";
import "./style.css";
import { InfoHelper } from "teselagen-react-components";
import { searchableTypes } from "../selectors/annotationSearchSelector";
import { getSingular } from "../utils/annotationTypes";
import { getFeatureToColorMap } from "@teselagen/sequence-utils";
import { getReverseComplementSequenceString } from "@teselagen/sequence-utils";
import isMobile from "is-mobile";
var opts = [{
  label: "DNA",
  value: "DNA"
}, {
  label: "Amino Acids",
  value: "AA"
}];
export var FindBar = /*#__PURE__*/function (_React$Component) {
  _inheritsLoose(FindBar, _React$Component);
  function FindBar() {
    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), "possiblyNormalizeMatchNumber", function () {
      var _this$props = _this.props,
        findTool = _this$props.findTool,
        updateMatchNumber = _this$props.updateMatchNumber;
      if (findTool.matchNumber !== 0 && findTool.matchNumber >= findTool.matchesTotal) {
        updateMatchNumber(0);
      }
    });
    return _this;
  }
  var _proto = FindBar.prototype;
  _proto.componentDidMount = function componentDidMount() {
    this.possiblyNormalizeMatchNumber();
    if (this.inputEl) {
      this.inputEl.select();
    }
  };
  _proto.componentDidUpdate = function componentDidUpdate() {
    this.possiblyNormalizeMatchNumber();
  };
  _proto.render = function render() {
    var _this2 = this;
    var _this$props2 = this.props,
      toggleFindTool = _this$props2.toggleFindTool,
      toggleHighlightAll = _this$props2.toggleHighlightAll,
      toggleIsInline = _this$props2.toggleIsInline,
      updateSearchText = _this$props2.updateSearchText,
      annotationVisibilityShow = _this$props2.annotationVisibilityShow,
      updateAmbiguousOrLiteral = _this$props2.updateAmbiguousOrLiteral,
      updateDnaOrAA = _this$props2.updateDnaOrAA,
      _updateMatchNumber = _this$props2.updateMatchNumber,
      selectionLayerUpdate = _this$props2.selectionLayerUpdate,
      annotationSearchMatches = _this$props2.annotationSearchMatches,
      _this$props2$findTool = _this$props2.findTool,
      findTool = _this$props2$findTool === void 0 ? {} : _this$props2$findTool;
    var searchText = findTool.searchText,
      dnaOrAA = findTool.dnaOrAA,
      highlightAll = findTool.highlightAll,
      ambiguousOrLiteral = findTool.ambiguousOrLiteral,
      _findTool$matchesTota = findTool.matchesTotal,
      matchesTotal = _findTool$matchesTota === void 0 ? 0 : _findTool$matchesTota,
      _findTool$matchNumber = findTool.matchNumber,
      matchNumber = _findTool$matchNumber === void 0 ? 0 : _findTool$matchNumber,
      isInline = findTool.isInline;
    var updateMatchNumber = function updateMatchNumber() {
      for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        args[_key2] = arguments[_key2];
      }
      if (matchesTotal > 1 && !(getReverseComplementSequenceString(searchText) === searchText && matchesTotal === 2)) {
        _updateMatchNumber.apply(void 0, args);
      } else {
        _updateMatchNumber(null);
        setTimeout(function () {
          _updateMatchNumber.apply(void 0, args);
        });
      }
    };
    var findOptionsEls = [/*#__PURE__*/React.createElement(HTMLSelect, {
      key: "dnaoraa",
      options: opts,
      name: "dnaOrAA",
      value: dnaOrAA,
      onChange: function onChange(e) {
        updateDnaOrAA(e.target.value);
      }
    }), /*#__PURE__*/React.createElement("div", {
      style: {
        display: "flex"
      },
      key: "ambiguousorliteral"
    }, /*#__PURE__*/React.createElement(HTMLSelect, {
      name: "ambiguousOrLiteral",
      options: [{
        label: "精确",
        value: "LITERAL"
      }, {
        label: "模糊",
        value: "AMBIGUOUS"
      }],
      value: ambiguousOrLiteral,
      onChange: function onChange(e) {
        updateAmbiguousOrLiteral(e.target.value);
      }
    }), /*#__PURE__*/React.createElement(InfoHelper, {
      style: {
        marginLeft: 10
      }
    }, /*#__PURE__*/React.createElement("div", null, "Ambiguous substitutions:", /*#__PURE__*/React.createElement("div", {
      style: {
        display: "flex",
        fontSize: 12
      }
    }, /*#__PURE__*/React.createElement("div", {
      style: {
        marginRight: 20
      }
    }, /*#__PURE__*/React.createElement("div", {
      style: {
        fontSize: 14,
        marginBottom: 4,
        marginTop: 5
      }
    }, "DNA:"), /*#__PURE__*/React.createElement("div", null, "M: AC"), /*#__PURE__*/React.createElement("div", null, "R: AG"), /*#__PURE__*/React.createElement("div", null, "W: AT"), /*#__PURE__*/React.createElement("div", null, "S: CG"), /*#__PURE__*/React.createElement("div", null, "Y: CT"), /*#__PURE__*/React.createElement("div", null, "K: GT"), /*#__PURE__*/React.createElement("div", null, "V: ACG"), /*#__PURE__*/React.createElement("div", null, "H: ACT"), /*#__PURE__*/React.createElement("div", null, "D: AGT"), /*#__PURE__*/React.createElement("div", null, "B: CGT"), /*#__PURE__*/React.createElement("div", null, "X: GATC"), /*#__PURE__*/React.createElement("div", null, "N: GATC"), /*#__PURE__*/React.createElement("div", null, "*: any")), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
      style: {
        fontSize: 14,
        marginBottom: 4,
        marginTop: 5
      }
    }, "AA:"), /*#__PURE__*/React.createElement("div", null, "B: ND"), /*#__PURE__*/React.createElement("div", null, "J: IL"), /*#__PURE__*/React.createElement("div", null, "X: ACDEFGHIKLMNPQRSTVWY"), /*#__PURE__*/React.createElement("div", null, "Z: QE"), /*#__PURE__*/React.createElement("div", null, "*: any")))))), /*#__PURE__*/React.createElement(Switch, {
      key: "highlightall",
      checked: highlightAll,
      onChange: toggleHighlightAll,
      disabled: matchesTotal > MAX_MATCHES_DISPLAYED
    }, /*#__PURE__*/React.createElement(Tooltip, {
      disabled: matchesTotal <= MAX_MATCHES_DISPLAYED,
      content: "Disabled because there are >{MAX_MATCHES_DISPLAYED} matches"
    }, "\u7A81\u51FA\u663E\u793A\u5168\u90E8"))].concat(isMobile() ? [] : [/*#__PURE__*/React.createElement(Switch, {
      key: "isInline",
      checked: !isInline,
      onChange: toggleIsInline
    }, "\u6269\u5C55")]);
    var InputToUse = !isInline ? TextArea : InputGroup;
    var rightEl = /*#__PURE__*/React.createElement("span", null, isInline && /*#__PURE__*/React.createElement(Popover, {
      autoFocus: false,
      enforceFocus: false,
      position: Position.BOTTOM,
      target: /*#__PURE__*/React.createElement(Button, {
        "data-test": "veFindBarOptionsToggle",
        minimal: true,
        icon: "wrench"
      }),
      content: /*#__PURE__*/React.createElement("div", {
        className: "ve-find-options-popover",
        style: {
          display: "flex",
          flexDirection: "column",
          paddingLeft: 20,
          paddingBottom: 10,
          paddingTop: 10,
          paddingRight: 20
        }
      }, findOptionsEls)
    }), /*#__PURE__*/React.createElement("span", {
      style: {
        marginRight: 3,
        color: "lightgrey"
      }
    }, matchesTotal > 0 ? matchNumber + 1 : 0, "/", matchesTotal), /*#__PURE__*/React.createElement(Button, {
      "data-test": "veFindPreviousMatchButton",
      minimal: true,
      small: true,
      disabled: matchesTotal <= 0,
      onClick: function onClick() {
        updateMatchNumber(matchesTotal <= 0 ? 0 : mod(matchNumber - 1, matchesTotal));
      },
      icon: "caret-up"
    }), /*#__PURE__*/React.createElement(Button, {
      "data-test": "veFindNextMatchButton",
      minimal: true,
      small: true,
      disabled: matchesTotal <= 0,
      onClick: function onClick() {
        updateMatchNumber(matchesTotal <= 0 ? 0 : mod(matchNumber + 1, matchesTotal));
      },
      icon: "caret-down"
    }), isInline && /*#__PURE__*/React.createElement(Button, {
      minimal: true,
      small: true,
      onClick: toggleFindTool,
      icon: "small-cross"
    }));
    return /*#__PURE__*/React.createElement("div", {
      style: isInline ? {
        display: "flex",
        minWidth: 300
      } : {
        position: "fixed",
        top: 0,
        right: 25,
        padding: 10,
        display: "flex",
        alignItems: "center",
        paddingBottom: 5,
        background: "white",
        zIndex: "20000",
        borderBottom: "1px solid lightgrey",
        borderLeft: "1px solid lightgrey",
        borderRight: "1px solid lightgrey",
        borderBottomLeftRadius: "5px",
        borderBottomRightRadius: "5px"
      },
      className: "veFindBar"
    }, /*#__PURE__*/React.createElement(Popover, {
      autoFocus: false,
      enforceFocus: false,
      target: /*#__PURE__*/React.createElement(InputToUse, {
        autoFocus: true,
        style: _extends({
          resize: "vertical"
        }, !isInline && {
          width: 350,
          minHeight: 70
        }),
        className: "tg-find-tool-input",
        inputRef: function inputRef(n) {
          if (n) _this2.inputEl = n;
        },
        onKeyDown: function onKeyDown(e) {
          e.persist();
          if (e.metaKey && e.keyCode === 70) {
            //cmd-f
            // toggleFindTool();
            e.preventDefault();
            e.stopPropagation();
          } else if (e.keyCode === 13) {
            //enter key!
            updateMatchNumber(matchesTotal <= 0 ? 0 : mod(matchNumber + 1, matchesTotal));
            e.stopPropagation();
            e.preventDefault();
          } else if (e.keyCode === 27) {
            //esc key!
            toggleFindTool();
          }
        },
        rightElement: rightEl,
        onChange: function onChange(e) {
          return updateSearchText(e.target.value.replace(/\s/g, ""));
        },
        value: searchText,
        leftIcon: "search"
      }),
      position: "bottom",
      minimal: true,
      isOpen: annotationSearchMatches && annotationSearchMatches.filter(function (m) {
        return m.length;
      }).length,
      content: /*#__PURE__*/React.createElement(AnnotationSearchMatchComp, {
        annotationVisibilityShow: annotationVisibilityShow,
        toggleFindTool: toggleFindTool,
        selectionLayerUpdate: selectionLayerUpdate,
        annotationSearchMatches: annotationSearchMatches
      })
    }), !isInline && /*#__PURE__*/React.createElement("div", {
      style: {
        display: "flex",
        maxWidth: "400px",
        flexWrap: "wrap",
        justifyContent: "space-around",
        alignItems: "stretch",
        height: "76px"
      }
    }, rightEl, findOptionsEls), !isInline && /*#__PURE__*/React.createElement(Button, {
      minimal: true,
      style: {
        position: "absolute",
        bottom: 0,
        right: -10
      },
      onClick: toggleFindTool,
      icon: "cross"
    }));
  };
  return FindBar;
}(React.Component);
export default withEditorProps(FindBar);
function mod(n, m) {
  return (n % m + m) % m;
}
function AnnotationSearchMatchComp(_ref) {
  var annotationSearchMatches = _ref.annotationSearchMatches,
    selectionLayerUpdate = _ref.selectionLayerUpdate,
    annotationVisibilityShow = _ref.annotationVisibilityShow,
    toggleFindTool = _ref.toggleFindTool;
  var toReturn = /*#__PURE__*/React.createElement("div", {
    className: "veAnnotationFindMatches"
  }, searchableTypes.map(function (type, i) {
    var annotationsFound = annotationSearchMatches[i];
    if (!annotationsFound) return null;
    return annotationsFound.length ? /*#__PURE__*/React.createElement("div", {
      key: i
    }, /*#__PURE__*/React.createElement("div", {
      className: "veAnnotationFoundType"
    }, annotationsFound.length, " ", getSingular(type), " match", annotationsFound.length > 1 ? "es" : null, annotationsFound.length <= 10 ? null : " (only showing 10)", ":"), /*#__PURE__*/React.createElement("div", null, annotationsFound.slice(0, 10).map(function (ann, i) {
      return /*#__PURE__*/React.createElement("div", {
        onClick: function onClick() {
          annotationVisibilityShow(type);
          selectionLayerUpdate(ann);
          toggleFindTool();
        },
        className: "veAnnotationFoundResult",
        key: i
      }, /*#__PURE__*/React.createElement("div", {
        style: {
          display: "flex",
          alignItems: "center"
        }
      }, /*#__PURE__*/React.createElement("div", {
        style: {
          background: type === "parts" ? "#ac68cc" : ann.color || getFeatureToColorMap({
            includeHidden: true
          })[ann.type],
          height: 15,
          width: 15,
          marginRight: 3
        }
      }), ann.name), /*#__PURE__*/React.createElement("div", {
        className: "veAnnotationFoundResultRange"
      }, ann.start + 1, "-", ann.end + 1));
    }))) : null;
  }));
  return toReturn;
}