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

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

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