// 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 VERTICAL_OFFSET = 7;

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

  Polymer({
    is: 'gr-textarea',

    properties: {
      autocomplete: Boolean,
      disabled: Boolean,
      rows: Number,
      maxRows: Number,
      placeholder: String,
      fixedPositionDropdown: Boolean,
      moveToRoot: Boolean,
      text: {
        type: String,
        notify: true,
        observer: '_handleTextChanged',
      },
      backgroundColor: {
        type: String,
        value: '#fff',
      },
      hideBorder: {
        type: Boolean,
        value: false,
      },
      monospace: {
        type: Boolean,
        value: false,
      },
      _colonIndex: Number,
      _currentSearchString: {
        type: String,
        value: '',
        observer: '_determineSuggestions',
      },
      _hideAutocomplete: {
        type: Boolean,
        value: true,
      },
      _index: Number,
      _suggestions: Array,
    },

    behaviors: [
      Gerrit.KeyboardShortcutBehavior,
    ],

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

    ready() {
      this._resetEmojiDropdown();
      if (this.monospace) {
        this.classList.add('monospace');
      }
      if (this.hideBorder) {
        this.$.textarea.classList.add('noBorder');
      }
      if (this.backgroundColor) {
        this.customStyle['--background-color'] = this.backgroundColor;
        this.updateStyles();
      }
      this.listen(this.$.emojiSuggestions, 'dropdown-closed', '_resetAndFocus');
      this.listen(this.$.emojiSuggestions, 'item-selected',
          '_handleEmojiSelect');
    },

    detached() {
      this.closeDropdown();
      this.listen(this.$.emojiSuggestions, 'dropdown-closed', '_resetAndFocus');
      this.listen(this.$.emojiSuggestions, 'item-selected',
          '_handleEmojiSelect');
    },

    closeDropdown() {
      if (!this.$.emojiSuggestions.hidden) {
        this._closeEmojiDropdown();
      }
    },

    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._resetAndFocus();
    },

    _resetAndFocus() {
      this._resetEmojiDropdown();
      this.$.textarea.textarea.focus();
    },

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

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

    _handleEnterByKey(e) {
      if (this._hideAutocomplete) { return; }
      e.preventDefault();
      e.stopPropagation();
      this.text = this._getText(this.$.emojiSuggestions.getCurrentText());
      this._resetEmojiDropdown();
    },

    _handleEmojiSelect(e) {
      this.text = this._getText(e.detail.selected.dataset.value);
      this._resetEmojiDropdown();
    },

    _getText(value) {
      return this.text.substr(0, this._colonIndex) +
          value + this.text.substr(this.$.textarea.selectionStart) + ' ';
    },

    _getPositionOfCursor() {
      this.$.hiddenText.textContent = this.$.textarea.value.substr(0,
          this.$.textarea.selectionStart);

      const caratSpan = document.createElement('span');
      this.$.hiddenText.appendChild(caratSpan);
      return caratSpan.getBoundingClientRect();
    },

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

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

    /**
     * This positions the dropdown to be just below the cursor position. It is
     * calculated by having a hidden element with the same width and styling of
     * the tetarea and the text up until the point of interest. Then a span
     * element is added to the end so that there is a specific element to get
     * the position of.  Line height is determined (or falls back to 12px) as
     * extra height to add.
     */
    _updateSelectorPosition() {
      // These are broken out into separate functions for testability.
      const caratPosition = this._getPositionOfCursor();
      const fontSize = this._getFontSize();

      let top = caratPosition.top + fontSize + VERTICAL_OFFSET;

      if (!this.fixedPositionDropdown) {
        top += this._getScrollTop();
      }
      top += 'px';
      const left = caratPosition.left + 'px';
      this.$.emojiSuggestions.setPosition(top, left);
    },

    /**
     * _handleKeydown used for key handling in the this.$.textarea AND all child
     * autocomplete options.
     */
    _onValueChanged(e) {
      // If cursor is not in textarea (just opened with colon as last char),
      // Don't do anything.
      if (!e.currentTarget.focused) { return; }
      const newChar = e.detail.value[this.$.textarea.selectionStart - 1];

      // When a colon is detected, set a colon index, but don't do anything else
      // yet.
      if (newChar === ':') {
        this._colonIndex = this.$.textarea.selectionStart - 1;
      // If the colon index exists, continue to determine what needs to be done
      // with the dropdown. It may be open or closed at this point.
      } else if (this._colonIndex !== null) {
        // The search string is a substring of the textarea's value from (1
        // position after) the colon index to the cursor position.
        this._currentSearchString = e.detail.value.substr(this._colonIndex + 1,
            this.$.textarea.selectionStart);
        // 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.hidden) {
          this._hideAutocomplete = false;
          this._openEmojiDropdown();
          this._updateSelectorPosition();
        }
        this.$.textarea.textarea.focus();
      }
    },

    _closeEmojiDropdown() {
      this.$.emojiSuggestions.close();
      this.$.emojiSuggestions.hidden = true;
    },

    _openEmojiDropdown() {
      this.$.emojiSuggestions.open();
      this.$.emojiSuggestions.hidden = false;
    },

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

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

    _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}}));
    },
  });
})();
