"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.words = exports.sort = exports.sentences = exports.paragraphs = exports.normalize = exports.intersection = exports.handleSentence = void 0;

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));

var _compact = _interopRequireDefault(require("lodash/compact"));

var _parseEnglish = _interopRequireDefault(require("@pie-framework/parse-english"));

var _clone = _interopRequireDefault(require("lodash/clone"));

var g = function g(str, node) {
  if (node.children) {
    return node.children.reduce(g, str);
  } else if (node.value) {
    return str + node.value;
  } else {
    return str;
  }
};

var getParagraph = function getParagraph(p) {
  return g('', p);
};

var getSentence = function getSentence(s) {
  return g('', s);
};

var getWord = function getWord(w) {
  return g('', w);
};

var paragraphs = function paragraphs(text) {
  var tree = new _parseEnglish["default"]().parse(text);
  var out = tree.children.reduce(function (acc, child) {
    if (child.type === 'ParagraphNode') {
      var paragraph = {
        text: getParagraph(child),
        start: child.position.start.offset,
        end: child.position.end.offset
      };
      return acc.concat([paragraph]);
    } else {
      return acc;
    }
  }, []);
  return out;
};

exports.paragraphs = paragraphs;

var handleSentence = function handleSentence(child, acc) {
  var sentenceChilds = []; // we parse the children of the sentence

  var newAcc = child.children.reduce(function (acc, child) {
    // if we find a whitespace node that's \n, we end the sentence
    if (child.type === 'WhiteSpaceNode' && child.value === '\n') {
      if (sentenceChilds.length) {
        var firstWord = sentenceChilds[0]; // we create a sentence starting from the first word until the new line

        var sentence = {
          text: sentenceChilds.map(function (d) {
            return getSentence(d);
          }).join(''),
          start: firstWord.position.start.offset,
          end: child.position.start.offset
        }; // we remove all the elements from the array

        sentenceChilds.splice(0, sentenceChilds.length);
        return acc.concat([sentence]);
      }
    } else {
      // otherwise we add it to the array that contains the child forming a sentence
      sentenceChilds.push(child);
    }

    return acc;
  }, acc); // we treat the case when no \n character is found at the end
  // so we create a sentence from the last words or white spaces found

  if (sentenceChilds.length) {
    var firstWord = sentenceChilds[0];
    var lastWord = sentenceChilds[sentenceChilds.length - 1];
    var sentence = {
      text: sentenceChilds.map(function (d) {
        return getSentence(d);
      }).join(''),
      start: firstWord.position.start.offset,
      end: lastWord.position.end.offset
    };
    newAcc = newAcc.concat([sentence]);
    sentenceChilds.splice(0, sentenceChilds.length);
  }

  return newAcc;
};

exports.handleSentence = handleSentence;

var sentences = function sentences(text) {
  var tree = new _parseEnglish["default"]().parse(text);
  var out = tree.children.reduce(function (acc, child) {
    if (child.type === 'ParagraphNode') {
      return child.children.reduce(function (acc, child) {
        if (child.type === 'SentenceNode') {
          var newAcc = handleSentence(child, acc);
          return newAcc || acc;
        } else {
          return acc;
        }
      }, acc);
    } else {
      return acc;
    }
  }, []);
  return out;
};

exports.sentences = sentences;

var words = function words(text) {
  var tree = new _parseEnglish["default"]().parse(text);
  var out = tree.children.reduce(function (acc, child) {
    if (child.type === 'ParagraphNode') {
      return child.children.reduce(function (acc, child) {
        if (child.type === 'SentenceNode') {
          return child.children.reduce(function (acc, child) {
            if (child.type === 'WordNode') {
              var node = {
                text: getWord(child),
                start: child.position.start.offset,
                end: child.position.end.offset
              };
              return acc.concat([node]);
            } else {
              return acc;
            }
          }, acc);
        } else {
          return acc;
        }
      }, acc);
    } else {
      return acc;
    }
  }, []);
  return out;
};

exports.words = words;

var Intersection = /*#__PURE__*/function () {
  function Intersection(results) {
    (0, _classCallCheck2["default"])(this, Intersection);
    this.results = results;
  }

  (0, _createClass2["default"])(Intersection, [{
    key: "hasOverlap",
    get: function get() {
      return this.results.filter(function (r) {
        return r.type === 'overlap';
      }).length > 0;
    }
  }, {
    key: "surroundedTokens",
    get: function get() {
      return this.results.filter(function (r) {
        return r.type === 'within-selection';
      }).map(function (t) {
        return t.token;
      });
    }
  }]);
  return Intersection;
}();
/**
 * get intersection info for the selection in relation to tokens.
 * @param {{start: number, end: number}} selection
 * @param {{start: number, end: number}[]} tokens
 * @return {tokens: [], type: 'overlap|no-overlap|contains'}
 */


var intersection = function intersection(selection, tokens) {
  var start = selection.start,
      end = selection.end;

  var startsWithin = function startsWithin(t) {
    return start >= t.start && start < t.end;
  };

  var endsWithin = function endsWithin(t) {
    return end > t.start && end <= t.end;
  };

  var mapped = tokens.map(function (t) {
    if (start === t.start && end === t.end) {
      return {
        token: t,
        type: 'exact-fit'
      };
    } else if (start <= t.start && end >= t.end) {
      return {
        token: t,
        type: 'within-selection'
      };
    } else if (startsWithin(t) || endsWithin(t)) {
      return {
        token: t,
        type: 'overlap'
      };
    }
  });
  return new Intersection((0, _compact["default"])(mapped));
};

exports.intersection = intersection;

var sort = function sort(tokens) {
  if (!Array.isArray(tokens)) {
    return tokens;
  } else {
    var out = (0, _clone["default"])(tokens);
    out.sort(function (a, b) {
      var s = a.start < b.start ? -1 : a.start > b.start ? 1 : 0;
      var e = a.end < b.end ? -1 : a.end > b.end ? 1 : 0;

      if (s === -1 && e !== -1) {
        throw new Error("sort does not support intersecting tokens. a: ".concat(a.start, "-").concat(a.end, ", b: ").concat(b.start, "-").concat(b.end));
      }

      return s;
    });
    return out;
  }
};

exports.sort = sort;

var normalize = function normalize(textToNormalize, tokens) {
  // making sure text provided is a string
  var text = textToNormalize || '';

  if (!Array.isArray(tokens) || tokens.length === 0) {
    return [{
      text: text,
      start: 0,
      end: text.length
    }];
  }

  var out = sort(tokens).reduce(function (acc, t, index, outer) {
    var tokens = [];
    var lastIndex = acc.lastIndex;

    if (t.start === lastIndex) {
      tokens = [{
        text: text.substring(lastIndex, t.end),
        start: lastIndex,
        end: t.end,
        predefined: true,
        correct: t.correct,
        isMissing: t.isMissing
      }];
    } else if (lastIndex < t.start) {
      tokens = [{
        text: text.substring(lastIndex, t.start),
        start: lastIndex,
        end: t.start
      }, {
        text: text.substring(t.start, t.end),
        start: t.start,
        end: t.end,
        predefined: true,
        correct: t.correct,
        isMissing: t.isMissing
      }];
    }

    if (index === outer.length - 1 && t.end < text.length) {
      var last = {
        text: text.substring(t.end),
        start: t.end,
        end: text.length
      };
      tokens.push(last);
    }

    return {
      lastIndex: tokens.length ? tokens[tokens.length - 1].end : lastIndex,
      result: acc.result.concat(tokens)
    };
  }, {
    result: [],
    lastIndex: 0
  });
  return out.result;
};

exports.normalize = normalize;
//# sourceMappingURL=builder.js.map