// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_POPUP_SELECTION_H_
#define COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_POPUP_SELECTION_H_

#include <stddef.h>

#include <tuple>
#include <vector>

class AutocompleteProviderClient;
class AutocompleteResult;
class AutocompleteInput;
class TemplateURLService;

struct OmniboxPopupSelection {
  // Directions for stepping through selections. These may apply for going
  // up/down by lines or cycling left/right through states within a line.
  enum Direction { kForward, kBackward };

  // When changing selections, these are the possible stepping behaviors.
  enum Step {
    // Step by an entire line regardless of line state. Usually used for the
    // Up and Down arrow keys.
    kWholeLine,

    // Step by a state if another one is available on the current line;
    // otherwise step by line. Usually used for the Tab and Shift+Tab keys.
    kStateOrLine,

    // Step across all lines to the first or last line. Usually used for the
    // PgUp and PgDn keys.
    kAllLines
  };

  // See `state` below for details. The order matters; earlier items will be
  // selected first when tabbing through the popup. They are not persisted
  // anywhere and can be freely changed.
  enum LineState {
    // NORMAL means the row is focused, and Enter key navigates to the match.
    NORMAL,

    // KEYWORD_MODE state is used when in Keyword mode.  If the keyword search
    // button is enabled, keyword mode is entered when the keyword button is
    // focused.
    KEYWORD_MODE,

    // FOCUSED_BUTTON_AIM state means that the AIM page action button in the
    // omnibox text field is focused.
    FOCUSED_BUTTON_AIM,

    // FOCUSED_BUTTON_ACTION state means an Action button (such as a Pedal)
    // is in focus.
    FOCUSED_BUTTON_ACTION,

    // FOCUSED_BUTTON_THUMBS_UP state means the thumbs up button is focused.
    FOCUSED_BUTTON_THUMBS_UP,

    // FOCUSED_BUTTON_THUMBS_DOWN state means the thumbs down button is focused.
    // Pressing enter will attempt to submit feedback form for this suggestion.
    FOCUSED_BUTTON_THUMBS_DOWN,

    // FOCUSED_BUTTON_REMOVE_SUGGESTION state means the Remove Suggestion (X)
    // button is focused. Pressing enter will attempt to remove this suggestion.
    FOCUSED_BUTTON_REMOVE_SUGGESTION,

    // `NULL_RESULT_MESSAGE` IPH match types are not normally focusable, but
    // their links still need to be tab-accessible, so this state is available
    // when such a match has an IPH URL link.
    FOCUSED_IPH_LINK,

    // Whenever new line state is added, accessibility label for current
    // selection should be revisited
    // (`OmniboxEditModel::GetPopupAccessibilityLabelForCurrentSelection()`).
    LINE_STATE_MAX_VALUE
  };

  // The sentinel value for `line` which means no line is selected.
  static const size_t kNoMatch;

  // The selected line. This is `kNoMatch` when nothing is selected, which
  // should only be true when a) the popup is closed or b) an empty suggestion
  // is selected (e.g. the default suggestion in zero-input mode).
  size_t line;

  // If the selected line has both a normal match and a keyword match, this
  // determines whether the normal match (if NORMAL) or the keyword match
  // (if KEYWORD) is selected. Likewise, if the selected line has a normal
  // match and a secondary button match, this determines whether the button
  // match (if FOCUSED_BUTTON_*) is selected.
  LineState state;

  // When `state` is `FOCUSED_BUTTON_ACTION`, this indicates which action
  // is selected by index into `AutocompleteMatch::actions`. Other states
  // keep an unused zero index.
  size_t action_index = 0u;

  explicit OmniboxPopupSelection(size_t line,
                                 LineState state = NORMAL,
                                 size_t action_index = 0)
      : line(line), state(state), action_index(action_index) {}

  friend bool operator==(const OmniboxPopupSelection&,
                         const OmniboxPopupSelection&) = default;

  // Special handling is required for ordering, since `kNoMatch` can have an
  // associated `FOCUSED_BUTTON_AIM` state and we need `kNoMatch` to be treated
  // as the smallest value while it is being represented as the maximum value of
  // size_t (static_cast<size_t>(-1)).
  friend std::strong_ordering operator<=>(const OmniboxPopupSelection& a,
                                          const OmniboxPopupSelection& b) {
    auto sort_key = [](const OmniboxPopupSelection& selection) {
      return std::make_tuple(selection.line == kNoMatch ? 0 : 1, selection.line,
                             selection.state, selection.action_index);
    };
    return sort_key(a) <=> sort_key(b);
  }

  // Returns true if going to this selection from given `from` selection
  // results in activation of keyword state when it wasn't active before.
  bool IsChangeToKeyword(OmniboxPopupSelection from) const;

  // Returns true if this selection represents a button being focused.
  bool IsButtonFocused() const;

  // Returns true if this selection represents taking an action.
  bool IsAction() const;

  // Returns true if the control represented by this selection's `state` is
  // present on the match for `line` in given `result`.
  bool IsControlPresentOnMatch(const AutocompleteResult& result) const;

  // Returns the next selection after this one in given `result`.
  OmniboxPopupSelection GetNextSelection(
      const AutocompleteInput& input,
      const AutocompleteResult& result,
      TemplateURLService* template_url_service,
      bool aim_button_visible,
      Direction direction,
      Step step) const;

 private:
  //  This is a utility function to support `GetNextSelection`.
  static std::vector<OmniboxPopupSelection> GetAllAvailableSelectionsSorted(
      const AutocompleteInput& input,
      const AutocompleteResult& result,
      TemplateURLService* template_url_service,
      bool aim_button_visible,
      Step step);
};

#endif  // COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_POPUP_SELECTION_H_
