/**
 * @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
     */
    _handleDropdownClick(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);
})();
