// Copyright (c) 2012 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.

#ifndef CEF_LIBCEF_BROWSER_NATIVE_NATIVE_MENU_WIN_H_
#define CEF_LIBCEF_BROWSER_NATIVE_NATIVE_MENU_WIN_H_

#include <memory>
#include <vector>

#include "libcef/browser/native/menu_wrapper.h"

#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/strings/string16.h"

namespace ui {
class MenuModel;
}

namespace views {

// A Windows implementation of MenuWrapper.
// TODO(beng): rename to MenuWin once the old class is dead.
class CefNativeMenuWin : public MenuWrapper {
 public:
  // Construct a CefNativeMenuWin, with a model and delegate. If
  // |system_menu_for| is non-NULL, the CefNativeMenuWin wraps the system menu
  // for that window.
  // The caller owns the model and the delegate.
  CefNativeMenuWin(ui::MenuModel* model, HWND system_menu_for);
  ~CefNativeMenuWin() override;

  // Overridden from MenuWrapper:
  void RunMenuAt(const gfx::Point& point, int alignment) override;
  void CancelMenu() override;
  void Rebuild(MenuInsertionDelegateWin* delegate) override;
  void UpdateStates() override;
  HMENU GetNativeMenu() const override;
  MenuAction GetMenuAction() const override;
  void SetMinimumWidth(int width) override;

 private:
  // IMPORTANT: Note about indices.
  //            Functions in this class deal in two index spaces:
  //            1. menu_index - the index of an item within the actual Windows
  //               native menu.
  //            2. model_index - the index of the item within our model.
  //            These two are most often but not always the same value! The
  //            notable exception is when this object is used to wrap the
  //            Windows System Menu. In this instance, the model indices start
  //            at 0, but the insertion index into the existing menu is not.
  //            It is important to take this into consideration when editing the
  //            code in the functions in this class.

  struct HighlightedMenuItemInfo;

  // Returns true if the item at the specified index is a separator.
  bool IsSeparatorItemAt(int menu_index) const;

  // Add items. See note above about indices.
  void AddMenuItemAt(int menu_index, int model_index);
  void AddSeparatorItemAt(int menu_index, int model_index);

  // Sets the state of the item at the specified index.
  void SetMenuItemState(int menu_index,
                        bool enabled,
                        bool checked,
                        bool is_default);

  // Sets the label of the item at the specified index.
  void SetMenuItemLabel(int menu_index,
                        int model_index,
                        const base::string16& label);

  // Updates the local data structure with the correctly formatted version of
  // |label| at the specified model_index, and adds string data to |mii| if
  // the menu is not owner-draw. That's a mouthful. This function exists because
  // of the peculiarities of the Windows menu API.
  void UpdateMenuItemInfoForString(MENUITEMINFO* mii,
                                   int model_index,
                                   const base::string16& label);

  // Returns the alignment flags to be passed to TrackPopupMenuEx, based on the
  // supplied alignment and the UI text direction.
  UINT GetAlignmentFlags(int alignment) const;

  // Resets the native menu stored in |menu_| by destroying any old menu then
  // creating a new empty one.
  void ResetNativeMenu();

  // Creates the host window that receives notifications from the menu.
  void CreateHostWindow();

  // Callback from task to notify menu it was selected.
  void DelayedSelect();

  // Given a menu that's currently popped-up, find the currently highlighted
  // item. Returns true if a highlighted item was found.
  static bool GetHighlightedMenuItemInfo(HMENU menu,
                                         HighlightedMenuItemInfo* info);

  // Hook to receive keyboard events while the menu is open.
  static LRESULT CALLBACK MenuMessageHook(int n_code,
                                          WPARAM w_param,
                                          LPARAM l_param);

  // Our attached model and delegate.
  ui::MenuModel* model_;

  HMENU menu_;

  // True if the contents of menu items in this menu are drawn by the menu host
  // window, rather than Windows.
  bool owner_draw_;

  // An object that collects all of the data associated with an individual menu
  // item.
  struct ItemData;
  typedef std::vector<std::unique_ptr<ItemData>> ItemDataList;
  ItemDataList items_;

  // The window that receives notifications from the menu.
  class MenuHostWindow;
  friend MenuHostWindow;
  std::unique_ptr<MenuHostWindow> host_window_;

  // The HWND this menu is the system menu for, or NULL if the menu is not a
  // system menu.
  HWND system_menu_for_;

  // The index of the first item in the model in the menu.
  int first_item_index_;

  // The action that took place during the call to RunMenuAt.
  MenuAction menu_action_;

  // See comment in MenuMessageHook for details on these.
  CefNativeMenuWin* menu_to_select_;
  int position_to_select_;

  // If we're a submenu, this is our parent.
  CefNativeMenuWin* parent_;

  // If non-null the destructor sets this to true. This is set to non-null while
  // the menu is showing. It is used to detect if the menu was deleted while
  // running.
  bool* destroyed_flag_;

  base::WeakPtrFactory<CefNativeMenuWin> menu_to_select_factory_;

  // Ugly: a static pointer to the instance of this class that currently
  // has a menu open, because our hook function that receives keyboard
  // events doesn't have a mechanism to get a user data pointer.
  static CefNativeMenuWin* open_native_menu_win_;

  DISALLOW_COPY_AND_ASSIGN(CefNativeMenuWin);
};

}  // namespace views

#endif  // CEF_LIBCEF_BROWSER_NATIVE_NATIVE_MENU_WIN_H_
