// 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('options.autofillOptions', function() {
  /** @const */ var DeletableItem = options.DeletableItem;
  /** @const */ var DeletableItemList = options.DeletableItemList;
  /** @const */ var InlineEditableItem = options.InlineEditableItem;
  /** @const */ var InlineEditableItemList = options.InlineEditableItemList;

  function AutofillEditProfileButton(guid, edit) {
    var editButtonEl = document.createElement('button');
    editButtonEl.className = 'list-inline-button custom-appearance';
    editButtonEl.textContent =
        loadTimeData.getString('autofillEditProfileButton');
    editButtonEl.onclick = function(e) { edit(guid); };

    editButtonEl.onmousedown = function(e) {
      // Don't select the row when clicking the button.
      e.stopPropagation();
      // Don't focus on the button when clicking it.
      e.preventDefault();
    };

    return editButtonEl;
  }

  /**
   * Creates a new address list item.
   * @param {Array} entry An array of the form [guid, label].
   * @constructor
   * @extends {options.DeletableItem}
   */
  function AddressListItem(entry) {
    var el = cr.doc.createElement('div');
    el.guid = entry[0];
    el.label = entry[1];
    el.__proto__ = AddressListItem.prototype;
    el.decorate();

    return el;
  }

  AddressListItem.prototype = {
    __proto__: DeletableItem.prototype,

    /** @override */
    decorate: function() {
      DeletableItem.prototype.decorate.call(this);

      // The stored label.
      var label = this.ownerDocument.createElement('div');
      label.className = 'autofill-list-item';
      label.textContent = this.label;
      this.contentElement.appendChild(label);

      // The 'Edit' button.
      var editButtonEl = new AutofillEditProfileButton(
        this.guid,
        AutofillOptions.loadAddressEditor);
      this.contentElement.appendChild(editButtonEl);
    },
  };

  /**
   * Creates a new credit card list item.
   * @param {Array} entry An array of the form [guid, label, icon].
   * @constructor
   * @extends {options.DeletableItem}
   */
  function CreditCardListItem(entry) {
    var el = cr.doc.createElement('div');
    el.guid = entry[0];
    el.label = entry[1];
    el.icon = entry[2];
    el.description = entry[3];
    el.__proto__ = CreditCardListItem.prototype;
    el.decorate();

    return el;
  }

  CreditCardListItem.prototype = {
    __proto__: DeletableItem.prototype,

    /** @override */
    decorate: function() {
      DeletableItem.prototype.decorate.call(this);

      // The stored label.
      var label = this.ownerDocument.createElement('div');
      label.className = 'autofill-list-item';
      label.textContent = this.label;
      this.contentElement.appendChild(label);

      // The credit card icon.
      var icon = this.ownerDocument.createElement('image');
      icon.src = this.icon;
      icon.alt = this.description;
      this.contentElement.appendChild(icon);

      // The 'Edit' button.
      var editButtonEl = new AutofillEditProfileButton(
        this.guid,
        AutofillOptions.loadCreditCardEditor);
      this.contentElement.appendChild(editButtonEl);
    },
  };

  /**
   * Creates a new value list item.
   * @param {AutofillValuesList} list The parent list of this item.
   * @param {string} entry A string value.
   * @constructor
   * @extends {options.InlineEditableItem}
   */
  function ValuesListItem(list, entry) {
    var el = cr.doc.createElement('div');
    el.list = list;
    el.value = entry ? entry : '';
    el.__proto__ = ValuesListItem.prototype;
    el.decorate();

    return el;
  }

  ValuesListItem.prototype = {
    __proto__: InlineEditableItem.prototype,

    /** @override */
    decorate: function() {
      InlineEditableItem.prototype.decorate.call(this);

      // Note: This must be set prior to calling |createEditableTextCell|.
      this.isPlaceholder = !this.value;

      // The stored value.
      var cell = this.createEditableTextCell(this.value);
      this.contentElement.appendChild(cell);
      this.input = cell.querySelector('input');

      if (this.isPlaceholder) {
        this.input.placeholder = this.list.getAttribute('placeholder');
        this.deletable = false;
      }

      this.addEventListener('commitedit', this.onEditCommitted_);
    },

    /**
     * @return {string} This item's value.
     * @protected
     */
    value_: function() {
      return this.input.value;
    },

    /**
     * @param {Object} value The value to test.
     * @return {boolean} True if the given value is non-empty.
     * @protected
     */
    valueIsNonEmpty_: function(value) {
      return !!value;
    },

    /**
     * @return {boolean} True if value1 is logically equal to value2.
     */
    valuesAreEqual_: function(value1, value2) {
      return value1 === value2;
    },

    /**
     * Clears the item's value.
     * @protected
     */
    clearValue_: function() {
      this.input.value = '';
    },

    /**
     * Called when committing an edit.
     * If this is an "Add ..." item, committing a non-empty value adds that
     * value to the end of the values list, but also leaves this "Add ..." item
     * in place.
     * @param {Event} e The end event.
     * @private
     */
    onEditCommitted_: function(e) {
      var value = this.value_();
      var i = this.list.items.indexOf(this);
      if (i < this.list.dataModel.length &&
          this.valuesAreEqual_(value, this.list.dataModel.item(i))) {
        return;
      }

      var entries = this.list.dataModel.slice();
      if (this.valueIsNonEmpty_(value) &&
          !entries.some(this.valuesAreEqual_.bind(this, value))) {
        // Update with new value.
        if (this.isPlaceholder) {
          // It is important that updateIndex is done before validateAndSave.
          // Otherwise we can not be sure about AddRow index.
          this.list.dataModel.updateIndex(i);
          this.list.validateAndSave(i, 0, value);
        } else {
          this.list.validateAndSave(i, 1, value);
        }
      } else {
        // Reject empty values and duplicates.
        if (!this.isPlaceholder)
          this.list.dataModel.splice(i, 1);
        else
          this.clearValue_();
      }
    },
  };

  /**
   * Creates a new name value list item.
   * @param {AutofillNameValuesList} list The parent list of this item.
   * @param {array} entry An array of [first, middle, last] names.
   * @constructor
   * @extends {options.ValuesListItem}
   */
  function NameListItem(list, entry) {
    var el = cr.doc.createElement('div');
    el.list = list;
    el.first = entry ? entry[0] : '';
    el.middle = entry ? entry[1] : '';
    el.last = entry ? entry[2] : '';
    el.__proto__ = NameListItem.prototype;
    el.decorate();

    return el;
  }

  NameListItem.prototype = {
    __proto__: ValuesListItem.prototype,

    /** @override */
    decorate: function() {
      InlineEditableItem.prototype.decorate.call(this);

      // Note: This must be set prior to calling |createEditableTextCell|.
      this.isPlaceholder = !this.first && !this.middle && !this.last;

      // The stored value.
      // For the simulated static "input element" to display correctly, the
      // value must not be empty.  We use a space to force the UI to render
      // correctly when the value is logically empty.
      var cell = this.createEditableTextCell(this.first);
      this.contentElement.appendChild(cell);
      this.firstNameInput = cell.querySelector('input');

      cell = this.createEditableTextCell(this.middle);
      this.contentElement.appendChild(cell);
      this.middleNameInput = cell.querySelector('input');

      cell = this.createEditableTextCell(this.last);
      this.contentElement.appendChild(cell);
      this.lastNameInput = cell.querySelector('input');

      if (this.isPlaceholder) {
        this.firstNameInput.placeholder =
            loadTimeData.getString('autofillAddFirstNamePlaceholder');
        this.middleNameInput.placeholder =
            loadTimeData.getString('autofillAddMiddleNamePlaceholder');
        this.lastNameInput.placeholder =
            loadTimeData.getString('autofillAddLastNamePlaceholder');
        this.deletable = false;
      }

      this.addEventListener('commitedit', this.onEditCommitted_);
    },

    /** @override */
    value_: function() {
      return [this.firstNameInput.value,
              this.middleNameInput.value,
              this.lastNameInput.value];
    },

    /** @override */
    valueIsNonEmpty_: function(value) {
      return value[0] || value[1] || value[2];
    },

    /** @override */
    valuesAreEqual_: function(value1, value2) {
      // First, check for null values.
      if (!value1 || !value2)
        return value1 == value2;

      return value1[0] === value2[0] &&
             value1[1] === value2[1] &&
             value1[2] === value2[2];
    },

    /** @override */
    clearValue_: function() {
      this.firstNameInput.value = '';
      this.middleNameInput.value = '';
      this.lastNameInput.value = '';
    },
  };

  /**
   * Base class for shared implementation between address and credit card lists.
   * @constructor
   * @extends {options.DeletableItemList}
   */
  var AutofillProfileList = cr.ui.define('list');

  AutofillProfileList.prototype = {
    __proto__: DeletableItemList.prototype,

    decorate: function() {
      DeletableItemList.prototype.decorate.call(this);

      this.addEventListener('blur', this.onBlur_);
    },

    /**
     * When the list loses focus, unselect all items in the list.
     * @private
     */
    onBlur_: function() {
      this.selectionModel.unselectAll();
    },
  };

  /**
   * Create a new address list.
   * @constructor
   * @extends {options.AutofillProfileList}
   */
  var AutofillAddressList = cr.ui.define('list');

  AutofillAddressList.prototype = {
    __proto__: AutofillProfileList.prototype,

    decorate: function() {
      AutofillProfileList.prototype.decorate.call(this);
    },

    /** @override */
    activateItemAtIndex: function(index) {
      AutofillOptions.loadAddressEditor(this.dataModel.item(index)[0]);
    },

    /** @override */
    createItem: function(entry) {
      return new AddressListItem(entry);
    },

    /** @override */
    deleteItemAtIndex: function(index) {
      AutofillOptions.removeData(this.dataModel.item(index)[0]);
    },
  };

  /**
   * Create a new credit card list.
   * @constructor
   * @extends {options.DeletableItemList}
   */
  var AutofillCreditCardList = cr.ui.define('list');

  AutofillCreditCardList.prototype = {
    __proto__: AutofillProfileList.prototype,

    decorate: function() {
      AutofillProfileList.prototype.decorate.call(this);
    },

    /** @override */
    activateItemAtIndex: function(index) {
      AutofillOptions.loadCreditCardEditor(this.dataModel.item(index)[0]);
    },

    /** @override */
    createItem: function(entry) {
      return new CreditCardListItem(entry);
    },

    /** @override */
    deleteItemAtIndex: function(index) {
      AutofillOptions.removeData(this.dataModel.item(index)[0]);
    },
  };

  /**
   * Create a new value list.
   * @constructor
   * @extends {options.InlineEditableItemList}
   */
  var AutofillValuesList = cr.ui.define('list');

  AutofillValuesList.prototype = {
    __proto__: InlineEditableItemList.prototype,

    /** @override */
    createItem: function(entry) {
      return new ValuesListItem(this, entry);
    },

    /** @override */
    deleteItemAtIndex: function(index) {
      this.dataModel.splice(index, 1);
    },

    /** @override */
    shouldFocusPlaceholder: function() {
      return false;
    },

    /**
     * Called when the list hierarchy as a whole loses or gains focus.
     * If the list was focused in response to a mouse click, call into the
     * superclass's implementation.  If the list was focused in response to a
     * keyboard navigation, focus the first item.
     * If the list loses focus, unselect all the elements.
     * @param {Event} e The change event.
     * @private
     */
    handleListFocusChange_: function(e) {
      // We check to see whether there is a selected item as a proxy for
      // distinguishing between mouse- and keyboard-originated focus events.
      var selectedItem = this.selectedItem;
      if (selectedItem)
        InlineEditableItemList.prototype.handleListFocusChange_.call(this, e);

      if (!e.newValue) {
        // When the list loses focus, unselect all the elements.
        this.selectionModel.unselectAll();
      } else {
        // When the list gains focus, select the first item if nothing else is
        // selected.
        var firstItem = this.getListItemByIndex(0);
        if (!selectedItem && firstItem && e.newValue)
          firstItem.handleFocus_();
      }
    },

    /**
     * Called when a new list item should be validated; subclasses are
     * responsible for implementing if validation is required.
     * @param {number} index The index of the item that was inserted or changed.
     * @param {number} remove The number items to remove.
     * @param {string} value The value of the item to insert.
     */
    validateAndSave: function(index, remove, value) {
      this.dataModel.splice(index, remove, value);
    },
  };

  /**
   * Create a new value list for phone number validation.
   * @constructor
   * @extends {options.AutofillValuesList}
   */
  var AutofillNameValuesList = cr.ui.define('list');

  AutofillNameValuesList.prototype = {
    __proto__: AutofillValuesList.prototype,

    /** @override */
    createItem: function(entry) {
      return new NameListItem(this, entry);
    },
  };

  /**
   * Create a new value list for phone number validation.
   * @constructor
   * @extends {options.AutofillValuesList}
   */
  var AutofillPhoneValuesList = cr.ui.define('list');

  AutofillPhoneValuesList.prototype = {
    __proto__: AutofillValuesList.prototype,

    /** @override */
    validateAndSave: function(index, remove, value) {
      var numbers = this.dataModel.slice(0, this.dataModel.length - 1);
      numbers.splice(index, remove, value);
      var info = new Array();
      info[0] = index;
      info[1] = numbers;
      info[2] = $('country').value;
      chrome.send('validatePhoneNumbers', info);
    },
  };

  return {
    AddressListItem: AddressListItem,
    CreditCardListItem: CreditCardListItem,
    ValuesListItem: ValuesListItem,
    NameListItem: NameListItem,
    AutofillAddressList: AutofillAddressList,
    AutofillCreditCardList: AutofillCreditCardList,
    AutofillValuesList: AutofillValuesList,
    AutofillNameValuesList: AutofillNameValuesList,
    AutofillPhoneValuesList: AutofillPhoneValuesList,
  };
});
