var _excluded = ["startAngle", "endAngle", "totalAngle", "centerAngle", "locationAngles"];
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
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 IntervalTree from "node-interval-tree";
import { sortBy, noop } from "lodash";
import { getRangeLength } from "@teselagen/range-utils";
import getRangeAngles from "./getRangeAnglesSpecial";
import getYOffset from "./getYOffset";
import withHover from "../helperComponents/withHover";
import PositionAnnotationOnCircle from "./PositionAnnotationOnCircle";
import getAnnotationNameAndStartStopString from "../utils/getAnnotationNameAndStartStopString";
import Feature from "./Feature";
import getAnnotationClassnames from "../utils/getAnnotationClassnames";
// import { normalizeAngleRange } from "./normalizeAngleRange";
// import { normalizeAngle } from "./normalizeAngle";

//annotations coming in can be positioned either by caretPosition or range
function drawAnnotations(props) {
  var readOnly = props.readOnly,
    annotationType = props.annotationType,
    radius = props.radius,
    noHover = props.noHover,
    isProtein = props.isProtein,
    type = props.type,
    annotations = props.annotations,
    annotationHeight = props.annotationHeight,
    noTitle = props.noTitle,
    spaceBetweenAnnotations = props.spaceBetweenAnnotations,
    sequenceLength = props.sequenceLength,
    showCicularViewInternalLabels = props.showCicularViewInternalLabels,
    getColor = props.getColor,
    useStartAngle = props.useStartAngle,
    _props$onClick = props.onClick,
    onClick = _props$onClick === void 0 ? noop : _props$onClick,
    noHeight = props.noHeight,
    positionBy = props.positionBy,
    allOnSameLevel = props.allOnSameLevel,
    _props$onRightClicked = props.onRightClicked,
    onRightClicked = _props$onRightClicked === void 0 ? noop : _props$onRightClicked,
    _props$onDoubleClick = props.onDoubleClick,
    onDoubleClick = _props$onDoubleClick === void 0 ? noop : _props$onDoubleClick,
    showLabels = props.showLabels,
    hideAnnotation = props.hideAnnotation,
    labelOptions = props.labelOptions,
    annotationProps = props.annotationProps,
    fontStyle = props.fontStyle;
  var totalAnnotationHeight = annotationHeight + spaceBetweenAnnotations;
  var featureITree = new IntervalTree();
  var maxYOffset = 0;
  var svgGroup = [];
  var labels = {};
  if (!Object.keys(annotations).length) return null;
  sortBy(annotations, function (a) {
    return -getRangeLength(a, sequenceLength);
  }).map(function (annotation) {
    var _getRangeAngles = getRangeAngles(positionBy ? positionBy(annotation) : annotation, sequenceLength),
      startAngle = _getRangeAngles.startAngle,
      endAngle = _getRangeAngles.endAngle,
      totalAngle = _getRangeAngles.totalAngle,
      centerAngle = _getRangeAngles.centerAngle,
      locationAngles = _getRangeAngles.locationAngles;
    var spansOrigin = startAngle > endAngle;
    var annotationCopy = _extends({}, annotation, {
      startAngle: startAngle,
      endAngle: endAngle,
      locationAngles: locationAngles,
      totalAngle: totalAngle,
      centerAngle: centerAngle,
      yOffset: 0
    });
    if (!allOnSameLevel) {
      //expand the end angle if annotation spans the origin
      var expandedEndAngle = spansOrigin ? endAngle + 2 * Math.PI : endAngle;
      var yOffset1;
      var yOffset2;
      if (spansOrigin) {
        annotationCopy.yOffset = getYOffset(featureITree, startAngle, expandedEndAngle);
      } else {
        //we need to check both locations to account for annotations that span the origin
        yOffset1 = getYOffset(featureITree, startAngle, expandedEndAngle);
        yOffset2 = getYOffset(featureITree, startAngle + Math.PI * 2, expandedEndAngle + Math.PI * 2);
        annotationCopy.yOffset = Math.max(yOffset1, yOffset2);
      }
      if (spansOrigin) {
        featureITree.insert(startAngle, expandedEndAngle, _extends({}, annotationCopy));
      } else {
        //normal feature
        // we need to add it twice to the interval tree to accomodate features which span the origin
        featureITree.insert(startAngle, expandedEndAngle, _extends({}, annotationCopy));
        featureITree.insert(startAngle + 2 * Math.PI, expandedEndAngle + 2 * Math.PI, _extends({}, annotationCopy));
      }
      if (annotationCopy.yOffset > maxYOffset) {
        maxYOffset = annotationCopy.yOffset;
      }
    }
    return annotationCopy;
  }).forEach(function (annotation, index) {
    annotation.yOffset = maxYOffset - annotation.yOffset;
    function _onClick(event) {
      onClick && onClick({
        event: event,
        annotation: annotation
      });
      annotation.onClick && annotation.onClick({
        event: event,
        annotation: annotation
      });
    }
    function onContextMenu(event) {
      onRightClicked({
        event: event,
        annotation: annotation
      });
      if (annotation.onRightClick) {
        annotation.onRightClick({
          event: event,
          annotation: annotation
        });
      }
    }
    function _onDoubleClick(event) {
      onDoubleClick && onDoubleClick({
        event: event,
        annotation: annotation
      });
      if (annotation.onDoubleClick) {
        annotation.onDoubleClick({
          event: event,
          annotation: annotation
        });
      }
    }
    var startAngle = annotation.startAngle,
      endAngle = annotation.endAngle,
      totalAngle = annotation.totalAngle,
      centerAngle = annotation.centerAngle,
      locationAngles = annotation.locationAngles,
      rest = _objectWithoutPropertiesLoose(annotation, _excluded);
    var _annotationProps = _extends({}, annotationProps, rest);
    var titleText = getAnnotationNameAndStartStopString(annotation, {
      isProtein: isProtein,
      readOnly: readOnly
    });
    var classNames = getAnnotationClassnames(annotation, {
      viewName: "CircularView",
      type: type,
      isProtein: isProtein,
      readOnly: readOnly
    });
    var annotationRadius = radius + annotation.yOffset * totalAnnotationHeight;
    var name = annotation.name || annotation.restrictionEnzyme && annotation.restrictionEnzyme.name;
    var ellipsizedName;
    // let spaceBeforeName = 0;
    var angleAdjust;
    if (name && showCicularViewInternalLabels) {
      // eslint-disable-next-line no-inner-declarations
      var getEllipsizedName = function getEllipsizedName(totalAngle) {
        var ellipsizedName;
        var arcLength = 2 * Math.PI * (annotationRadius - annotationHeight) * totalAngle; //for arrowhead

        var annLength = Math.max(0, Math.floor(arcLength / 55 - 3));
        ellipsizedName = name.slice(0, annLength);
        if (ellipsizedName && ellipsizedName !== name) {
          if (ellipsizedName.length >= name.length - 2) {
            ellipsizedName = name;
          } else if (ellipsizedName.length > 3) {
            ellipsizedName += "..";
          } else {
            ellipsizedName = undefined;
          }
        }
        return ellipsizedName;
      };
      if (locationAngles) {
        annotation.locationAngles = locationAngles.map(function (l) {
          var _ellipsizedName;
          var en = getEllipsizedName(l.totalAngle);
          if ((en === null || en === void 0 ? void 0 : en.length) > (((_ellipsizedName = ellipsizedName) === null || _ellipsizedName === void 0 ? void 0 : _ellipsizedName.length) || 0)) {
            ellipsizedName = en;
          }
          return _extends({}, l, {
            ellipsizedName: en
          });
        });
      } else {
        ellipsizedName = getEllipsizedName(totalAngle);
      }

      // //tnr: WIP to try to adjust the inline label in the circular view to always show up even when zoomed in
      // if (ellipsizedName && isZoomedIn) {
      //   const nameAngle =
      //     ((ellipsizedName.length + 3) * 55) /
      //     (2 * Math.PI * (annotationRadius - annotationHeight));
      //   const maxAngleAdjust = (totalAngle - nameAngle) / 2;
      //   const idealAngle = normalizeAngle(
      //     -normalizeAngle(rotationRadians) - normalizeAngle(centerAngle)
      //   );
      //   angleAdjust = idealAngle;
      //   if (
      //     Math.min(maxAngleAdjust, idealAngle) !== idealAngle
      //     // &&
      //     // Math.min(maxAngleAdjust, 2 * Math.PI - idealAngle) !==
      //     //   2 * Math.PI - idealAngle
      //   ) {
      //     angleAdjust = -maxAngleAdjust;
      //     if (
      //       normalizeAngle(
      //         normalizeAngle(centerAngle) + normalizeAngle(rotationRadians)
      //       ) > Math.PI
      //     ) {
      //       angleAdjust = -angleAdjust;
      //     }
      //   }
      //   // angleAdjust =idealAngle
      //   angleAdjust = (angleAdjust / Math.PI) * 180;
      //   // if (normalizeAngle(normalizeAngle(centerAngle) + normalizeAngle(rotationRadians)) > Math.PI) {
      //   //   angleAdjust = -angleAdjust;
      //   // }
      // }
    }

    if (showLabels && !ellipsizedName) {
      //add labels to the exported label array (to be drawn by the label component)
      labels[annotation.id] = _extends({
        annotation: annotation,
        annotationType: annotationType,
        annotationCenterAngle: useStartAngle ? startAngle : centerAngle,
        annotationCenterRadius: annotationRadius,
        text: name,
        id: annotation.id,
        title: titleText,
        className: classNames + " " + (annotation.labelClassName || ""),
        highPriorityLabel: annotation.highPriorityLabel,
        onClick: _onClick,
        onDoubleClick: _onDoubleClick,
        fontStyle: fontStyle || "normal",
        color: annotation.labelColor || (annotationType === "part" ? "#ac68cc" : "black"),
        onContextMenu: onContextMenu
      }, labelOptions);
    }
    if (!hideAnnotation) {
      var annotationColor = getColor ? getColor(annotation) : annotation.color || "#ac68cc";
      DrawAnnotation.displayName = annotationType + "--- DrawAnnotation";
      var CompToUse = noHover ? DrawAnnotationInner : DrawAnnotation;
      svgGroup.push( /*#__PURE__*/React.createElement(CompToUse, _extends({}, _extends({}, props, rest, annotation, {
        angleAdjust: angleAdjust,
        ellipsizedName: ellipsizedName,
        name: name,
        annotationHeight: annotationHeight,
        annotationRadius: annotationRadius,
        annotationType: annotationType,
        isProtein: isProtein,
        noTitle: noTitle,
        titleText: titleText,
        classNames: classNames,
        onClick: _onClick,
        onDoubleClick: _onDoubleClick,
        onContextMenu: onContextMenu,
        annotation: annotation,
        annotationColor: annotationColor,
        totalAngle: totalAngle,
        centerAngle: centerAngle,
        annotationProps: _annotationProps
      }), {
        id: annotation.id,
        key: "veAnnotation-" + annotationType + index
      })));
    }
  });
  return {
    component: /*#__PURE__*/React.createElement("g", {
      className: "veAnnotations-" + annotationType,
      key: "veAnnotations-" + annotationType
    }, svgGroup),
    height: noHeight ? 0 : maxYOffset * totalAnnotationHeight + 0.5 * annotationHeight,
    labels: labels
  };
}
export default drawAnnotations;
function DrawAnnotationInner(_ref) {
  var className = _ref.className,
    startAngle = _ref.startAngle,
    endAngle = _ref.endAngle,
    onClick = _ref.onClick,
    onDoubleClick = _ref.onDoubleClick,
    onContextMenu = _ref.onContextMenu,
    titleText = _ref.titleText,
    classNames = _ref.classNames,
    locationAngles = _ref.locationAngles,
    annotation = _ref.annotation,
    reverseAnnotations = _ref.reverseAnnotations,
    _ref$Annotation = _ref.Annotation,
    Annotation = _ref$Annotation === void 0 ? Feature : _ref$Annotation,
    totalAngle = _ref.totalAngle,
    annotationColor = _ref.annotationColor,
    isProtein = _ref.isProtein,
    annotationRadius = _ref.annotationRadius,
    annotationHeight = _ref.annotationHeight,
    onMouseLeave = _ref.onMouseLeave,
    onMouseOver = _ref.onMouseOver,
    annotationType = _ref.annotationType,
    annotationProps = _ref.annotationProps,
    addHeight = _ref.addHeight,
    noTitle = _ref.noTitle,
    useCenter = _ref.useCenter,
    centerAngle = _ref.centerAngle,
    perAnnotationProps = _ref.perAnnotationProps,
    passAnnotation = _ref.passAnnotation,
    ellipsizedName = _ref.ellipsizedName,
    angleAdjust = _ref.angleAdjust,
    rotationRadians = _ref.rotationRadians;
  var sharedProps = {
    style: noTitle ? undefined : {
      cursor: "pointer"
    },
    className: className + " " + classNames,
    onContextMenu: onContextMenu,
    onClick: onClick,
    onDoubleClick: onDoubleClick,
    onMouseLeave: onMouseLeave,
    onMouseOver: onMouseOver
  };
  var title = /*#__PURE__*/React.createElement("title", null, titleText);
  function getInner(_ref2, i) {
    var startAngle = _ref2.startAngle,
      endAngle = _ref2.endAngle,
      totalAngle = _ref2.totalAngle,
      isNotLocation = _ref2.isNotLocation,
      containsLocations = _ref2.containsLocations,
      ellipsizedNameLocation = _ref2.ellipsizedName;
    var _PositionAnnotationOn = PositionAnnotationOnCircle({
        sAngle: useCenter ? centerAngle : startAngle,
        eAngle: useCenter ? centerAngle : endAngle,
        height: addHeight ? annotationRadius : undefined,
        forward: reverseAnnotations ? !annotation.forward : annotation.forward
      }),
      transform = _PositionAnnotationOn.transform,
      revTransform = _PositionAnnotationOn.revTransform;
    return /*#__PURE__*/React.createElement("g", _extends({
      transform: transform,
      key: isNotLocation ? "notLocation" : "location--" + annotation.id + "--" + i
      // {...(ellipsizedName && ellipsizedName !== name
      //   ? { "data-tip": name }
      //   : {})}
    }, sharedProps), noTitle ? null : title, /*#__PURE__*/React.createElement(Annotation, _extends({}, passAnnotation && {
      annotation: annotation
    }, {
      annotationType: annotationType,
      arrowheadType: annotation.arrowheadType,
      totalAngle: totalAngle,
      centerAngle: centerAngle,
      revTransform: revTransform,
      rotationRadians: rotationRadians,
      ellipsizedName: containsLocations ? ellipsizedNameLocation : ellipsizedName,
      locationNumber: i,
      angleAdjust: angleAdjust,
      color: annotationColor,
      isProtein: isProtein,
      containsLocations: containsLocations,
      radius: annotationRadius,
      annotationHeight: annotationHeight
    }, annotationProps, perAnnotationProps && perAnnotationProps(annotation))));
  }
  return /*#__PURE__*/React.createElement(React.Fragment, null, getInner({
    startAngle: startAngle,
    endAngle: endAngle,
    totalAngle: totalAngle,
    centerAngle: centerAngle,
    containsLocations: !!locationAngles
  }), locationAngles && locationAngles.map(getInner));
}
var DrawAnnotation = withHover(DrawAnnotationInner);