'use strict';

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

var _immutable = require('immutable');

/**
 * Range.
 */

var Range = new _immutable.Record({
  text: '',
  marks: new _immutable.Set()
});

/**
 * Group a list of `characters` into ranges by the marks they have.
 *
 * @param {List} characters
 * @return {List} ranges
 */

function groupByMarks(characters) {
  if (characters.size == 0) {
    var ranges = new _immutable.List();
    ranges = ranges.push(new Range());
    return ranges;
  }

  return characters.toList().reduce(function (ranges, char, i) {
    var marks = char.marks;
    var text = char.text;

    // The first one can always just be created.

    if (i == 0) {
      return ranges.push(new Range({ text: text, marks: marks }));
    }

    // Otherwise, compare to the previous and see if a new range should be
    // created, or whether the text should be added to the previous range.
    var previous = characters.get(i - 1);
    var prevMarks = previous.marks;
    var added = marks.filterNot(function (mark) {
      return prevMarks.includes(mark);
    });
    var removed = prevMarks.filterNot(function (mark) {
      return marks.includes(mark);
    });
    var isSame = !added.size && !removed.size;

    // If the marks are the same, add the text to the previous range.
    if (isSame) {
      var index = ranges.size - 1;
      var prevRange = ranges.get(index);
      var prevText = prevRange.get('text');
      prevRange = prevRange.set('text', prevText += text);
      return ranges.set(index, prevRange);
    }

    // Otherwise, create a new range.
    return ranges.push(new Range({ text: text, marks: marks }));
  }, new _immutable.List());
}

/**
 * Export.
 */

exports.default = groupByMarks;