<!--

`paper-autocomplete` extends `paper-input`, adding autocomplete functionality.
The current value is used to prefix-match against the labels of this element's
child nodes (either `core-item` or `paper-item`). Those that match are shown,
while those that fail to match are hidden. The suggested items can be selected
using keyboard and mouse input.

Example:
    <paper-autocomplete label="Country" on-change="{{changeHandler}}">
      <core-item label="United States></core-item>
      <core-item label="Canada"></core-item>
    </paper-autocomplete>

All attributes and events of paper-input are inherited by paper-autocomplete.

New Attributes:
    maxItems
    caseSensitive
    delimiter
    allowWhitespace

New Events:
    delete-item: An event indicating that the user wants a child item removed

-->

<polymer-element name="paper-autocomplete" extends="paper-input" attributes="maxItems caseSensitive delimiter allowWhitespace">
  <template>
    <link href="paper-autocomplete.css" rel="stylesheet">
    <div id="frame">
      <div id="top-input">
        <shadow></shadow>
      </div>
      <div id="bottom-suggest">
        <core-selector id="suggest-box" class="suggest-box-style hidden"
                       on-core-activate="{{selectAction}}">
          <content id="items" select="core-item,paper-item"></content>
        </core-selector>
      </div>
    </div>
  </template>
  <script>
    Polymer({
      /**
       * Maximum number of items to show in the suggestion box.
       * A null value indicates that there is no limit.
       *
       * @attribute: maxItems
       * @type: integer | null
       */
      maxItems: null,

      /**
       * Flag that indicates the case-sensitivity of prefix-matching.
       *
       * @attribute: caseSensitive
       * @type: boolean
       */
      caseSensitive: false,

      /**
       * If null, this element acts like a standard autocomplete unit.
       * If given a value, then instead of replacing the full text string,
       * this element will replace the substring after the last occurrence of
       * the delimiter. In effect, making this like a list selector.
       *
       * Example: delimiter === '' (Append-only)
       * When the text box has 'abcd', selecting 'ef' makes this 'abcdef'
       * This choice of delimiter prevents suggestions from being filtered.
       *
       * Example: delimiter === ',' (CSV-style list)
       * If the text box has 'red,orange,g', and 'green' is selected,
       * then the text box will have 'red,orange,green'.
       *
       * Some delimiters work well with dynamic child node suggestions.
       *
       * Example: delimiter === '/' (Directory path)
       * If the text box has 'drive/google/photos/' and 'May2012' is selected,
       * then the text box will have 'drive/google/photos/May2012'.
       *
       * @attribute: delimiter
       * @type: string | null
       */
      delimiter: null,

      /**
       * Set to true to tolerate whitespace when filtering suggestions.
       * Whitespace will also be maintained when a suggestion is selected.
       * Note: This attribute is only useful when there is a delimiter.
       *
       * Example: delimiter === ',' and allowWhitespace === true
       * If the text box has 'red, orange,  g' and 'green' is selected,
       * then the text box will have 'red, orange,  green'.
       *
       * @attribute: allowWhitespace
       * @type: boolean
       */
      allowWhitespace: false,

      /**
       * Whether this element is currently being edited or not. Becomes true
       * when the internal paper-input gains focus or receives input.
       *
       * @type: boolean
       */
      editing: false,

      /**
       * A special flag indicating that the suggestion box is going to close.
       */
      closing: false,

      /**
       * List of indexes of children that can be shown. The children are
       * filtered by the current value.
       *
       * @type: Array<integer>
       */
      showing: [],

      /**
       * Tracks the highlight position in the showing array. The corresponding
       * child node is highlighted with the 'highlighted' class.
       *
       * @type: int | null
       */
      highlightIndex: null,

      /**
       * Tracks the highlighted item's label. Used to update the highlight index
       * when the user types new characters.
       *
       * @type: string | null
       */
      highlightLabel: null,

      /**
       * Called when this node is added to the DOM. Sets up event listeners
       * through the shadow DOM to its internal paper-input. Additionally,
       * watches for mutations in its light DOM children.
       */
      ready: function() {
        this.super();

        // Add listener to the suggestBox to cancel the suggestion box from
        // closing if the user starts to click on it.
        var suggestBox = this.$['suggest-box'];
        suggestBox.addEventListener(
          'mousedown',
          this.cancelClosing.bind(this)
        );

        // Listen to inputs to determine editing status.
        this.addEventListener('input', this.inputAction.bind(this));
        this.addEventListener('keydown', this.keydownAction.bind(this));
        this.addEventListener('focus', this.inputFocusAction.bind(this));
        this.addEventListener('blur', this.inputBlurAction.bind(this));

        // Capture changes to children
        this.watchMutation();
      },

      /**
       * Whenever the light DOM children change, then rerender this element.
       */
      watchMutation: function() {
          var change = function() {
            this.filterSuggestions();
            // Note: onMutation unbinds after each use, so we need to rebind.
            this.onMutation(this, change.bind(this));
          }
          this.onMutation(this, change.bind(this));
      },

      /**
       * Set the editing flag to true upon gaining focus.
       */
      inputFocusAction: function(e) {
        this.super(e);
        if (!this.closing) {
          this.editing = true;
        }
        this.closing = false;
        this.filterSuggestions();
      },

      /**
       * When blurring, potentially set editing to false.
       * Has a delay before the suggestion box is closed in case the user starts
       * to click on the suggestion box.
       */
      inputBlurAction: function(e) {
        this.super(e);

        this.closing = true;
        this.async(function() {
          if (this.closing) {
            this.showSuggestions(false);
            this.editing = false;
          }
        }, null, 100);
      },

      /**
       * If the mouse is pressed down on the suggestion box, set the closing
       * flag to false.
       */
      cancelClosing: function(e) {
        this.async(function() {
          if (this.closing) {
            this.closing = false;
          }
        }, null, 0);
      },

      /**
       * On the hidden input's 'input' event, the fact that data changed means
       * that the user is editing. Re-render the suggestions.
       */
      inputAction: function(e) {
        this.closing = false;
        this.editing = true;
        this.filterSuggestions();
      },

      /**
       * Filters the potential list of suggestions drawn from child node labels.
       * Use a prefixMatch to decide which child nodes to show/hide.
       * Finally, show the suggestion box if the conditions are right.
       */
      filterSuggestions: function() {
        var showing = [];
        var childNodes = this.$.items.getDistributedNodes();
        for (var i = 0; i < childNodes.length; i++) {
          var item = childNodes[i];

          // Show nodes with a prefix match, as long
          // as the maxItems limit has not been reached.
          if ((this.maxItems === null || showing.length < this.maxItems) &&
            this.prefixMatch(this.getItemLabel(item))) {

            showing.push(i);
            item.style.display = '';
          } else {
            item.style.display = 'none';
          }
        }
        this.showing = showing;

        this.highlightSeekIndex();
        this.showSuggestions(this.shouldShowSuggestions());
      },

      /**
       * Update the highlight index, using the highlight label and the shown
       * items. If there are no matches, reset the highlight variables.
       * Note: There may be false updates if the suggestion list contains
       * >1 of the same label.
       */
      highlightSeekIndex: function() {
        var found = false;
        var childNodes = this.$.items.getDistributedNodes();
        for (var i = 0; i < this.showing.length; i++) {
          var itemIndex = this.showing[i];
          var item = childNodes[itemIndex];

          if (!found && this.getItemLabel(item) === this.highlightLabel) {
            // There was a match; the new highlightIndex is the showing index.
            this.highlightIndex = i;
            found = true;
            item.classList.toggle('highlighted', true);
          } else {
            // This isn't a match, so reset highlighting, just in case.
            item.classList.toggle('highlighted', false);
          }
        }

        // If not found, then nothing should be highlighted.
        // Note: Cannot use highlightReset since the item may not exist at the
        // current highlightIndex.
        if (!found) {
          this.highlightIndex = null;
          this.highlightLabel = null;
        }
      },

      /**
       * Depending on the caseSensitive attribute, returns whether or not the
       * given word has a prefix match with the current value of this element.
       */
      prefixMatch: function(word) {
        var curValue = this.getInputValueSuffix();
        if (!this.caseSensitive) {
          return word.toLowerCase().indexOf(curValue.toLowerCase()) === 0;
        }
        return word.indexOf(curValue) === 0;
      },

      /**
       * Get the suffix of the current input value. If there is no delimiter,
       * then the full input value is used instead.
       */
      getInputValueSuffix: function() {
        var value = this.value || '';
        if (this.delimiter === '') {
          return '';
        } else if (!this.delimiter) {
          return value;
        }

        // Find the suffix.
        var parts = value.split(this.delimiter);
        var suffix = parts[parts.length - 1];

        // Handle excess whitespace.
        if (this.allowWhitespace) {
          return suffix.trimLeft();
        }
        return suffix;
      },

      /**
       * Gets the label out of the item for prefix-matching and replacement.
       * Note: paper-item and core-item mismatch; label is not available on the
       * former anymore.
       */
      getItemLabel: function(item) {
        return item.textContent || item.label;
      },

      /**
       * Determine whether or not the suggestBox should be shown.
       * Show if this node is being edited and there are valid suggestions.
       */
      shouldShowSuggestions: function() {
        return this.editing && this.showing.length > 0;
      },

      /**
       * The suggestion box is shown/hidden. If hidden, then additional internal
       * values are reset.
       */
      showSuggestions: function(shouldShow) {
        this.$['suggest-box'].classList.toggle('hidden', !shouldShow);
        if (!shouldShow) {
          this.highlightReset();
          this.closing = false;
        }
      },

      /**
       * Process the 'core-activate' event when a suggestion was tapped.
       */
      selectAction: function(e) {
        this.selectItem(e, e.detail.item);
      },

      /**
       * When an item in the suggestion list is clicked or 'enter' is pressed
       * while it is being highlighted, then replace this node's value.
       *
       * This node is no longer being edited, so re-render will hide it.
       * Note: Fires this element's 'input' and 'change' events.
       * Special: Click loses the element's focus, but pressing enter does not.
       */
      selectItem: function(e, item) {
        this.highlightReset();

        this.replaceValue(this.getItemLabel(item));

        this.fireInput();
        this.changeAction(e);

        this.showSuggestions(false);
        this.editing = false;
      },

      /**
       * Replace the current value and inputValue of this element.
       * If there is a delimiter, replace only the suffix.
       */
      replaceValue: function(newValue) {
        if (this.delimiter === '') {
          this.value += newValue;
        } else if (!this.delimiter) {
          this.value = newValue;
        } else {
          // Find the suffix.
          var parts = this.value.split(this.delimiter);
          var suffix = parts[parts.length - 1];

          // Compute the replacement, taking into account whitespace.
          var keepLength = 0;
          if (this.allowWhitespace) {
            keepLength = suffix.length - suffix.trimLeft().length
          }
          parts[parts.length - 1] = suffix.substring(0, keepLength) + newValue;

          // Replace the input value.
          this.value = parts.join(this.delimiter);
        }
      },

      /**
       * Fire the input event. (The invocation matches core-input's.)
       */
      fireInput: function() {
        this.fire('input', null, this);
      },

      /**
       * Fire the delete-item event with the corresponding child item.
       */
      fireDeleteItem: function(item) {
        this.fire('delete-item', null, item);
      },

      /**
       * Obtain the child item that is currently highlighted.
       */
      getHighlightedItem: function() {
        var selected = this.showing[this.highlightIndex];
        return this.$.items.getDistributedNodes()[selected];
      },

      /**
       * Remove highlight off the current item and stop tracking it.
       */
      highlightReset: function() {
        this.highlightItem(false);
        this.highlightIndex = null;
      },

      /**
       * Add/remove the highlighted class off the currently highlighted item.
       */
      highlightItem: function(shouldHighlight) {
          if (this.highlightIndex !== null) {
            var item = this.getHighlightedItem();
            item.classList.toggle('highlighted', shouldHighlight);
            this.highlightLabel = this.getItemLabel(item);
          } else {
            this.highlightLabel = null;
          }
      },

      /**
       * Pressing up and down change the currently highlighted item.
       * Pressing enter will select that item.
       * Pressing escape will close the suggestBox.
       * Pressing any other key will reset highlight.
       */
      keydownAction: function(e) {
        var KEY_DELETE = 46;
        var KEY_UP = 38;
        var KEY_DOWN = 40;
        var KEY_ENTER = 13;
        var KEY_ESC = 27;

        // The suggest box is not open.
        if (!this.shouldShowSuggestions()) {
          // If up or down was hit, potentially open the suggest box.
          if (e.keyCode === KEY_UP || e.keyCode === KEY_DOWN) {
            this.editing = true;
            this.showSuggestions(this.shouldShowSuggestions());
          }
          return;
        }

        // The suggest box is open. Handle the keypresses accordingly.
        switch(e.keyCode) {
          case KEY_DELETE:
            // Shift+Delete => fire a 'delete-item' event
            if (e.shiftKey === true && this.highlightIndex !== null) {
              this.fireDeleteItem(this.getHighlightedItem());
            }
            break;
          case KEY_UP: // Highlight the item above the current one.
            e.preventDefault();

            // unhighlight, change selection, highlight
            this.highlightItem(false);
            if (this.highlightIndex === null || this.highlightIndex === 0) {
              this.highlightIndex = this.showing.length - 1;
            } else {
              this.highlightIndex--;
            }
            this.highlightItem(true);
            break;
          case KEY_DOWN: // Highlight the item below the current one.
            e.preventDefault();

            // unhighlight, change selection, highlight
            this.highlightItem(false);
            if (this.highlightIndex === null ||
              this.highlightIndex === this.showing.length - 1) {

              this.highlightIndex = 0;
            } else {
              this.highlightIndex++;
            }
            this.highlightItem(true);
            break;
          case KEY_ENTER: // Activate the highlighted node, if any.
            if (this.highlightIndex !== null) {
              e.preventDefault(); // do not commit a change

              this.selectItem(e, this.getHighlightedItem());
            } else {
              this.showSuggestions(false);
              this.editing = false;
            }
            break;
          case KEY_ESC: // Hide the suggestions and reset the current highlight.
            this.showSuggestions(false);
            this.editing = false;
            break;
        }
      }
    });
  </script>
</polymer-element>