// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

cr.define('cr.ui', function() {
  /** @const */ var Event = cr.Event;
  /** @const */ var EventTarget = cr.EventTarget;

  /**
   * Creates a new selection model that is to be used with lists.
   *
   * @param {number=} opt_length The number items in the selection.
   *
   * @constructor
   * @extends {!cr.EventTarget}
   */
  function ListSelectionModel(opt_length) {
    this.length_ = opt_length || 0;
    // Even though selectedIndexes_ is really a map we use an array here to get
    // iteration in the order of the indexes.
    this.selectedIndexes_ = [];

    // True if any item could be lead or anchor. False if only selected ones.
    this.independentLeadItem_ = !cr.isMac && !cr.isChromeOS;
  }

  ListSelectionModel.prototype = {
    __proto__: EventTarget.prototype,

    /**
     * The number of items in the model.
     * @type {number}
     */
    get length() {
      return this.length_;
    },

    /**
     * The selected indexes.
     * Setter also changes lead and anchor indexes if value list is nonempty.
     * @type {!Array}
     */
    get selectedIndexes() {
      return Object.keys(this.selectedIndexes_).map(Number);
    },
    set selectedIndexes(selectedIndexes) {
      this.beginChange();
      var unselected = {};
      for (var index in this.selectedIndexes_) {
        unselected[index] = true;
      }

      for (var i = 0; i < selectedIndexes.length; i++) {
        var index = selectedIndexes[i];
        if (index in this.selectedIndexes_) {
          delete unselected[index];
        } else {
          this.selectedIndexes_[index] = true;
          // Mark the index as changed. If previously marked, then unmark,
          // since it just got reverted to the original state.
          if (index in this.changedIndexes_)
            delete this.changedIndexes_[index];
          else
            this.changedIndexes_[index] = true;
        }
      }

      for (var index in unselected) {
        delete this.selectedIndexes_[index];
        // Mark the index as changed. If previously marked, then unmark,
        // since it just got reverted to the original state.
        if (index in this.changedIndexes_)
          delete this.changedIndexes_[index];
        else
          this.changedIndexes_[index] = false;
      }

      if (selectedIndexes.length) {
        this.leadIndex = this.anchorIndex = selectedIndexes[0];
      } else {
        this.leadIndex = this.anchorIndex = -1;
      }
      this.endChange();
    },

    /**
     * Convenience getter which returns the first selected index.
     * Setter also changes lead and anchor indexes if value is nonnegative.
     * @type {number}
     */
    get selectedIndex() {
      for (var i in this.selectedIndexes_) {
        return Number(i);
      }
      return -1;
    },
    set selectedIndex(selectedIndex) {
      this.selectedIndexes = selectedIndex != -1 ? [selectedIndex] : [];
    },

    /**
     * Returns the last selected index or -1 if no item selected.
     * @type {number}
     */
    get lastSelectedIndex() {
      var result = -1;
      for (var i in this.selectedIndexes_) {
        result = Math.max(result, Number(i));
      }
      return result;
    },

    /**
     * Selects a range of indexes, starting with {@code start} and ends with
     * {@code end}.
     * @param {number} start The first index to select.
     * @param {number} end The last index to select.
     */
    selectRange: function(start, end) {
      // Swap if starts comes after end.
      if (start > end) {
        var tmp = start;
        start = end;
        end = tmp;
      }

      this.beginChange();

      for (var index = start; index != end; index++) {
        this.setIndexSelected(index, true);
      }
      this.setIndexSelected(end, true);

      this.endChange();
    },

    /**
     * Selects all indexes.
     */
    selectAll: function() {
      this.selectRange(0, this.length - 1);
    },

    /**
     * Clears the selection
     */
    clear: function() {
      this.beginChange();
      this.length_ = 0;
      this.anchorIndex = this.leadIndex = -1;
      this.unselectAll();
      this.endChange();
    },

    /**
     * Unselects all selected items.
     */
    unselectAll: function() {
      this.beginChange();
      for (var i in this.selectedIndexes_) {
        this.setIndexSelected(i, false);
      }
      this.endChange();
    },

    /**
     * Sets the selected state for an index.
     * @param {number} index The index to set the selected state for.
     * @param {boolean} b Whether to select the index or not.
     */
    setIndexSelected: function(index, b) {
      var oldSelected = index in this.selectedIndexes_;
      if (oldSelected == b)
        return;

      if (b)
        this.selectedIndexes_[index] = true;
      else
        delete this.selectedIndexes_[index];

      this.beginChange();

      this.changedIndexes_[index] = b;

      // End change dispatches an event which in turn may update the view.
      this.endChange();
    },

    /**
     * Whether a given index is selected or not.
     * @param {number} index The index to check.
     * @return {boolean} Whether an index is selected.
     */
    getIndexSelected: function(index) {
      return index in this.selectedIndexes_;
    },

    /**
     * This is used to begin batching changes. Call {@code endChange} when you
     * are done making changes.
     */
    beginChange: function() {
      if (!this.changeCount_) {
        this.changeCount_ = 0;
        this.changedIndexes_ = {};
        this.oldLeadIndex_ = this.leadIndex_;
        this.oldAnchorIndex_ = this.anchorIndex_;
      }
      this.changeCount_++;
    },

    /**
     * Call this after changes are done and it will dispatch a change event if
     * any changes were actually done.
     */
    endChange: function() {
      this.changeCount_--;
      if (!this.changeCount_) {
        // Calls delayed |dispatchPropertyChange|s, only when |leadIndex| or
        // |anchorIndex| has been actually changed in the batch.
        this.leadIndex_ = this.adjustIndex_(this.leadIndex_);
        if (this.leadIndex_ != this.oldLeadIndex_) {
          cr.dispatchPropertyChange(this, 'leadIndex',
                                    this.leadIndex_, this.oldLeadIndex_);
        }
        this.oldLeadIndex_ = null;

        this.anchorIndex_ = this.adjustIndex_(this.anchorIndex_);
        if (this.anchorIndex_ != this.oldAnchorIndex_) {
          cr.dispatchPropertyChange(this, 'anchorIndex',
                                    this.anchorIndex_, this.oldAnchorIndex_);
        }
        this.oldAnchorIndex_ = null;

        var indexes = Object.keys(this.changedIndexes_);
        if (indexes.length) {
          var e = new Event('change');
          e.changes = indexes.map(function(index) {
            return {
              index: Number(index),
              selected: this.changedIndexes_[index]
            };
          }, this);
          this.dispatchEvent(e);
        }
        this.changedIndexes_ = {};
      }
    },

    leadIndex_: -1,
    oldLeadIndex_: null,

    /**
     * The leadIndex is used with multiple selection and it is the index that
     * the user is moving using the arrow keys.
     * @type {number}
     */
    get leadIndex() {
      return this.leadIndex_;
    },
    set leadIndex(leadIndex) {
      var oldValue = this.leadIndex_;
      var newValue = this.adjustIndex_(leadIndex);
      this.leadIndex_ = newValue;
      // Delays the call of dispatchPropertyChange if batch is running.
      if (!this.changeCount_ && newValue != oldValue)
        cr.dispatchPropertyChange(this, 'leadIndex', newValue, oldValue);
    },

    anchorIndex_: -1,
    oldAnchorIndex_: null,

    /**
     * The anchorIndex is used with multiple selection.
     * @type {number}
     */
    get anchorIndex() {
      return this.anchorIndex_;
    },
    set anchorIndex(anchorIndex) {
      var oldValue = this.anchorIndex_;
      var newValue = this.adjustIndex_(anchorIndex);
      this.anchorIndex_ = newValue;
      // Delays the call of dispatchPropertyChange if batch is running.
      if (!this.changeCount_ && newValue != oldValue)
        cr.dispatchPropertyChange(this, 'anchorIndex', newValue, oldValue);
    },

    /**
     * Helper method that adjustes a value before assiging it to leadIndex or
     * anchorIndex.
     * @param {number} index New value for leadIndex or anchorIndex.
     * @return {number} Corrected value.
     */
    adjustIndex_: function(index) {
      index = Math.max(-1, Math.min(this.length_ - 1, index));
      // On Mac and ChromeOS lead and anchor items are forced to be among
      // selected items. This rule is not enforces until end of batch update.
      if (!this.changeCount_ && !this.independentLeadItem_ &&
          !this.getIndexSelected(index)) {
        index = this.lastSelectedIndex;
      }
      return index;
    },

    /**
     * Whether the selection model supports multiple selected items.
     * @type {boolean}
     */
    get multiple() {
      return true;
    },

    /**
     * Adjusts the selection after reordering of items in the table.
     * @param {!Array.<number>} permutation The reordering permutation.
     */
    adjustToReordering: function(permutation) {
      this.beginChange();
      var oldLeadIndex = this.leadIndex;
      var oldAnchorIndex = this.anchorIndex;
      var oldSelectedItemsCount = this.selectedIndexes.length;

      this.selectedIndexes = this.selectedIndexes.map(function(oldIndex) {
        return permutation[oldIndex];
      }).filter(function(index) {
        return index != -1;
      });

      // Will be adjusted in endChange.
      if (oldLeadIndex != -1)
        this.leadIndex = permutation[oldLeadIndex];
      if (oldAnchorIndex != -1)
        this.anchorIndex = permutation[oldAnchorIndex];

      if (oldSelectedItemsCount && !this.selectedIndexes.length &&
          this.length_) {
        // All selected items are deleted. We move selection to next item of
        // last selected item.
        this.selectedIndexes = [Math.min(oldLeadIndex, this.length_ - 1)];
      }

      this.endChange();
    },

    /**
     * Adjusts selection model length.
     * @param {number} length New selection model length.
     */
    adjustLength: function(length) {
      this.length_ = length;
    }
  };

  return {
    ListSelectionModel: ListSelectionModel
  };
});
