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 _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); }
import React from "react";
import { onlyUpdateForKeys } from "recompose";
import withHover from "../helperComponents/withHover";
import getXStartAndWidthOfRowAnnotation from "./getXStartAndWidthOfRowAnnotation";
import IntervalTree from "node-interval-tree";
import getYOffset from "../CircularView/getYOffset";
import { reduce, values, startCase, filter, clamp } from "lodash";
import { getRangeLength } from "@teselagen/range-utils";
import { doesLabelFitInAnnotation } from "./utils";
import getAnnotationNameAndStartStopString from "../utils/getAnnotationNameAndStartStopString";
var BUFFER_WIDTH = 6; //labels shouldn't be less than 6px from eachother on the same line

function Labels(props) {
  var _props$annotationRang = props.annotationRanges,
    annotationRanges = _props$annotationRang === void 0 ? {} : _props$annotationRang,
    bpsPerRow = props.bpsPerRow,
    charWidth = props.charWidth,
    rangeMax = props.rangeMax,
    onlyShowLabelsThatDoNotFit = props.onlyShowLabelsThatDoNotFit,
    annotationHeight = props.annotationHeight,
    _props$textWidth = props.textWidth,
    textWidth = _props$textWidth === void 0 ? 6 : _props$textWidth,
    editorName = props.editorName,
    labelLineIntensity = props.labelLineIntensity,
    isProtein = props.isProtein,
    noRedux = props.noRedux,
    readOnly = props.readOnly,
    noLabelLine = props.noLabelLine;
  if (annotationRanges.length === 0) {
    return null;
  }
  var warningMessage = null;
  // if (Object.keys(annotationRanges).length > 50) {
  //   warningMessage = (
  //     <span style={{ color: "red" }}>
  //       <br />
  //       Warning: Only the first 50 cutsites will be displayed. Filter the
  //       cutsites you wish to see using the filter tool <br />
  //     </span>
  //   );
  // }

  var rowLength = bpsPerRow * charWidth;
  // let counter = 0;
  var maxAnnotationYOffset = 0;
  var annotationsSVG = [];
  var rowCenter = rowLength / 2;
  var iTree = new IntervalTree(rowCenter);
  annotationRanges = values(reduce(annotationRanges, function (accum, annotationRange) {
    var identifier = annotationRange.annotation.annotationTypePlural + "--" + annotationRange.id;
    if (
    // annotationRange.annotation.annotationTypePlural === "parts" ||
    !accum[identifier] || getRangeLength(accum[identifier], rangeMax) < getRangeLength(annotationRange, rangeMax)) {
      accum[identifier] = annotationRange;
      return accum;
    } else {
      return accum;
    }
  }, {}));
  filter(annotationRanges, function (r) {
    if (onlyShowLabelsThatDoNotFit) {
      //tnrtodo: more work needs to be done here to make this actually configurable
      //check if annotation name will fit
      if (r.annotation.annotationTypePlural === "cutsites" || r.annotation.annotationTypePlural === "primers" && r.annotation.bases) {
        //we don't want to filter out any cutsite labels
        return true;
      }
      return !doesLabelFitInAnnotation(r.annotation.name, {
        range: r
      }, charWidth);
    }
    return true;
  }).forEach(function (annotationRange, index) {
    var pluralType = annotationRange.annotation.annotationTypePlural;
    var annotation = annotationRange.annotation;
    if (!annotation) {
      annotation = annotationRange;
    }
    var annotationLength = (annotation.name || annotation.restrictionEnzyme && annotation.restrictionEnzyme.name || "").length * textWidth;
    var _getXStartAndWidthOfR = getXStartAndWidthOfRowAnnotation(annotationRange, bpsPerRow, charWidth),
      xStart = _getXStartAndWidthOfR.xStart,
      width = _getXStartAndWidthOfR.width;
    xStart = annotation.annotationTypePlural === "cutsites" ? xStart : xStart + width / 2;
    var xStartOriginal = xStart;
    var xEnd = xStart + annotationLength;
    if (xEnd > rowLength) {
      xStart = xStart - (xEnd - rowLength);
      xEnd = rowLength;
    }
    xEnd += BUFFER_WIDTH;
    var yOffset = getYOffset(iTree, xStart, xEnd);
    iTree.insert(xStart, xEnd, _extends({}, annotationRange, {
      yOffset: yOffset
    }));
    if (yOffset > maxAnnotationYOffset) {
      maxAnnotationYOffset = yOffset;
    }
    var height = yOffset * annotationHeight;
    annotationsSVG.push( /*#__PURE__*/React.createElement(DrawLabel, {
      id: annotation.id,
      key: "cutsiteLabel" + index,
      readOnly: readOnly,
      editorName: editorName,
      annotation: annotation,
      noLabelLine: noLabelLine,
      className: (annotationRange.annotation.labelClassName || "") + " " + labelClassNames[pluralType] + " veLabel ",
      isProtein: isProtein,
      xStartOriginal: xStartOriginal,
      onClick: annotationRange.onClick,
      onDoubleClick: annotationRange.onDoubleClick,
      onRightClick: annotationRange.onRightClick,
      height: height,
      xStart: xStart,
      xEnd: xEnd,
      textWidth: textWidth,
      labelLineIntensity: labelLineIntensity,
      noRedux: noRedux
    }));
  });
  if (!annotationsSVG.length) return null;
  var containerHeight = (maxAnnotationYOffset + 1) * annotationHeight;
  return /*#__PURE__*/React.createElement("div", {
    width: "100%",
    style: {
      position: "relative",
      height: containerHeight,
      display: "block"
    },
    className: "veRowViewLabelsContainer"
  }, annotationsSVG, warningMessage);
}
export default onlyUpdateForKeys(["annotationRanges", "bpsPerRow", "charWidth", "annotationHeight", "spaceBetweenAnnotations", "onClick", "onRightClick", "onDoubleClick", "textWidth", "editorName"])(Labels);
var DrawLabel = withHover( /*#__PURE__*/function (_React$Component) {
  _inheritsLoose(DrawLabelInner, _React$Component);
  function DrawLabelInner() {
    return _React$Component.apply(this, arguments) || this;
  }
  var _proto = DrawLabelInner.prototype;
  _proto.render = function render() {
    var _this = this;
    var _this$props = this.props,
      hovered = _this$props.hovered,
      className = _this$props.className,
      annotation = _this$props.annotation,
      _onClick = _this$props.onClick,
      noLabelLine = _this$props.noLabelLine,
      _onDoubleClick = _this$props.onDoubleClick,
      onRightClick = _this$props.onRightClick,
      height = _this$props.height,
      xStartOriginal = _this$props.xStartOriginal,
      xStart = _this$props.xStart,
      onMouseLeave = _this$props.onMouseLeave,
      isProtein = _this$props.isProtein,
      onMouseOver = _this$props.onMouseOver,
      editorName = _this$props.editorName,
      labelLineIntensity = _this$props.labelLineIntensity,
      textWidth = _this$props.textWidth,
      readOnly = _this$props.readOnly;
    var heightToUse = height;
    var bottom = 0;
    if (hovered) {
      try {
        var line = this.n;
        var isRowView = document.querySelector(".veEditor." + editorName + " .veRowView").contains(line);
        var el = line.closest(".veRowItem").querySelector(annotation.annotationTypePlural === "cutsites" ? isRowView ? ".cutsiteLabelSelectionLayer" : ".veRowViewAxis" : "[data-id=\"" + annotation.id + "\"].veRowView" + startCase(annotation.annotationTypePlural.slice(0, -1)));
        var annDims = el.getBoundingClientRect();
        var lineDims = line.getBoundingClientRect();
        var heightDiff = annDims.bottom - lineDims.bottom - annDims.height / 2;
        heightToUse = height + heightDiff;
        bottom = -heightDiff;
      } catch (e) {
        window.veDebugLabels && console.error("err computing label line:", e);
      }
    }
    var truncateLabelIfNeeded = function truncateLabelIfNeeded(annotationText, xLeftCoord) {
      var numberOfCharsToChop = xLeftCoord < 0 ? Math.ceil(Math.abs(xLeftCoord) / textWidth) + 2 : 0;
      return numberOfCharsToChop > 0 ? annotationText.slice(0, -numberOfCharsToChop) + ".." : annotationText;
    };
    var titleText = getAnnotationNameAndStartStopString(annotation, {
      isProtein: isProtein,
      readOnly: readOnly
    });
    var labelText = annotation.name || annotation.restrictionEnzyme.name;
    return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
      onMouseLeave: onMouseLeave,
      onMouseOver: onMouseOver,
      className: className + " veLabelText ve-monospace-font",
      onClick: function onClick(event) {
        _onClick && _onClick({
          event: event,
          annotation: annotation
        });
        event.stopPropagation();
      },
      onDoubleClick: function onDoubleClick(event) {
        if (_onDoubleClick) {
          _onDoubleClick({
            event: event,
            annotation: annotation
          });
          event.stopPropagation();
        }
      },
      onContextMenu: function onContextMenu(event) {
        onRightClick({
          event: event,
          annotation: annotation
        });
        event.stopPropagation();
      },
      title: titleText,
      style: _extends({
        cursor: "pointer",
        position: "absolute",
        bottom: height
      }, hovered && {
        textDecoration: "underline"
      }, annotation.annotationTypePlural !== "cutsites" && {
        fontStyle: "normal"
      }, {
        left: clamp(xStart, 0, Number.MAX_VALUE),
        whiteSpace: "nowrap",
        color: annotation.annotationTypePlural === "parts" ? "#ac68cc" : annotation.labelColor,
        zIndex: 10
      })
    }, truncateLabelIfNeeded(labelText, xStart)), !noLabelLine && /*#__PURE__*/React.createElement("div", {
      ref: function ref(n) {
        if (n) _this.n = n;
      },
      className: "veLabelLine",
      style: {
        zIndex: 50,
        position: "absolute",
        left: xStartOriginal,
        bottom: bottom,
        height: Math.max(heightToUse, 3),
        width: hovered ? 2 : 1,
        opacity: hovered ? 1 : labelLineIntensity
        // background: "black"
      }
    }));
  };
  return DrawLabelInner;
}(React.Component));
var labelClassNames = {
  cutsites: "veCutsiteLabel",
  parts: "vePartLabel",
  features: "veFeatureLabel"
};