/**
 * @license
 * Copyright (C) 2016 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';

  const REL_NOOPENER = 'noopener';
  const REL_EXTERNAL = 'external';

  /**
    * @appliesMixin Gerrit.BaseUrlMixin
    * @appliesMixin Gerrit.KeyboardShortcutMixin
    */
  class GrDropdown extends Polymer.mixinBehaviors( [
    Gerrit.BaseUrlBehavior,
    Gerrit.KeyboardShortcutBehavior,
  ], Polymer.GestureEventListeners(
      Polymer.LegacyElementMixin(
          Polymer.Element))) {
    static get is() { return 'gr-dropdown'; }
    /**
     * Fired when a non-link dropdown item with the given ID is tapped.
     *
     * @event tap-item-<id>
     */

    /**
     * Fired when a non-link dropdown item is tapped.
     *
     * @event tap-item
     */

    static get properties() {
      return {
        items: {
          type: Array,
          observer: '_resetCursorStops',
        },
        downArrow: Boolean,
        topContent: Object,
        horizontalAlign: {
          type: String,
          value: 'left',
        },

        /**
       * Style the dropdown trigger as a link (rather than a button).
       */
        link: {
          type: Boolean,
          value: false,
        },

        verticalOffset: {
          type: Number,
          value: 40,
        },

        /**
       * List the IDs of dropdown buttons to be disabled. (Note this only
       * diisables bittons and not link entries.)
       */
        disabledIds: {
          type: Array,
          value() { return []; },
        },

        /**
       * The elements of the list.
       */
        _listElements: {
          type: Array,
          value() { return []; },
        },
      };
    }

    get keyBindings() {
      return {
        'down': '_handleDown',
        'enter space': '_handleEnter',
        'tab': '_handleTab',
        'up': '_handleUp',
      };
    }

    /**
     * Handle the up key.
     * @param {!Event} e
     */
    _handleUp(e) {
      if (this.$.dropdown.opened) {
        e.preventDefault();
        e.stopPropagation();
        this.$.cursor.previous();
      } else {
        this._open();
      }
    }

    /**
     * Handle the down key.
     * @param {!Event} e
     */
    _handleDown(e) {
      if (this.$.dropdown.opened) {
        e.preventDefault();
        e.stopPropagation();
        this.$.cursor.next();
      } else {
        this._open();
      }
    }

    /**
     * Handle the tab key.
     * @param {!Event} e
     */
    _handleTab(e) {
      if (this.$.dropdown.opened) {
        // Tab in a native select is a no-op. Emulate this.
        e.preventDefault();
        e.stopPropagation();
      }
    }

    /**
     * Handle the enter key.
     * @param {!Event} e
     */
    _handleEnter(e) {
      e.preventDefault();
      e.stopPropagation();
      if (this.$.dropdown.opened) {
        // TODO(milutin): This solution is not particularly robust in general.
        // Since gr-tooltip-content click on shadow dom is not propagated down,
        // we have to target `a` inside it.
        const el = this.$.cursor.target.querySelector(':not([hidden]) a');
        if (el) { el.click(); }
      } else {
        this._open();
      }
    }

    /**
     * Handle a click on the iron-dropdown element.
     * @param {!Event} e
     */
    _handleDropdownTap(e) {
      this._close();
    }

    /**
     * Hanlde a click on the button to open the dropdown.
     * @param {!Event} e
     */
    _dropdownTriggerTapHandler(e) {
      e.preventDefault();
      e.stopPropagation();
      if (this.$.dropdown.opened) {
        this._close();
      } else {
        this._open();
      }
    }

    /**
     * Open the dropdown and initialize the cursor.
     */
    _open() {
      this.$.dropdown.open();
      this._resetCursorStops();
      this.$.cursor.setCursorAtIndex(0);
      this.$.cursor.target.focus();
    }

    _close() {
      // async is needed so that that the click event is fired before the
      // dropdown closes (This was a bug for touch devices).
      this.async(() => {
        this.$.dropdown.close();
      }, 1);
    }

    /**
     * Get the class for a top-content item based on the given boolean.
     * @param {boolean} bold Whether the item is bold.
     * @return {string} The class for the top-content item.
     */
    _getClassIfBold(bold) {
      return bold ? 'bold-text' : '';
    }

    /**
     * Build a URL for the given host and path. The base URL will be only added,
     * if it is not already included in the path.
     * @param {!string} host
     * @param {!string} path
     * @return {!string} The scheme-relative URL.
     */
    _computeURLHelper(host, path) {
      const base = path.startsWith(this.getBaseUrl()) ?
        '' : this.getBaseUrl();
      return '//' + host + base + path;
    }

    /**
     * Build a scheme-relative URL for the current host. Will include the base
     * URL if one is present. Note: the URL will be scheme-relative but absolute
     * with regard to the host.
     * @param {!string} path The path for the URL.
     * @return {!string} The scheme-relative URL.
     */
    _computeRelativeURL(path) {
      const host = window.location.host;
      return this._computeURLHelper(host, path);
    }

    /**
     * Compute the URL for a link object.
     * @param {!Object} link The object describing the link.
     * @return {!string} The URL.
     */
    _computeLinkURL(link) {
      if (typeof link.url === 'undefined') {
        return '';
      }
      if (link.target || !link.url.startsWith('/')) {
        return link.url;
      }
      return this._computeRelativeURL(link.url);
    }

    /**
     * Compute the value for the rel attribute of an anchor for the given link
     * object. If the link has a target value, then the rel must be "noopener"
     * for security reasons.
     * @param {!Object} link The object describing the link.
     * @return {?string} The rel value for the link.
     */
    _computeLinkRel(link) {
      // Note: noopener takes precedence over external.
      if (link.target) { return REL_NOOPENER; }
      if (link.external) { return REL_EXTERNAL; }
      return null;
    }

    /**
     * Handle a click on an item of the dropdown.
     * @param {!Event} e
     */
    _handleItemTap(e) {
      const id = e.target.getAttribute('data-id');
      const item = this.items.find(item => item.id === id);
      if (id && !this.disabledIds.includes(id)) {
        if (item) {
          this.dispatchEvent(new CustomEvent('tap-item', {detail: item}));
        }
        this.dispatchEvent(new CustomEvent('tap-item-' + id));
      }
    }

    /**
     * If a dropdown item is shown as a button, get the class for the button.
     * @param {string} id
     * @param {!Object} disabledIdsRecord The change record for the disabled IDs
     *     list.
     * @return {!string} The class for the item button.
     */
    _computeDisabledClass(id, disabledIdsRecord) {
      return disabledIdsRecord.base.includes(id) ? 'disabled' : '';
    }

    /**
     * Recompute the stops for the dropdown item cursor.
     */
    _resetCursorStops() {
      if (this.items && this.items.length > 0 && this.$.dropdown.opened) {
        Polymer.dom.flush();
        this._listElements = Array.from(
            Polymer.dom(this.root).querySelectorAll('li'));
      }
    }

    _computeHasTooltip(tooltip) {
      return !!tooltip;
    }

    _computeIsDownload(link) {
      return !!link.download;
    }
  }

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