// 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.

#include "base/callback.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chrome/test/base/view_event_test_base.h"
#include "ui/base/models/menu_model.h"
#include "ui/base/test/ui_controls.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/button/menu_button_listener.h"
#include "ui/views/controls/menu/menu_controller.h"
#include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/controls/menu/menu_model_adapter.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/controls/menu/submenu_view.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget.h"

namespace {

const int kTopMenuBaseId = 100;
const int kSubMenuBaseId = 200;

// Implement most of the ui::MenuModel pure virtual methods for subclasses
//
// Exceptions:
//  virtual int GetItemCount() const = 0;
//  virtual ItemType GetTypeAt(int index) const = 0;
//  virtual int GetCommandIdAt(int index) const = 0;
//  virtual base::string16 GetLabelAt(int index) const = 0;
class CommonMenuModel : public ui::MenuModel {
 public:
  CommonMenuModel() {
  }

  virtual ~CommonMenuModel() {
  }

 protected:
  // ui::MenuModel implementation.
  virtual bool HasIcons() const OVERRIDE {
    return false;
  }

  virtual bool IsItemDynamicAt(int index) const OVERRIDE {
    return false;
  }

  virtual bool GetAcceleratorAt(int index,
                                ui::Accelerator* accelerator) const OVERRIDE {
    return false;
  }

  virtual ui::MenuSeparatorType GetSeparatorTypeAt(int index) const OVERRIDE {
    return ui::NORMAL_SEPARATOR;
  }

  virtual bool IsItemCheckedAt(int index) const OVERRIDE {
    return false;
  }

  virtual int GetGroupIdAt(int index) const OVERRIDE {
    return 0;
  }

  virtual bool GetIconAt(int index, gfx::Image* icon) OVERRIDE {
    return false;
  }

  virtual ui::ButtonMenuItemModel* GetButtonMenuItemAt(
      int index) const OVERRIDE {
    return NULL;
  }

  virtual bool IsEnabledAt(int index) const OVERRIDE {
    return true;
  }

  virtual ui::MenuModel* GetSubmenuModelAt(int index) const OVERRIDE {
    return NULL;
  }

  virtual void HighlightChangedTo(int index) OVERRIDE {
  }

  virtual void ActivatedAt(int index) OVERRIDE {
  }

  virtual void SetMenuModelDelegate(ui::MenuModelDelegate* delegate) OVERRIDE {
  }

  virtual ui::MenuModelDelegate* GetMenuModelDelegate() const OVERRIDE {
    return NULL;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(CommonMenuModel);
};

class SubMenuModel : public CommonMenuModel {
 public:
  SubMenuModel()
      : showing_(false) {
  }

  virtual ~SubMenuModel() {
  }

  bool showing() const {
    return showing_;
  }

 private:
  // ui::MenuModel implementation.
  virtual int GetItemCount() const OVERRIDE {
    return 1;
  }

  virtual ItemType GetTypeAt(int index) const OVERRIDE {
    return TYPE_COMMAND;
  }

  virtual int GetCommandIdAt(int index) const OVERRIDE {
    return index + kSubMenuBaseId;
  }

  virtual base::string16 GetLabelAt(int index) const OVERRIDE {
    return base::ASCIIToUTF16("Item");
  }

  virtual void MenuWillShow() OVERRIDE {
    showing_ = true;
  }

  // Called when the menu has been closed.
  virtual void MenuClosed() OVERRIDE {
    showing_ = false;
  }

  bool showing_;

  DISALLOW_COPY_AND_ASSIGN(SubMenuModel);
};

class TopMenuModel : public CommonMenuModel {
 public:
  TopMenuModel() {
  }

  virtual ~TopMenuModel() {
  }

  bool IsSubmenuShowing() {
    return sub_menu_model_.showing();
  }

 private:
  // ui::MenuModel implementation.
  virtual int GetItemCount() const OVERRIDE {
    return 1;
  }

  virtual ItemType GetTypeAt(int index) const OVERRIDE {
    return TYPE_SUBMENU;
  }

  virtual int GetCommandIdAt(int index) const OVERRIDE {
    return index + kTopMenuBaseId;
  }

  virtual base::string16 GetLabelAt(int index) const OVERRIDE {
    return base::ASCIIToUTF16("submenu");
  }

  virtual MenuModel* GetSubmenuModelAt(int index) const OVERRIDE {
    return &sub_menu_model_;
  }

  mutable SubMenuModel sub_menu_model_;

  DISALLOW_COPY_AND_ASSIGN(TopMenuModel);
};

}  // namespace

class MenuModelAdapterTest : public ViewEventTestBase,
                             public views::MenuButtonListener {
 public:
  MenuModelAdapterTest()
      : ViewEventTestBase(),
        button_(NULL),
        menu_model_adapter_(&top_menu_model_),
        menu_(NULL) {
  }

  virtual ~MenuModelAdapterTest() {
  }

  // ViewEventTestBase implementation.

  virtual void SetUp() OVERRIDE {
    button_ = new views::MenuButton(
        NULL, base::ASCIIToUTF16("Menu Adapter Test"), this, true);

    menu_ = menu_model_adapter_.CreateMenu();
    menu_runner_.reset(
        new views::MenuRunner(menu_, views::MenuRunner::HAS_MNEMONICS));

    ViewEventTestBase::SetUp();
  }

  virtual void TearDown() OVERRIDE {
    menu_runner_.reset(NULL);
    menu_ = NULL;
    ViewEventTestBase::TearDown();
  }

  virtual views::View* CreateContentsView() OVERRIDE {
    return button_;
  }

  virtual gfx::Size GetPreferredSize() const OVERRIDE {
    return button_->GetPreferredSize();
  }

  // views::MenuButtonListener implementation.
  virtual void OnMenuButtonClicked(views::View* source,
                                   const gfx::Point& point) OVERRIDE {
    gfx::Point screen_location;
    views::View::ConvertPointToScreen(source, &screen_location);
    gfx::Rect bounds(screen_location, source->size());
    ignore_result(menu_runner_->RunMenuAt(source->GetWidget(),
                                          button_,
                                          bounds,
                                          views::MENU_ANCHOR_TOPLEFT,
                                          ui::MENU_SOURCE_NONE));
  }

  // ViewEventTestBase implementation
  virtual void DoTestOnMessageLoop() OVERRIDE {
    Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step1));
  }

  // Open the submenu.
  void Step1() {
    views::SubmenuView* topmenu = menu_->GetSubmenu();
    ASSERT_TRUE(topmenu);
    ASSERT_TRUE(topmenu->IsShowing());
    ASSERT_FALSE(top_menu_model_.IsSubmenuShowing());

    // Click the first item to open the submenu.
    views::MenuItemView* item = topmenu->GetMenuItemAt(0);
    ASSERT_TRUE(item);
    Click(item, CreateEventTask(this, &MenuModelAdapterTest::Step2));
  }

  // Rebuild the menu which should close the submenu.
  void Step2() {
    views::SubmenuView* topmenu = menu_->GetSubmenu();
    ASSERT_TRUE(topmenu);
    ASSERT_TRUE(topmenu->IsShowing());
    ASSERT_TRUE(top_menu_model_.IsSubmenuShowing());

    menu_model_adapter_.BuildMenu(menu_);

    base::MessageLoopForUI::current()->PostTask(
        FROM_HERE, CreateEventTask(this, &MenuModelAdapterTest::Step3));
  }

  // Verify that the submenu MenuModel received the close callback
  // and close the menu.
  void Step3() {
    views::SubmenuView* topmenu = menu_->GetSubmenu();
    ASSERT_TRUE(topmenu);
    ASSERT_TRUE(topmenu->IsShowing());
    ASSERT_FALSE(top_menu_model_.IsSubmenuShowing());

    // Click the button to exit the menu.
    Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step4));
  }

  // All done.
  void Step4() {
    views::SubmenuView* topmenu = menu_->GetSubmenu();
    ASSERT_TRUE(topmenu);
    ASSERT_FALSE(topmenu->IsShowing());
    ASSERT_FALSE(top_menu_model_.IsSubmenuShowing());

    Done();
  }

 private:
  // Generate a mouse click on the specified view and post a new task.
  virtual void Click(views::View* view, const base::Closure& next) {
    ui_test_utils::MoveMouseToCenterAndPress(
        view,
        ui_controls::LEFT,
        ui_controls::DOWN | ui_controls::UP,
        next);
  }

  views::MenuButton* button_;
  TopMenuModel top_menu_model_;
  views::MenuModelAdapter menu_model_adapter_;
  views::MenuItemView* menu_;
  scoped_ptr<views::MenuRunner> menu_runner_;
};

VIEW_TEST(MenuModelAdapterTest, RebuildMenu)
