/**
 * @license
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
(function() {
  'use strict';

  /** @extends Polymer.Element */
  class GrLabelScoreRow extends Polymer.GestureEventListeners(
      Polymer.LegacyElementMixin(
          Polymer.Element)) {
    static get is() { return 'gr-label-score-row'; }
    /**
     * Fired when any label is changed.
     *
     * @event labels-changed
     */

    static get properties() {
      return {
      /**
       * @type {{ name: string }}
       */
        label: Object,
        labels: Object,
        name: {
          type: String,
          reflectToAttribute: true,
        },
        permittedLabels: Object,
        labelValues: Object,
        _selectedValueText: {
          type: String,
          value: 'No value selected',
        },
        _items: {
          type: Array,
          computed: '_computePermittedLabelValues(permittedLabels, label.name)',
        },
      };
    }

    get selectedItem() {
      if (!this._ironSelector) { return undefined; }
      return this._ironSelector.selectedItem;
    }

    get selectedValue() {
      if (!this._ironSelector) { return undefined; }
      return this._ironSelector.selected;
    }

    setSelectedValue(value) {
      // The selector may not be present if it’s not at the latest patch set.
      if (!this._ironSelector) { return; }
      this._ironSelector.select(value);
    }

    get _ironSelector() {
      return this.$ && this.$.labelSelector;
    }

    _computeBlankItems(permittedLabels, label, side) {
      if (!permittedLabels || !permittedLabels[label] ||
          !permittedLabels[label].length || !this.labelValues ||
          !Object.keys(this.labelValues).length) {
        return [];
      }
      const startPosition = this.labelValues[parseInt(
          permittedLabels[label][0], 10)];
      if (side === 'start') {
        return new Array(startPosition);
      }
      const endPosition = this.labelValues[parseInt(
          permittedLabels[label][permittedLabels[label].length - 1], 10)];
      return new Array(Object.keys(this.labelValues).length - endPosition - 1);
    }

    _getLabelValue(labels, permittedLabels, label) {
      if (label.value) {
        return label.value;
      } else if (labels[label.name].hasOwnProperty('default_value') &&
                 permittedLabels.hasOwnProperty(label.name)) {
        // default_value is an int, convert it to string label, e.g. "+1".
        return permittedLabels[label.name].find(
            value => parseInt(value, 10) === labels[label.name].default_value);
      }
    }

    /**
     * Maps the label value to exactly one of: min, max, positive, negative,
     * neutral. Used for the 'vote' attribute, because we don't want to
     * interfere with <iron-selector> using the 'class' attribute for setting
     * 'iron-selected'.
     */
    _computeVoteAttribute(value, index, totalItems) {
      if (value < 0 && index === 0) {
        return 'min';
      } else if (value < 0) {
        return 'negative';
      } else if (value > 0 && index === totalItems - 1) {
        return 'max';
      } else if (value > 0) {
        return 'positive';
      } else {
        return 'neutral';
      }
    }

    _computeLabelValue(labels, permittedLabels, label) {
      if ([labels, permittedLabels, label].some(arg => arg === undefined)) {
        return null;
      }
      if (!labels[label.name]) { return null; }
      const labelValue = this._getLabelValue(labels, permittedLabels, label);
      const len = permittedLabels[label.name] != null ?
        permittedLabels[label.name].length : 0;
      for (let i = 0; i < len; i++) {
        const val = permittedLabels[label.name][i];
        if (val === labelValue) {
          return val;
        }
      }
      return null;
    }

    _setSelectedValueText(e) {
      // Needed because when the selected item changes, it first changes to
      // nothing and then to the new item.
      if (!e.target.selectedItem) { return; }
      this._selectedValueText = e.target.selectedItem.getAttribute('title');
      // Needed to update the style of the selected button.
      this.updateStyles();
      const name = e.target.selectedItem.dataset.name;
      const value = e.target.selectedItem.dataset.value;
      this.dispatchEvent(new CustomEvent(
          'labels-changed',
          {detail: {name, value}, bubbles: true, composed: true}));
    }

    _computeAnyPermittedLabelValues(permittedLabels, label) {
      return permittedLabels && permittedLabels.hasOwnProperty(label) &&
        permittedLabels[label].length;
    }

    _computeHiddenClass(permittedLabels, label) {
      return !this._computeAnyPermittedLabelValues(permittedLabels, label) ?
        'hidden' : '';
    }

    _computePermittedLabelValues(permittedLabels, label) {
      // Polymer 2: check for undefined
      if ([permittedLabels, label].some(arg => arg === undefined)) {
        return undefined;
      }

      return permittedLabels[label];
    }

    _computeLabelValueTitle(labels, label, value) {
      return labels[label] &&
        labels[label].values &&
        labels[label].values[value];
    }
  }

  customElements.define(GrLabelScoreRow.is, GrLabelScoreRow);
})();
