/**
 * @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';

  const MAX_ITEMS_DROPDOWN = 10;

  const ALL_SUGGESTIONS = [
    {value: '😊', match: 'smile :)'},
    {value: '👍', match: 'thumbs up'},
    {value: '😄', match: 'laugh :D'},
    {value: '🎉', match: 'party'},
    {value: '😞', match: 'sad :('},
    {value: '😂', match: 'tears :\')'},
    {value: '🙏', match: 'pray'},
    {value: '😐', match: 'neutral :|'},
    {value: '😮', match: 'shock :O'},
    {value: '👎', match: 'thumbs down'},
    {value: '😎', match: 'cool |;)'},
    {value: '😕', match: 'confused'},
    {value: '👌', match: 'ok'},
    {value: '🔥', match: 'fire'},
    {value: '👊', match: 'fistbump'},
    {value: '💯', match: '100'},
    {value: '💔', match: 'broken heart'},
    {value: '🍺', match: 'beer'},
    {value: '✔', match: 'check'},
    {value: '😋', match: 'tongue'},
    {value: '😭', match: 'crying :\'('},
    {value: '🐨', match: 'koala'},
    {value: '🤓', match: 'glasses'},
    {value: '😆', match: 'grin'},
    {value: '💩', match: 'poop'},
    {value: '😢', match: 'tear'},
    {value: '😒', match: 'unamused'},
    {value: '😉', match: 'wink ;)'},
    {value: '🍷', match: 'wine'},
    {value: '😜', match: 'winking tongue ;)'},
  ];

  Polymer({
    is: 'gr-textarea',

    /**
     * @event bind-value-changed
     */

    properties: {
      autocomplete: Boolean,
      disabled: Boolean,
      rows: Number,
      maxRows: Number,
      placeholder: String,
      text: {
        type: String,
        notify: true,
        observer: '_handleTextChanged',
      },
      hideBorder: {
        type: Boolean,
        value: false,
      },
      /** Text input should be rendered in monspace font.  */
      monospace: {
        type: Boolean,
        value: false,
      },
      /** Text input should be rendered in code font, which is smaller than the
          standard monospace font. */
      code: {
        type: Boolean,
        value: false,
      },
      /** @type(?number) */
      _colonIndex: Number,
      _currentSearchString: {
        type: String,
        observer: '_determineSuggestions',
      },
      _hideAutocomplete: {
        type: Boolean,
        value: true,
      },
      _index: Number,
      _suggestions: Array,
      // Offset makes dropdown appear below text.
      _verticalOffset: {
        type: Number,
        value: 20,
        readOnly: true,
      },
    },

    behaviors: [
      Gerrit.FireBehavior,
      Gerrit.KeyboardShortcutBehavior,
    ],

    keyBindings: {
      esc: '_handleEscKey',
      tab: '_handleEnterByKey',
      enter: '_handleEnterByKey',
      up: '_handleUpKey',
      down: '_handleDownKey',
    },

    ready() {
      if (this.monospace) {
        this.classList.add('monospace');
      }
      if (this.code) {
        this.classList.add('code');
      }
      if (this.hideBorder) {
        this.$.textarea.classList.add('noBorder');
      }
    },

    closeDropdown() {
      return this.$.emojiSuggestions.close();
    },

    getNativeTextarea() {
      return this.$.textarea.textarea;
    },

    putCursorAtEnd() {
      const textarea = this.getNativeTextarea();
      // Put the cursor at the end always.
      textarea.selectionStart = textarea.value.length;
      textarea.selectionEnd = textarea.selectionStart;
      this.async(() => {
        textarea.focus();
      });
    },

    _handleEscKey(e) {
      if (this._hideAutocomplete) { return; }
      e.preventDefault();
      e.stopPropagation();
      this._resetEmojiDropdown();
    },

    _handleUpKey(e) {
      if (this._hideAutocomplete) { return; }
      e.preventDefault();
      e.stopPropagation();
      this.$.emojiSuggestions.cursorUp();
      this.$.textarea.textarea.focus();
      this.disableEnterKeyForSelectingEmoji = false;
    },

    _handleDownKey(e) {
      if (this._hideAutocomplete) { return; }
      e.preventDefault();
      e.stopPropagation();
      this.$.emojiSuggestions.cursorDown();
      this.$.textarea.textarea.focus();
      this.disableEnterKeyForSelectingEmoji = false;
    },

    _handleEnterByKey(e) {
      if (this._hideAutocomplete || this.disableEnterKeyForSelectingEmoji) {
        return;
      }
      e.preventDefault();
      e.stopPropagation();
      this._setEmoji(this.$.emojiSuggestions.getCurrentText());
    },

    _handleEmojiSelect(e) {
      this._setEmoji(e.detail.selected.dataset.value);
    },

    _setEmoji(text) {
      const colonIndex = this._colonIndex;
      this.text = this._getText(text);
      this.$.textarea.selectionStart = colonIndex + 1;
      this.$.textarea.selectionEnd = colonIndex + 1;
      this.$.reporting.reportInteraction('select-emoji');
      this._resetEmojiDropdown();
    },

    _getText(value) {
      return this.text.substr(0, this._colonIndex || 0) +
          value + this.text.substr(this.$.textarea.selectionStart);
    },
    /**
     * Uses a hidden element with the same width and styling of the textarea and
     * the text up until the point of interest. Then caratSpan element is added
     * to the end and is set to be the positionTarget for the dropdown. Together
     * this allows the dropdown to appear near where the user is typing.
     */
    _updateCaratPosition() {
      this._hideAutocomplete = false;
      this.$.hiddenText.textContent = this.$.textarea.value.substr(0,
          this.$.textarea.selectionStart);

      const caratSpan = this.$.caratSpan;
      this.$.hiddenText.appendChild(caratSpan);
      this.$.emojiSuggestions.positionTarget = caratSpan;
      this._openEmojiDropdown();
    },

    _getFontSize() {
      const fontSizePx = getComputedStyle(this).fontSize || '12px';
      return parseInt(fontSizePx.substr(0, fontSizePx.length - 2),
          10);
    },

    _getScrollTop() {
      return document.body.scrollTop;
    },

    /**
     * _handleKeydown used for key handling in the this.$.textarea AND all child
     * autocomplete options.
     */
    _onValueChanged(e) {
      // Relay the event.
      this.fire('bind-value-changed', e);

      // If cursor is not in textarea (just opened with colon as last char),
      // Don't do anything.
      if (!e.currentTarget.focused) { return; }

      const charAtCursor = e.detail && e.detail.value ?
        e.detail.value[this.$.textarea.selectionStart - 1] : '';
      if (charAtCursor !== ':' && this._colonIndex == null) { return; }

      // When a colon is detected, set a colon index. We are interested only on
      // colons after space or in beginning of textarea
      if (charAtCursor === ':') {
        if (this.$.textarea.selectionStart < 2 ||
            e.detail.value[this.$.textarea.selectionStart - 2] === ' ') {
          this._colonIndex = this.$.textarea.selectionStart - 1;
        }
      }

      this._currentSearchString = e.detail.value.substr(this._colonIndex + 1,
          this.$.textarea.selectionStart - this._colonIndex - 1);
      // Under the following conditions, close and reset the dropdown:
      // - The cursor is no longer at the end of the current search string
      // - The search string is an space or new line
      // - The colon has been removed
      // - There are no suggestions that match the search string
      if (this.$.textarea.selectionStart !==
          this._currentSearchString.length + this._colonIndex + 1 ||
          this._currentSearchString === ' ' ||
          this._currentSearchString === '\n' ||
          !(e.detail.value[this._colonIndex] === ':') ||
          !this._suggestions.length) {
        this._resetEmojiDropdown();
      // Otherwise open the dropdown and set the position to be just below the
      // cursor.
      } else if (this.$.emojiSuggestions.isHidden) {
        this._updateCaratPosition();
      }
      this.$.textarea.textarea.focus();
    },

    _openEmojiDropdown() {
      this.$.emojiSuggestions.open();
      this.$.reporting.reportInteraction('open-emoji-dropdown');
    },

    _formatSuggestions(matchedSuggestions) {
      const suggestions = [];
      for (const suggestion of matchedSuggestions) {
        suggestion.dataValue = suggestion.value;
        suggestion.text = suggestion.value + ' ' + suggestion.match;
        suggestions.push(suggestion);
      }
      this.set('_suggestions', suggestions);
    },

    _determineSuggestions(emojiText) {
      if (!emojiText.length) {
        this._formatSuggestions(ALL_SUGGESTIONS);
        this.disableEnterKeyForSelectingEmoji = true;
      } else {
        const matches = ALL_SUGGESTIONS.filter(suggestion => {
          return suggestion.match.includes(emojiText);
        }).slice(0, MAX_ITEMS_DROPDOWN);
        this._formatSuggestions(matches);
        this.disableEnterKeyForSelectingEmoji = false;
      }
    },

    _resetEmojiDropdown() {
      // hide and reset the autocomplete dropdown.
      Polymer.dom.flush();
      this._currentSearchString = '';
      this._hideAutocomplete = true;
      this.closeDropdown();
      this._colonIndex = null;
      this.$.textarea.textarea.focus();
    },

    _handleTextChanged(text) {
      this.dispatchEvent(
          new CustomEvent('value-changed', {detail: {value: text}}));
    },
  });
})();
