"use strict";

exports.__esModule = true;
exports.getBasesToShow = getBasesToShow;
var _react = _interopRequireDefault(require("react"));
var _lodash = require("lodash");
var _constants = require("../constants");
var _getYOffset = _interopRequireDefault(require("../../CircularView/getYOffset"));
var _rangeUtils = require("@teselagen/range-utils");
var _getStructuredBases2 = require("./getStructuredBases");
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 getBasesToShow(_ref) {
  var hidePrimerBases = _ref.hidePrimerBases,
    annotation = _ref.annotation,
    annotationRange = _ref.annotationRange,
    charWidth = _ref.charWidth,
    bpsPerRow = _ref.bpsPerRow,
    fullSequence = _ref.fullSequence,
    iTree = _ref.iTree,
    sequenceLength = _ref.sequenceLength;
  if (hidePrimerBases) return {};
  var basesToShow = {};
  if (annotation && annotation.bases) {
    var fudge = charWidth - _constants.realCharWidth;
    var forward = annotation.forward,
      primerBindsOn = annotation.primerBindsOn;
    var _getStructuredBases = (0, _getStructuredBases2.getStructuredBases)(_extends({}, annotation, {
        fullSequence: fullSequence,
        annotationRange: annotationRange,
        sequenceLength: sequenceLength
      })),
      basesNoInsertsWithMetaData = _getStructuredBases.basesNoInsertsWithMetaData,
      inserts = _getStructuredBases.inserts,
      aRange = _getStructuredBases.aRange;
    var annLen = (0, _rangeUtils.getRangeLength)(annotation, sequenceLength);
    var aRangeLen = (0, _rangeUtils.getRangeLength)(annotationRange, sequenceLength);
    var startOffset = annotationRange.start % bpsPerRow;
    var endOffset = bpsPerRow - annotationRange.end % bpsPerRow;
    basesToShow.insertPaths = "";
    basesToShow.insertTicks = "";
    basesToShow.flipAnnotation = !forward;
    basesToShow.extraHeight = 0;
    var insertText = [];
    var level1Height = -10;
    var level2Height = 11;
    inserts.forEach(function (i, n) {
      //loop thru all inserts
      var indexToUse = forward ? i.index : annLen - i.index - 1;
      if (aRange.start - (primerBindsOn === "5prime" ? 1 : 0) <= indexToUse && aRange.end + (primerBindsOn === "5prime" ? 1 : 0) >= indexToUse) {
        //only draw if insert falls within the annotation range
        var xStart = i.index - aRange.start - Math.ceil(0.5 * i.bases.length); //calculate initial xStart
        var xEnd = i.index - aRange.start + Math.floor(0.5 * i.bases.length);
        if (aRange.end + 3 < xEnd) {
          xStart -= xEnd - aRange.end - 3;
          xEnd -= xEnd - aRange.end - 3;
        }
        if (i.index === 0) {
          //for the first chunk, try to make it hang off the end if possible
          xStart -= xEnd - 1;
          xEnd -= xEnd - 1;
        }
        var forwAnd3Prime = forward;
        if (xStart < -(forwAnd3Prime ? startOffset : endOffset)) {
          //if the xStart is going to fall off the row to the left, correct it by moving the xStart to the right
          var offsetLeft = -(forwAnd3Prime ? startOffset : endOffset) - xStart;
          xStart += offsetLeft;
          xEnd += offsetLeft;
        } else if (xEnd + (forwAnd3Prime ? startOffset : endOffset) > bpsPerRow) {
          //if the xStart is going to fall off the row to the right, correct it by moving the xStart to the left
          var _offsetLeft = bpsPerRow - xEnd - (forwAnd3Prime ? startOffset : endOffset);
          xStart += _offsetLeft;
          xEnd += _offsetLeft;
        }
        // use an interval tree to determine the level the primer insert should be on to not overlap with other inserts
        var yOffset = (0, _getYOffset["default"])(iTree, xStart, xEnd);
        iTree.insert(xStart, xEnd, _extends({}, annotationRange, {
          yOffset: yOffset
        }));
        basesToShow.extraHeight = Math.max(basesToShow.extraHeight, 15 + yOffset * 20);
        var insertStart = (indexToUse - (forward ? aRange.start : aRange.end)) * (!forward && primerBindsOn === "5prime" ? -1 : 1);
        basesToShow.insertPaths += getInsertPath({
          xStart: xStart,
          xEnd: xEnd,
          charWidth: charWidth,
          level: yOffset,
          insertStart: insertStart
        });
        if (indexToUse !== aRange.end + 1 && indexToUse !== -1) {
          basesToShow.insertTicks += getInsertTick({
            charWidth: charWidth,
            height: level2Height,
            insertStart: insertStart
          });
        }
        var _textLength = charWidth * i.bases.length - fudge - _constants.fudge2;
        insertText.push( /*#__PURE__*/_react["default"].createElement("text", {
          style: {
            pointerEvents: "none"
          },
          "data-insert-bases": i.bases,
          className: "ve-monospace-font tg-primer-bases-insert",
          textLength: _textLength,
          transform: forward ? "" : "translate(" + aRangeLen * charWidth + ",-5) scale(-1,-1) ",
          key: n,
          x: forward ? (xStart - 1) * charWidth + fudge : xStart * charWidth - fudge / 2,
          y: level1Height - yOffset * 20 - (forward ? 0 : 5)
        }, i.bases.split("").map(function (b, i) {
          return /*#__PURE__*/_react["default"].createElement("tspan", {
            key: i,
            rotate: forward ? 0 : 180,
            className: "tg-no-match-seq",
            textLength: _textLength
          }, b);
        })));
      }
    });
    var textLength = charWidth * basesNoInsertsWithMetaData.length - fudge - _constants.fudge2;
    basesToShow.baseEl = /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement("text", {
      textLength: textLength,
      y: forward ? level2Height : -(basesToShow.extraHeight - 5),
      x: forward ? fudge / 2 : fudge / 2 + 0.2 /* + diffLen * charWidth */,

      style: {
        pointerEvents: "none"
      },
      className: "ve-monospace-font tg-primer-bases"
    }, (0, _lodash.map)(basesNoInsertsWithMetaData, function (_ref2, i) {
      var b = _ref2.b,
        isMatch = _ref2.isMatch,
        isAmbiguousMatch = _ref2.isAmbiguousMatch;
      return /*#__PURE__*/_react["default"].createElement("tspan", {
        key: i,
        className: b === "&" ? "tg-no-show-seq" : isMatch ? "" : isAmbiguousMatch ? "tg-ambiguous-match-seq" : "tg-no-match-seq",
        textLength: textLength
      }, b);
    })), insertText);
  }
  return basesToShow;
}
function getInsertTick(_ref3) {
  var insertStart = _ref3.insertStart,
    charWidth = _ref3.charWidth,
    height = _ref3.height;
  if (insertStart === 0) return "";
  var insertLocation = insertStart * charWidth;
  var jutUp = "\n  L " + (insertLocation - 1) + "," + (height + 5) + "\n  L " + (insertLocation - 1) + "," + (height - 4) + "\n  L " + (insertLocation - 1) + "," + (height + 5) + "\n   ";
  return jutUp;
}
function getInsertPath(_ref4) {
  var charWidth = _ref4.charWidth,
    xStart = _ref4.xStart,
    xEnd = _ref4.xEnd,
    insertStart = _ref4.insertStart,
    _ref4$level = _ref4.level,
    level = _ref4$level === void 0 ? 0 : _ref4$level;
  var insertLocation = insertStart * charWidth;
  var insertHeight = 15;
  var levelHeight = -5 - level * 20;
  var leftX = (xStart - 1) * charWidth;
  var rightX = (xEnd - 1) * charWidth;
  var jutUp = "\n   L " + (insertLocation - 6) + "," + 0 + "\n   L " + (insertLocation - 6) + "," + levelHeight + "\n   L " + leftX + "," + levelHeight + "\n   L " + leftX + "," + (-insertHeight + levelHeight) + "\n\n   L " + rightX + "," + (-insertHeight + levelHeight) + "\n   L " + rightX + "," + levelHeight + "\n   L " + (insertLocation + 4) + "," + levelHeight + "\n   L " + (insertLocation + 4) + "," + 0 + "\n   ";
  return jutUp;
}