// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

var Selection = function(handler) {
  this.handler = handler;
  this.selectionBase = null;
  this.lastSelection = null;
  this.selection = new Set();
}


Selection.prototype.isEmpty = function() {
  return this.selection.size == 0;
}


Selection.prototype.clear = function() {
  var handler = this.handler;
  this.selectionBase = null;
  this.lastSelection = null;
  handler.select(this.selection, false);
  handler.clear();
  this.selection = new Set();
}


count = 0;

Selection.prototype.select = function(s, isSelected) {
  var handler = this.handler;
  if (!(Symbol.iterator in Object(s))) { s = [s]; }
  if (isSelected) {
    let first = true;
    for (let i of s) {
      if (first) {
        this.selectionBase = i;
        this.lastSelection = i;
        first = false;
      }
      this.selection.add(i);
    }
  } else {
    let unselectSet = new Set();
    for (let i of s) {
      if (this.selection.has(i)) {
        unselectSet.add(i);
        this.selection.delete(i);
      }
    }
  }
  handler.select(this.selection, isSelected);
}


Selection.prototype.extendTo = function(pos) {
  if (pos == this.lastSelection || this.lastSelection === null) return;

  var handler = this.handler;
  var pos_diff = handler.selectionDifference(pos, true, this.lastSelection, false);
  var unselect_diff = [];
  if (pos_diff.length == 0) {
    pos_diff = handler.selectionDifference(this.selectionBase, false, pos, true);
    if (pos_diff.length != 0) {
      unselect_diff = handler.selectionDifference(this.lastSelection, true, this.selectionBase, false);
      this.selection = new Set();
      this.selection.add(this.selectionBase);
      for (var d of pos_diff) {
        this.selection.add(d);
      }
    } else {
      unselect_diff = handler.selectionDifference(this.lastSelection, true, pos, false);
      for (var d of unselect_diff) {
        this.selection.delete(d);
      }
    }
  } else {
    unselect_diff = handler.selectionDifference(this.selectionBase, false, this.lastSelection, true);
    if (unselect_diff != 0) {
      pos_diff = handler.selectionDifference(pos, true, this.selectionBase, false);
      if (pos_diff.length == 0) {
        unselect_diff = handler.selectionDifference(pos, false, this.lastSelection, true);
      }
      for (var d of unselect_diff) {
        this.selection.delete(d);
      }
    }
    if (pos_diff.length != 0) {
      for (var d of pos_diff) {
        this.selection.add(d);
      }
    }
  }
  handler.select(unselect_diff, false);
  handler.select(pos_diff, true);
  this.lastSelection = pos;
}


Selection.prototype.detachSelection = function() {
  var result = new Set();
  for (var i of this.selection) {
    result.add(i);
  }
  this.clear();
  return result;
}
