"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.setColor = setColor;
exports.toggleMark = toggleMark;

var _util = require("../../util");

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }

function setColor(editor, type, color) {
  var state = editor.state; //@ts-ignore

  var _state$selection = state.selection,
      empty = _state$selection.empty,
      $cursor = _state$selection.$cursor,
      ranges = _state$selection.ranges,
      from = _state$selection.from,
      to = _state$selection.to;
  if (empty && !$cursor || !markApplies(state.doc, ranges, type)) return false;

  if ($cursor) {
    if (type.isInSet(state.storedMarks || $cursor.marks() || !color)) editor.view.dispatch(state.tr.removeStoredMark(type));else editor.view.dispatch(state.tr.addStoredMark(type.create({
      color: color
    })));
    return true;
  }

  var tr = state.tr;

  if (!color) {
    tr.removeMark(state.selection.from, state.selection.to, type);
  } else {
    var isShared = (0, _util.isSharedMark)(editor, from, to, type, {
      color: color
    });
    tr.removeMark(state.selection.from, state.selection.to, type);
    if (!isShared) tr.addMark(from, to, type.create({
      color: color
    }));
  }

  editor.view.dispatch(tr.scrollIntoView());
  editor.view.focus();
  return true;
}

function markApplies(doc, ranges, type) {
  var _loop = function _loop(i) {
    var _ranges$i = ranges[i],
        $from = _ranges$i.$from,
        $to = _ranges$i.$to;
    var can = $from.depth == 0 ? doc.type.allowsMarkType(type) : false;
    doc.nodesBetween($from.pos, $to.pos, function (node) {
      if (can) return false;
      can = node.inlineContent && node.type.allowsMarkType(type);
    });
    if (can) return {
      v: true
    };
  };

  for (var i = 0; i < ranges.length; i++) {
    var _ret = _loop(i);

    if (_typeof(_ret) === "object") return _ret.v;
  }

  return false;
}

function toggleMark(markType, attrs) {
  return function (state, dispatch) {
    var _state$selection2 = state.selection,
        empty = _state$selection2.empty,
        $cursor = _state$selection2.$cursor,
        ranges = _state$selection2.ranges;
    if (empty && !$cursor || !markApplies(state.doc, ranges, markType)) return false;

    if (dispatch) {
      if ($cursor) {
        if (markType.isInSet(state.storedMarks || $cursor.marks())) dispatch(state.tr.removeStoredMark(markType));else dispatch(state.tr.addStoredMark(markType.create(attrs)));
      } else {
        var has = false,
            tr = state.tr;

        for (var i = 0; !has && i < ranges.length; i++) {
          var _ranges$i2 = ranges[i],
              $from = _ranges$i2.$from,
              $to = _ranges$i2.$to;
          has = state.doc.rangeHasMark($from.pos, $to.pos, markType);
        }

        for (var _i = 0; _i < ranges.length; _i++) {
          var _ranges$_i = ranges[_i],
              _$from = _ranges$_i.$from,
              _$to = _ranges$_i.$to;

          if (has) {
            tr.removeMark(_$from.pos, _$to.pos, markType);
          } else {
            var _$exec, _$exec2;

            var from = _$from.pos,
                to = _$to.pos,
                start = _$from.nodeAfter,
                end = _$to.nodeBefore;
            var spaceStart = start && start.isText ? ((_$exec = /^\s*/.exec(start.text)) === null || _$exec === void 0 ? void 0 : _$exec[0].length) || 0 : 0;
            var spaceEnd = end && end.isText ? ((_$exec2 = /\s*$/.exec(end.text)) === null || _$exec2 === void 0 ? void 0 : _$exec2[0].length) || 0 : 0;

            if (from + spaceStart < to) {
              from += spaceStart;
              to -= spaceEnd;
            }

            tr.addMark(from, to, markType.create(attrs));
          }
        }

        dispatch(tr.scrollIntoView());
      }
    }

    return true;
  };
}