// 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 */ const EventTarget = cr.EventTarget;

  /**
   * Creates a new selection model that is to be used with lists. This only
   * allows a single index to be selected.
   *
   * @param {number=} opt_length The number items in the selection.
   *
   * @constructor
   * @extends {cr.EventTarget}
   */
  function ListSingleSelectionModel(opt_length) {
    this.length_ = opt_length || 0;
    this.selectedIndex = -1;

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

  ListSingleSelectionModel.prototype = {
    __proto__: EventTarget.prototype,

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

    /**
     * @type {!Array} The selected indexes.
     */
    get selectedIndexes() {
      const i = this.selectedIndex;
      return i != -1 ? [this.selectedIndex] : [];
    },
    set selectedIndexes(indexes) {
      this.selectedIndex = indexes.length ? indexes[0] : -1;
    },

    /**
     * Convenience getter which returns the first selected index.
     * Setter also changes lead and anchor indexes if value is nonegative.
     * @type {number}
     */
    get selectedIndex() {
      return this.selectedIndex_;
    },
    set selectedIndex(selectedIndex) {
      const oldSelectedIndex = this.selectedIndex;
      const i = Math.max(-1, Math.min(this.length_ - 1, selectedIndex));

      if (i != oldSelectedIndex) {
        this.beginChange();
        this.selectedIndex_ = i;
        this.leadIndex = i >= 0 ? i : this.leadIndex;
        this.endChange();
      }
    },

    /**
     * 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) {
      // Only select first index.
      this.selectedIndex = Math.min(start, end);
    },

    /**
     * Selects all indexes.
     */
    selectAll: function() {
      // Select all is not allowed on a single selection model
    },

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

    /**
     * Unselects all selected items.
     */
    unselectAll: function() {
      this.selectedIndex = -1;
    },

    /**
     * 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) {
      // Only allow selection
      const oldSelected = index == this.selectedIndex_;
      if (oldSelected == b) {
        return;
      }

      if (b) {
        this.selectedIndex = index;
      } else if (index == this.selectedIndex_) {
        this.selectedIndex = -1;
      }
    },

    /**
     * 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 == this.selectedIndex_;
    },

    /**
     * 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.selectedIndexBefore_ = this.selectedIndex_;
      }
      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_) {
        if (this.selectedIndexBefore_ != this.selectedIndex_) {
          const beforeChange = this.createChangeEvent('beforeChange');
          if (this.dispatchEvent(beforeChange)) {
            this.dispatchEvent(this.createChangeEvent('change'));
          } else {
            this.selectedIndex_ = this.selectedIndexBefore_;
          }
        }
      }
    },

    /**
     * Creates event with specified name and fills its {changes} property.
     * @param {string} eventName Event name.
     */
    createChangeEvent: function(eventName) {
      const e = new Event(eventName);
      const indexes = [this.selectedIndexBefore_, this.selectedIndex_];
      e.changes =
          indexes
              .filter(function(index) {
                return index != -1;
              })
              .map(function(index) {
                return {index: index, selected: index == this.selectedIndex_};
              }, this);

      return e;
    },

    leadIndex_: -1,

    /**
     * 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) {
      const li = this.adjustIndex_(leadIndex);
      if (li != this.leadIndex_) {
        const oldLeadIndex = this.leadIndex_;
        this.leadIndex_ = li;
        cr.dispatchPropertyChange(this, 'leadIndex', li, oldLeadIndex);
        cr.dispatchPropertyChange(this, 'anchorIndex', li, oldLeadIndex);
      }
    },

    adjustIndex_: function(index) {
      index = Math.max(-1, Math.min(this.length_ - 1, index));
      if (!this.independentLeadItem_) {
        index = this.selectedIndex;
      }
      return index;
    },

    /**
     * The anchorIndex is used with multiple selection.
     * @type {number}
     */
    get anchorIndex() {
      return this.leadIndex;
    },
    set anchorIndex(anchorIndex) {
      this.leadIndex = anchorIndex;
    },

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

    /**
     * Adjusts the selection after reordering of items in the table.
     * @param {!Array<number>} permutation The reordering permutation.
     */
    adjustToReordering: function(permutation) {
      if (this.leadIndex != -1) {
        this.leadIndex = permutation[this.leadIndex];
      }

      const oldSelectedIndex = this.selectedIndex;
      if (oldSelectedIndex != -1) {
        this.selectedIndex = permutation[oldSelectedIndex];
      }
    },

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

  return {ListSingleSelectionModel: ListSingleSelectionModel};
});
