/* Copyright 2016 The Chromium Authors. All Rights Reserved.
 *
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file or at
 * https://developers.google.com/open-source/licenses/bsd
 */

/**
 * An autocomplete library for javascript.
 * Public API
 * - _ac_install() install global handlers required for everything else to
 *   function.
 * - _ac_register(SC) register a store constructor (see below)
 * - _ac_isCompleting() true iff focus is in an auto complete box and the user
 *   has triggered completion with a keystroke, and completion has not been
 *   cancelled (programatically or otherwise).
 * - _ac_isCompleteListShowing() true if _as_isCompleting and the complete list
 *   is visible to the user.
 * - _ac_cancel() if completing, stop it, otherwise a no-op.
 *
 *
 * A quick example
 *     // an auto complete store
 *     var myFavoritestAutoCompleteStore = new _AC_SimpleStore(
 *       ['some', 'strings', 'to', 'complete']);
 *
 *     // a store constructor
 *     _ac_register(function (inputNode, keyEvent) {
 *         if (inputNode.id == 'my-auto-completing-check-box') {
 *           return myFavoritestAutoCompleteStore;
 *         }
 *         return null;
 *       });
 *
 *     <html>
 *       <head>
 *         <script type=text/javascript src=ac.js></script>
 *       </head>
 *       <body onload=_ac_install()>
 *         <!-- the constructor above looks at the id.  It could as easily
 *            - look at the class, name, or value.
 *            - The autocomplete=off stops browser autocomplete from
 *            - interfering with our autocomplete
 *           -->
 *         <input type=text id="my-auto-completing-check-box"
 *          autocomplete=off>
 *       </body>
 *     </html>
 *
 *
 * Concepts
 * - Store Constructor function
 *   A store constructor is a policy function with the signature
 *     _AC_Store myStoreConstructor(
 *       HtmlInputElement|HtmlTextAreaElement inputNode, Event keyEvent)
 *   When a key event is received on a text input or text area, the autocomplete
 *   library will try each of the store constructors in turn until it finds one
 *   that returns an AC_Store which will be used for auto-completion of that
 *   text box until focus is lost.
 *
 * - interface _AC_Store
 *   An autocomplete store encapsulates all operations that affect how a
 *   particular text node is autocompleted.  It has the following operations:
 *   - String completable(String inputValue, int caret)
 *     This method returns null if not completable or the section of inputValue
 *     that is subject to completion.  If autocomplete works on items in a
 *     comma separated list, then the input value "foo, ba" might yield "ba"
 *     as the completable chunk since it is separated from its predecessor by
 *     a comma.
 *     caret is the position of the text cursor (caret) in the text input.
 *   - _AC_Completion[] completions(String completable,
 *                                  _AC_Completion[] toFilter)
 *     This method returns null if there are no completions.  If toFilter is
 *     not null or undefined, then this method may assume that toFilter was
 *     returned as a set of completions that contain completable.
 *   - String substitute(String inputValue, int caret,
 *                       String completable, _AC_Completion completion)
 *     returns the inputValue with the given completion substituted for the
 *     given completable.  caret has the same meaning as in the
 *     completable operation.
 *   - String oncomplete(boolean completed, String key,
 *                       HTMLElement element, String text)
 *     This method is called when the user hits a completion key. The default
 *     value is to do nothing, but you can override it if you want. Note that
 *     key will be null if the user clicked on it to select
 *   - Boolean autoselectFirstRow()
 *     This method returns True by default, but subclasses can override it
 *     to make autocomplete fields that require the user to press the down
 *     arrow or do a mouseover once before any completion option is considered
 *     to be selected.
 *
 * - class _AC_SimpleStore
 *   An implementation of _AC_Store that completes a set of strings given at
 *   construct time in a text field with a comma separated value.
 *
 * - struct _AC_Completion
 *   a struct with two fields
 *   - String value : the plain text completion value
 *   - String html : the value, as html, with the completable in bold.
 *
 * Key Handling
 * Several keys affect completion in an autocompleted input.
 * ESC - the escape key cancels autocompleting.  The autocompletion will have
 *   no effect on the focused textbox until it loses focus, regains it, and
 *   a key is pressed.
 * ENTER - completes using the currently selected completion, or if there is
 *   only one, uses that completion.
 * UP ARROW - selects the completion above the current selection.
 * DOWN ARROW - selects the completion below the current selection.
 *
 *
 * CSS styles
 * The following CSS selector rules can be used to change the completion list
 * look:
 * #ac-list               style of the auto-complete list
 * #ac-list .selected     style of the selected item
 * #ac-list b             style of the matching text in a candidate completion
 *
 * Dependencies
 * The library depends on the following libraries:
 * javascript:base for definition of key constants and SetCursorPos
 * javascript:shapes for nodeBounds()
 */

/**
 * install global handlers required for the rest of the module to function.
 */
function _ac_install() {
  ac_addHandler_(document.body, 'onkeydown', ac_keyevent_);
  ac_addHandler_(document.body, 'onkeypress', ac_keyevent_);
}

/**
 * register a store constructor
 * @param storeConstructor a function like
 *   _AC_Store myStoreConstructor(HtmlInputElement|HtmlTextArea, Event)
 */
function _ac_register(storeConstructor) {
  // check that not already registered
  for (let i = ac_storeConstructors.length; --i >= 0;) {
    if (ac_storeConstructors[i] === storeConstructor) {
      return;
    }
  }
  ac_storeConstructors.push(storeConstructor);
}

/**
 * may be attached as an onfocus handler to a text input to popup autocomplete
 * immediately on the box gaining focus.
 */
function _ac_onfocus(event) {
  ac_keyevent_(event);
}

/**
 * true iff the autocomplete widget is currently active.
 */
function _ac_isCompleting() {
  return !!ac_store && !ac_suppressCompletions;
}

/**
 * true iff the completion list is displayed.
 */
function _ac_isCompleteListShowing() {
  return !!ac_store && !ac_suppressCompletions && ac_completions &&
    ac_completions.length;
}

/**
 * cancel any autocomplete in progress.
 */
function _ac_cancel() {
  ac_suppressCompletions = true;
  ac_updateCompletionList(false);
}

/** add a handler without whacking any existing handler. @private */
function ac_addHandler_(node, handlerName, handler) {
  const oldHandler = node[handlerName];
  if (!oldHandler) {
    node[handlerName] = handler;
  } else {
    node[handlerName] = ac_fnchain_(node[handlerName], handler);
  }
  return oldHandler;
}

/** cancel the event. @private */
function ac_cancelEvent_(event) {
  if ('stopPropagation' in event) {
    event.stopPropagation();
  } else {
    event.cancelBubble = true;
  }

  // This is handled in IE by returning false from the handler
  if ('preventDefault' in event) {
    event.preventDefault();
  }
}

/** Call two functions, a and b, and return false if either one returns
    false.  This is used as a primitive way to attach multiple event
    handlers to an element without using addEventListener().   This
    library predates the availablity of addEventListener().
    @private
*/
function ac_fnchain_(a, b) {
  return function() {
    const ar = a.apply(this, arguments);
    const br = b.apply(this, arguments);

    // NOTE 1: (undefined && false) -> undefined
    // NOTE 2: returning FALSE from a onkeypressed cancels it,
    //         returning UNDEFINED does not.
    // As such, we specifically look for falses here
    if (ar === false || br === false) {
      return false;
    } else {
      return true;
    }
  };
}

/** key press handler.  @private */
function ac_keyevent_(event) {
  event = event || window.event;

  const source = getTargetFromEvent(event);
  const isInput = 'INPUT' == source.tagName &&
    source.type.match(/^text|email$/i);
  const isTextarea = 'TEXTAREA' == source.tagName;
  if (!isInput && !isTextarea) return true;

  const key = event.key;
  const isDown = event.type == 'keydown';
  const isShiftKey = event.shiftKey;
  let storeFound = true;

  if ((source !== ac_focusedInput) || (ac_store === null)) {
    ac_focusedInput = source;
    storeFound = false;
    if (ENTER_KEYNAME !== key && ESC_KEYNAME !== key) {
      for (let i = 0; i < ac_storeConstructors.length; ++i) {
        const store = (ac_storeConstructors[i])(source, event);
        if (store) {
          ac_store = store;
          ac_store.setAvoid(event);
          ac_oldBlurHandler = ac_addHandler_(
              ac_focusedInput, 'onblur', _ac_ob);
          storeFound = true;
          break;
        }
      }

      // There exists an odd condition where an edit box with autocomplete
      // attached can be removed from the DOM without blur being called
      // In which case we are left with a store around that will try to
      // autocomplete the next edit box to receive focus. We need to clean
      // this up

      // If we can't find a store, force a blur
      if (!storeFound) {
        _ac_ob(null);
      }
    }
    // ac-table rows need to be removed when switching to another input.
    ac_updateCompletionList(false);
  }
  // If the user typed Esc when the auto-complete menu was not shown,
  // then blur the input text field so that the user can use keyboard
  // shortcuts.
  const acList = document.getElementById('ac-list');
  if (ESC_KEYNAME == key &&
      (!acList || acList.style.display == 'none')) {
    ac_focusedInput.blur();
  }

  if (!storeFound) return true;

  const isCompletion = ac_store.isCompletionKey(key, isDown, isShiftKey);
  const hasResults = ac_completions && (ac_completions.length > 0);
  let cancelEvent = false;

  if (isCompletion && hasResults) {
    // Cancel any enter keystrokes if something is selected so that the
    // browser doesn't go submitting the form.
    cancelEvent = (!ac_suppressCompletions && !!ac_completions &&
                      (ac_selected != -1));
    window.setTimeout(function() {
      if (ac_store) {
        ac_handleKey_(key, isDown, isShiftKey);
      }
    }, 0);
  } else if (!isCompletion) {
    // Don't want to also blur the field. Up and down move the cursor (in
    // Firefox) to the start/end of the field. We also don't want that while
    // the list is showing.
    cancelEvent = (key == ESC_KEYNAME ||
                  key == DOWN_KEYNAME ||
                  key == UP_KEYNAME);

    window.setTimeout(function() {
      if (ac_store) {
        ac_handleKey_(key, isDown, isShiftKey);
      }
    }, 0);
  } else { // implicit if (isCompletion && !hasResults)
    if (ac_store.oncomplete) {
      ac_store.oncomplete(false, key, ac_focusedInput, undefined);
    }
  }

  if (cancelEvent) {
    ac_cancelEvent_(event);
  }

  return !cancelEvent;
}

/** Autocomplete onblur handler. */
function _ac_ob(event) {
  if (ac_focusedInput) {
    ac_focusedInput.onblur = ac_oldBlurHandler;
  }
  ac_store = null;
  ac_focusedInput = null;
  ac_everTyped = false;
  ac_oldBlurHandler = null;
  ac_suppressCompletions = false;
  ac_updateCompletionList(false);
}

/** @constructor */
function _AC_Store() {
}
/** returns the chunk of the input to treat as completable. */
_AC_Store.prototype.completable = function(inputValue, caret) {
  console.log('UNIMPLEMENTED completable');
};
/** returns the chunk of the input to treat as completable. */
_AC_Store.prototype.completions = function(prefix, tofilter) {
  console.log('UNIMPLEMENTED completions');
};
/** returns the chunk of the input to treat as completable. */
_AC_Store.prototype.oncomplete = function(completed, key, element, text) {
  // Call the onkeyup handler so that choosing an autocomplete option has
  // the same side-effect as typing.  E.g., exposing the next row of input
  // fields.
  element.dispatchEvent(new Event('keyup'));
  _ac_ob();
};
/** substitutes a completion for a completable in a text input's value. */
_AC_Store.prototype.substitute =
  function(inputValue, caret, completable, completion) {
    console.log('UNIMPLEMENTED substitute');
  };
/** true iff hitting a comma key should complete. */
_AC_Store.prototype.commaCompletes = true;
/**
 * true iff the given keystroke should cause a completion (and be consumed in
 * the process.
 */
_AC_Store.prototype.isCompletionKey = function(key, isDown, isShiftKey) {
  if (!isDown && (ENTER_KEYNAME === key ||
                  (COMMA_KEYNAME == key && this.commaCompletes))) {
    return true;
  }
  if (TAB_KEYNAME === key && !isShiftKey) {
    // IE doesn't fire an event for tab on click in a text field, and firefox
    // requires that the onkeypress event for tab be consumed or it navigates
    // to next field.
    return false;
    // JER: return isDown == BR_IsIE();
  }
  return false;
};

_AC_Store.prototype.setAvoid = function(event) {
  if (event && event.avoidValues) {
    ac_avoidValues = event.avoidValues;
  } else {
    ac_avoidValues = this.computeAvoid();
  }
  ac_avoidValues = ac_avoidValues.map((val) => val.toLowerCase());
};

/* Subclasses may implement this to compute values to avoid
   offering in the current input field, i.e., because those
   values are already used. */
_AC_Store.prototype.computeAvoid = function() {
  return [];
};


function _AC_AddItemToFirstCharMap(firstCharMap, ch, s) {
  let l = firstCharMap[ch];
  if (!l) {
    l = firstCharMap[ch] = [];
  } else if (l[l.length - 1].value == s) {
    return;
  }
  l.push(new _AC_Completion(s, null, ''));
}

/**
 * an _AC_Store implementation suitable for completing lists of email
 * addresses.
 * @constructor
 */
function _AC_SimpleStore(strings, opt_docStrings) {
  this.firstCharMap_ = {};

  for (let i = 0; i < strings.length; ++i) {
    let s = strings[i];
    if (!s) {
      continue;
    }
    if (opt_docStrings && opt_docStrings[s]) {
      s = s + ' ' + opt_docStrings[s];
    }

    const parts = s.split(/\W+/);
    for (let j = 0; j < parts.length; ++j) {
      if (parts[j]) {
        _AC_AddItemToFirstCharMap(
            this.firstCharMap_, parts[j].charAt(0).toLowerCase(), strings[i]);
      }
    }
  }

  // The maximimum number of results that we are willing to show
  this.countThreshold = 2500;
  this.docstrings = opt_docStrings || {};
}
_AC_SimpleStore.prototype = new _AC_Store();
_AC_SimpleStore.prototype.constructor = _AC_SimpleStore;

_AC_SimpleStore.prototype.completable =
  function(inputValue, caret) {
  // complete after the last comma not inside ""s
    let start = 0;
    let state = 0;
    for (let i = 0; i < caret; ++i) {
      const ch = inputValue.charAt(i);
      switch (state) {
        case 0:
          if ('"' == ch) {
            state = 1;
          } else if (',' == ch || ' ' == ch) {
            start = i + 1;
          }
          break;
        case 1:
          if ('"' == ch) {
            state = 0;
          }
          break;
      }
    }
    while (start < caret &&
         ' \t\r\n'.indexOf(inputValue.charAt(start)) >= 0) {
      ++start;
    }
    return inputValue.substring(start, caret);
  };


/** Simple function to create a <span> with matching text in bold.
 */
function _AC_CreateSpanWithMatchHighlighted(match) {
  const span = document.createElement('span');
  span.appendChild(document.createTextNode(match[1] || ''));
  const bold = document.createElement('b');
  span.appendChild(bold);
  bold.appendChild(document.createTextNode(match[2]));
  span.appendChild(document.createTextNode(match[3] || ''));
  return span;
};


/**
 * Get all completions matching the given prefix.
 * @param {string} prefix The prefix of the text to autocomplete on.
 * @param {List.<string>?} toFilter Optional list to filter on. Otherwise will
 *     use this.firstCharMap_ using the prefix's first character.
 * @return {List.<_AC_Completion>} The computed list of completions.
 */
_AC_SimpleStore.prototype.completions = function(prefix) {
  if (!prefix) {
    return [];
  }
  toFilter = this.firstCharMap_[prefix.charAt(0).toLowerCase()];

  // Since we use prefix to build a regular expression, we need to escape RE
  // characters. We match '-', '{', '$' and others in the prefix and convert
  // them into "\-", "\{", "\$".
  const regexForRegexCharacters = /([\^*+\-\$\\\{\}\(\)\[\]\#?\.])/g;
  const modifiedPrefix = prefix.replace(regexForRegexCharacters, '\\$1');

  // Match the modifiedPrefix anywhere as long as it is either at the very
  // beginning "Th" -> "The Hobbit", or comes immediately after a word separator
  // such as "Ga" -> "The-Great-Gatsby".
  const patternRegex = '^(.*\\W)?(' + modifiedPrefix + ')(.*)';
  const pattern = new RegExp(patternRegex, 'i' /* ignore case */);

  // We keep separate lists of possible completions that were generated
  // by matching a value or generated by matching a docstring.  We return
  // a concatenated list so that value matches all come before docstring
  // matches.
  const completions = [];
  const docCompletions = [];

  if (toFilter) {
    const toFilterLength = toFilter.length;
    for (let i = 0; i < toFilterLength; ++i) {
      const docStr = this.docstrings[toFilter[i].value];
      let compSpan = null;
      let docSpan = null;
      const matches = toFilter[i].value.match(pattern);
      const docMatches = docStr && docStr.match(pattern);
      if (matches) {
        compSpan = _AC_CreateSpanWithMatchHighlighted(matches);
        if (docStr) docSpan = document.createTextNode(docStr);
      } else if (docMatches) {
        compSpan = document.createTextNode(toFilter[i].value);
        docSpan = _AC_CreateSpanWithMatchHighlighted(docMatches);
      }

      if (compSpan) {
        const newCompletion = new _AC_Completion(
            toFilter[i].value, compSpan, docSpan);

        if (matches) {
          completions.push(newCompletion);
        } else {
          docCompletions.push(newCompletion);
        }
        if (completions.length + docCompletions.length > this.countThreshold) {
          break;
        }
      }
    }
  }

  return completions.concat(docCompletions);
};

// Normally, when the user types a few characters, we aggressively
// select the first possible completion (if any).  When the user
// hits ENTER, that first completion is substituted.  When that
// behavior is not desired, override this to return false.
_AC_SimpleStore.prototype.autoselectFirstRow = function() {
  return true;
};

// Comparison function for _AC_Completion
function _AC_CompareACCompletion(a, b) {
  // convert it to lower case and remove all leading junk
  const aval = a.value.toLowerCase().replace(/^\W*/, '');
  const bval = b.value.toLowerCase().replace(/^\W*/, '');

  if (a.value === b.value) {
    return 0;
  } else if (aval < bval) {
    return -1;
  } else {
    return 1;
  }
}

_AC_SimpleStore.prototype.substitute =
function(inputValue, caret, completable, completion) {
  return inputValue.substring(0, caret - completable.length) +
    completion.value + ', ' + inputValue.substring(caret);
};

/**
 * a possible completion.
 * @constructor
 */
function _AC_Completion(value, compSpan, docSpan) {
  /** plain text. */
  this.value = value;
  if (typeof compSpan == 'string') compSpan = document.createTextNode(compSpan);
  this.compSpan = compSpan;
  if (typeof docSpan == 'string') docSpan = document.createTextNode(docSpan);
  this.docSpan = docSpan;
}
_AC_Completion.prototype.toString = function() {
  return '(AC_Completion: ' + this.value + ')';
};

/** registered store constructors.  @private */
var ac_storeConstructors = [];
/**
 * the focused text input or textarea whether store is null or not.
 * A text input may have focus and this may be null iff no key has been typed in
 * the text input.
 */
var ac_focusedInput = null;
/**
 * null or the autocomplete store used to complete ac_focusedInput.
 * @private
 */
var ac_store = null;
/** store handler from ac_focusedInput. @private */
var ac_oldBlurHandler = null;
/**
 * true iff user has indicated completions are unwanted (via ESC key)
 * @private
 */
var ac_suppressCompletions = false;
/**
 * chunk of completable text seen last keystroke.
 * Used to generate ac_completions.
 * @private
 */
let ac_lastCompletable = null;
/** an array of _AC_Completions.  @private */
var ac_completions = null;
/** -1 or in [0, _AC_Completions.length).  @private */
var ac_selected = -1;

/** Maximum number of options displayed in menu. @private */
const ac_max_options = 100;

/** Don't offer these values because they are already used. @private */
let ac_avoidValues = [];

/**
 * handles all the key strokes, updating the completion list, tracking selected
 * element, performing substitutions, etc.
 * @private
 */
function ac_handleKey_(key, isDown, isShiftKey) {
  // check completions
  ac_checkCompletions();
  let show = true;
  const numCompletions = ac_completions ? ac_completions.length : 0;
  // handle enter and tab on key press and the rest on key down
  if (ac_store.isCompletionKey(key, isDown, isShiftKey)) {
    if (ac_selected < 0 && numCompletions >= 1 &&
        ac_store.autoselectFirstRow()) {
      ac_selected = 0;
    }
    if (ac_selected >= 0) {
      const backupInput = ac_focusedInput;
      const completeValue = ac_completions[ac_selected].value;
      ac_complete();
      if (ac_store.oncomplete) {
        ac_store.oncomplete(true, key, backupInput, completeValue);
      }
    }
  } else {
    switch (key) {
      case ESC_KEYNAME: // escape
      // JER?? ac_suppressCompletions = true;
        ac_selected = -1;
        show = false;
        break;
      case UP_KEYNAME: // up
        if (isDown) {
        // firefox fires arrow events on both down and press, but IE only fires
        // then on press.
          ac_selected = Math.max(numCompletions >= 0 ? 0 : -1, ac_selected - 1);
        }
        break;
      case DOWN_KEYNAME: // down
        if (isDown) {
          ac_selected = Math.min(
              ac_max_options - 1, Math.min(numCompletions - 1, ac_selected + 1));
        }
        break;
    }

    if (isDown) {
      switch (key) {
        case ESC_KEYNAME:
        case ENTER_KEYNAME:
        case UP_KEYNAME:
        case DOWN_KEYNAME:
        case RIGHT_KEYNAME:
        case LEFT_KEYNAME:
        case TAB_KEYNAME:
        case SHIFT_KEYNAME:
        case BACKSPACE_KEYNAME:
        case DELETE_KEYNAME:
          break;
        default: // User typed some new characters.
          ac_everTyped = true;
      }
    }
  }

  if (ac_focusedInput) {
    ac_updateCompletionList(show);
  }
}

/**
 * called when an option is clicked on to select that option.
 */
function _ac_select(optionIndex) {
  ac_selected = optionIndex;
  ac_complete();
  if (ac_store.oncomplete) {
    ac_store.oncomplete(true, null, ac_focusedInput, ac_focusedInput.value);
  }

  // check completions
  ac_checkCompletions();
  ac_updateCompletionList(true);
}

function _ac_mouseover(optionIndex) {
  ac_selected = optionIndex;
  ac_updateCompletionList(true);
}

/** perform the substitution of the currently selected item. */
function ac_complete() {
  const caret = ac_getCaretPosition_(ac_focusedInput);
  const completion = ac_completions[ac_selected];

  ac_focusedInput.value = ac_store.substitute(
      ac_focusedInput.value, caret,
      ac_lastCompletable, completion);
  // When the prefix starts with '*' we want to return the complete set of all
  // possible completions. We treat the ac_lastCompletable value as empty so
  // that the caret is correctly calculated (i.e. the caret should not consider
  // placeholder values like '*member').
  let new_caret = caret + completion.value.length;
  if (!ac_lastCompletable.startsWith('*')) {
    // Only consider the ac_lastCompletable length if it does not start with '*'
    new_caret = new_caret - ac_lastCompletable.length;
  }
  // If we inserted something ending in two quotation marks, position
  // the cursor between the quotation marks. If we inserted a complete term,
  // skip over the trailing space so that the user is ready to enter the next
  // term.  If we inserted just a search operator, leave the cursor immediately
  // after the colon or equals and don't skip over the space.
  if (completion.value.substring(completion.value.length - 2) == '""') {
    new_caret--;
  } else if (completion.value.substring(completion.value.length - 1) != ':' &&
             completion.value.substring(completion.value.length - 1) != '=') {
    new_caret++; // To account for the comma.
    new_caret++; // To account for the space after the comma.
  }
  ac_selected = -1;
  ac_completions = null;
  ac_lastCompletable = null;
  ac_everTyped = false;
  SetCursorPos(window, ac_focusedInput, new_caret);
}

/**
 * True if the user has ever typed any actual characters in the currently
 * focused text field.  False if they have only clicked, backspaced, and
 * used the arrow keys.
 */
var ac_everTyped = false;

/**
 * maintains ac_completions, ac_selected, ac_lastCompletable.
 * @private
 */
function ac_checkCompletions() {
  if (ac_focusedInput && !ac_suppressCompletions) {
    const caret = ac_getCaretPosition_(ac_focusedInput);
    const completable = ac_store.completable(ac_focusedInput.value, caret);

    // If we already have completed, then our work here is done.
    if (completable == ac_lastCompletable) {
      return;
    }

    ac_completions = null;
    ac_selected = -1;

    const oldSelected =
      ((ac_selected >= 0 && ac_selected < ac_completions.length) ?
        ac_completions[ac_selected].value : null);
    ac_completions = ac_store.completions(completable);
    // Don't offer options for values that the user has already used
    // in another part of the current form.
    ac_completions = ac_completions.filter((comp) =>
      FindInArray(ac_avoidValues, comp.value.toLowerCase()) === -1);

    ac_selected = oldSelected ? 0 : -1;
    ac_lastCompletable = completable;
    return;
  }
  ac_lastCompletable = null;
  ac_completions = null;
  ac_selected = -1;
}

/**
 * maintains the completion list GUI.
 * @private
 */
function ac_updateCompletionList(show) {
  let clist = document.getElementById('ac-list');
  const input = ac_focusedInput;
  if (input) {
    input.setAttribute('aria-activedescendant', 'ac-status-row-none');
  }
  let tableEl;
  let tableBody;
  if (show && ac_completions && ac_completions.length) {
    if (!clist) {
      clist = document.createElement('DIV');
      clist.id = 'ac-list';
      clist.style.position = 'absolute';
      clist.style.display = 'none';
      // with 'listbox' and 'option' roles, screenreader narrates total
      // number of options eg. 'New = issue has not .... 1 of 9'
      document.body.appendChild(clist);
      tableEl = document.createElement('table');
      tableEl.setAttribute('cellpadding', 0);
      tableEl.setAttribute('cellspacing', 0);
      tableEl.id = 'ac-table';
      tableEl.setAttribute('role', 'presentation');
      tableBody = document.createElement('tbody');
      tableBody.id = 'ac-table-body';
      tableEl.appendChild(tableBody);
      tableBody.setAttribute('role', 'listbox');
      clist.appendChild(tableEl);
      input.setAttribute('aria-controls', 'ac-table');
      input.setAttribute('aria-haspopup', 'grid');
    } else {
      tableEl = document.getElementById('ac-table');
      tableBody = document.getElementById('ac-table-body');
      while (tableBody.childNodes.length) {
        tableBody.removeChild(tableBody.childNodes[0]);
      }
    }

    // If no choice is selected, then select the first item, if desired.
    if (ac_selected < 0 && ac_store && ac_store.autoselectFirstRow()) {
      ac_selected = 0;
    }

    let headerCount= 0;
    for (let i = 0; i < Math.min(ac_max_options, ac_completions.length); ++i) {
      if (ac_completions[i].heading) {
        var rowEl = document.createElement('tr');
        tableBody.appendChild(rowEl);
        const cellEl = document.createElement('th');
        rowEl.appendChild(cellEl);
        cellEl.setAttribute('colspan', 2);
        if (headerCount) {
          cellEl.appendChild(document.createElement('br'));
        }
        cellEl.appendChild(
            document.createTextNode(ac_completions[i].heading));
        headerCount++;
      } else {
        var rowEl = document.createElement('tr');
        tableBody.appendChild(rowEl);
        if (i == ac_selected) {
          rowEl.className = 'selected';
        }
        rowEl.id = `ac-status-row-${i}`;
        rowEl.setAttribute('data-index', i);
        rowEl.setAttribute('role', 'option');
        rowEl.addEventListener('mousedown', function(event) {
          event.preventDefault();
        });
        rowEl.addEventListener('mouseup', function(event) {
          let target = event.target;
          while (target && target.tagName != 'TR') {
            target = target.parentNode;
          }
          const idx = Number(target.getAttribute('data-index'));
          try {
            _ac_select(idx);
          } finally {
            return false;
          }
        });
        rowEl.addEventListener('mouseover', function(event) {
          let target = event.target;
          while (target && target.tagName != 'TR') {
            target = target.parentNode;
          }
          const idx = Number(target.getAttribute('data-index'));
          _ac_mouseover(idx);
        });
        const valCellEl = document.createElement('td');
        rowEl.appendChild(valCellEl);
        if (ac_completions[i].compSpan) {
          valCellEl.appendChild(ac_completions[i].compSpan);
        }
        const docCellEl = document.createElement('td');
        rowEl.appendChild(docCellEl);
        if (ac_completions[i].docSpan &&
            ac_completions[i].docSpan.textContent) {
          docCellEl.appendChild(document.createTextNode(' = '));
          docCellEl.appendChild(ac_completions[i].docSpan);
        }
      }
    }

    // position
    const inputBounds = nodeBounds(ac_focusedInput);
    clist.style.left = inputBounds.x + 'px';
    clist.style.top = (inputBounds.y + inputBounds.h) + 'px';

    window.setTimeout(ac_autoscroll, 100);
    input.setAttribute('aria-activedescendant', `ac-status-row-${ac_selected}`);
    // Note - we use '' instead of 'block', since 'block' has odd effects on
    // the screen in IE, and causes scrollbars to resize
    clist.style.display = '';
  } else {
    tableBody = document.getElementById('ac-table-body');
    if (clist && tableBody) {
      clist.style.display = 'none';
      while (tableBody.childNodes.length) {
        tableBody.removeChild(tableBody.childNodes[0]);
      }
    }
  }
}

// TODO(jrobbins): make arrow keys and mouse not conflict if they are
// used at the same time.


/** Scroll the autocomplete menu to show the currently selected row. */
function ac_autoscroll() {
  const acList = document.getElementById('ac-list');
  const acSelRow = acList.getElementsByClassName('selected')[0];
  const acSelRowTop = acSelRow ? acSelRow.offsetTop : 0;
  const acSelRowHeight = acSelRow ? acSelRow.offsetHeight : 0;


  const EXTRA = 8; // Go an extra few pixels so the next row is partly exposed.

  if (!acList || !acSelRow) return;

  // Autoscroll upward if the selected item is above the visible area,
  // else autoscroll downward if the selected item is below the visible area.
  if (acSelRowTop < acList.scrollTop) {
    acList.scrollTop = acSelRowTop - EXTRA;
  } else if (acSelRowTop + acSelRowHeight + EXTRA >
             acList.scrollTop + acList.offsetHeight) {
    acList.scrollTop = (acSelRowTop + acSelRowHeight -
                        acList.offsetHeight + EXTRA);
  }
}


/** the position of the text caret in the given text field.
 *
 * @param textField an INPUT node with type=text or a TEXTAREA node
 * @return an index in [0, textField.value.length]
 */
function ac_getCaretPosition_(textField) {
  if ('INPUT' == textField.tagName) {
    let caret = textField.value.length;

    // chrome/firefox
    if (undefined != textField.selectionStart) {
      caret = textField.selectionEnd;

      // JER: Special treatment for issue status field that makes all
      // options show up more often
      if (textField.id.startsWith('status')) {
        caret = textField.selectionStart;
      }
      // ie
    } else if (document.selection) {
      // get an empty selection range
      const range = document.selection.createRange();
      const origSelectionLength = range.text.length;
      // Force selection start to 0 position
      range.moveStart('character', -caret);
      // the caret end position is the new selection length
      caret = range.text.length;

      // JER: Special treatment for issue status field that makes all
      // options show up more often
      if (textField.id.startsWith('status')) {
        // The amount that the selection grew when we forced start to
        // position 0 is == the original start position.
        caret = range.text.length - origSelectionLength;
      }
    }

    return caret;
  } else {
    // a textarea

    return GetCursorPos(window, textField);
  }
}

function getTargetFromEvent(event) {
  let targ = event.target || event.srcElement;
  if (targ.shadowRoot) {
    // Find the element within the shadowDOM.
    const path = event.path || event.composedPath();
    targ = path[0];
  }
  return targ;
}
