// 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/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_runner.h"
#include "ui/views/controls/menu/submenu_view.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget.h"

// This is a convenience base class for all tests to provide some
// common functionality.  It sets up a MenuButton and a MenuItemView
// and clicks the MenuButton.
//
// Subclasses should implement:
//  BuildMenu()            populate the menu
//  DoTestOnMessageLoop()  initiate the test
//
// Subclasses can call:
//  Click()       to post a mouse click on a View
//
// Although it should be possible to post a menu multiple times,
// MenuItemView prevents repeated activation of a menu by clicks too
// close in time.
class MenuItemViewTestBase : public ViewEventTestBase,
                             public views::MenuButtonListener,
                             public views::MenuDelegate {
 public:
  MenuItemViewTestBase()
      : ViewEventTestBase(),
        button_(NULL),
        menu_(NULL) {
  }

  virtual ~MenuItemViewTestBase() {
  }

  // ViewEventTestBase implementation.

  virtual void SetUp() OVERRIDE {
    button_ = new views::MenuButton(
        NULL, ASCIIToUTF16("Menu Test"), this, true);
    menu_ = new views::MenuItemView(this);
    BuildMenu(menu_);
    menu_runner_.reset(new views::MenuRunner(menu_));

    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() 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::MenuItemView::TOPLEFT,
        ui::MENU_SOURCE_NONE,
        views::MenuRunner::HAS_MNEMONICS));
  }

 protected:
  // 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);
  }

  virtual void BuildMenu(views::MenuItemView* menu) {
  }

  views::MenuButton* button_;
  views::MenuItemView* menu_;
  scoped_ptr<views::MenuRunner> menu_runner_;
};

// Simple test for clicking a menu item.  This template class clicks on an
// item and checks that the returned id matches.  The index of the item
// is the template argument.
template<int INDEX>
class MenuItemViewTestBasic : public MenuItemViewTestBase {
 public:
  MenuItemViewTestBasic() :
      last_command_(0) {
  }

  virtual ~MenuItemViewTestBasic() {
  }

  // views::MenuDelegate implementation
  virtual void ExecuteCommand(int id) OVERRIDE {
    last_command_ = id;
  }

  // MenuItemViewTestBase implementation
  virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
    menu->AppendMenuItemWithLabel(1, ASCIIToUTF16("item 1"));
    menu->AppendMenuItemWithLabel(2, ASCIIToUTF16("item 2"));
    menu->AppendSeparator();
    menu->AppendMenuItemWithLabel(3, ASCIIToUTF16("item 3"));
  }

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

  // Click on item INDEX.
  void Step1() {
    ASSERT_TRUE(menu_);

    views::SubmenuView* submenu = menu_->GetSubmenu();
    ASSERT_TRUE(submenu);
    ASSERT_TRUE(submenu->IsShowing());
    ASSERT_EQ(3, submenu->GetMenuItemCount());

    // click an item and pass control to the next step
    views::MenuItemView* item = submenu->GetMenuItemAt(INDEX);
    ASSERT_TRUE(item);
    Click(item, CreateEventTask(this, &MenuItemViewTestBasic::Step2));
  }

  // Check the clicked item and complete the test.
  void Step2() {
    ASSERT_FALSE(menu_->GetSubmenu()->IsShowing());
    ASSERT_EQ(INDEX + 1,last_command_);
    Done();
  }

 private:
  int last_command_;
};

// Click each item of a 3-item menu (with separator).
typedef MenuItemViewTestBasic<0> MenuItemViewTestBasic0;
typedef MenuItemViewTestBasic<1> MenuItemViewTestBasic1;
typedef MenuItemViewTestBasic<2> MenuItemViewTestBasic2;
VIEW_TEST(MenuItemViewTestBasic0, SelectItem0)
VIEW_TEST(MenuItemViewTestBasic1, SelectItem1)
VIEW_TEST(MenuItemViewTestBasic2, SelectItem2)

// Test class for inserting a menu item while the menu is open.
template<int INSERT_INDEX, int SELECT_INDEX>
class MenuItemViewTestInsert : public MenuItemViewTestBase {
 public:
  MenuItemViewTestInsert() :
      last_command_(0),
      inserted_item_(NULL) {
  }

  virtual ~MenuItemViewTestInsert() {
  }

  // views::MenuDelegate implementation
  virtual void ExecuteCommand(int id) OVERRIDE {
    last_command_ = id;
  }

  // MenuItemViewTestBase implementation
  virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
    menu->AppendMenuItemWithLabel(1, ASCIIToUTF16("item 1"));
    menu->AppendMenuItemWithLabel(2, ASCIIToUTF16("item 2"));
  }

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

  // Insert item at INSERT_INDEX and click item at SELECT_INDEX.
  void Step1() {
    ASSERT_TRUE(menu_);

    views::SubmenuView* submenu = menu_->GetSubmenu();
    ASSERT_TRUE(submenu);
    ASSERT_TRUE(submenu->IsShowing());
    ASSERT_EQ(2, submenu->GetMenuItemCount());

    inserted_item_ = menu_->AddMenuItemAt(INSERT_INDEX,
                                          1000,
                                          ASCIIToUTF16("inserted item"),
                                          string16(),
                                          string16(),
                                          gfx::ImageSkia(),
                                          views::MenuItemView::NORMAL,
                                          ui::NORMAL_SEPARATOR);
    ASSERT_TRUE(inserted_item_);
    menu_->ChildrenChanged();

    // click an item and pass control to the next step
    views::MenuItemView* item = submenu->GetMenuItemAt(SELECT_INDEX);
    ASSERT_TRUE(item);
    Click(item, CreateEventTask(this, &MenuItemViewTestInsert::Step2));
  }

  // Check clicked item and complete test.
  void Step2() {
    ASSERT_TRUE(menu_);

    views::SubmenuView* submenu = menu_->GetSubmenu();
    ASSERT_TRUE(submenu);
    ASSERT_FALSE(submenu->IsShowing());
    ASSERT_EQ(3, submenu->GetMenuItemCount());

    if (SELECT_INDEX == INSERT_INDEX)
      ASSERT_EQ(1000, last_command_);
    else if (SELECT_INDEX < INSERT_INDEX)
      ASSERT_EQ(SELECT_INDEX + 1, last_command_);
    else
      ASSERT_EQ(SELECT_INDEX, last_command_);

    Done();
  }

 private:
  int last_command_;
  views::MenuItemView* inserted_item_;
};

// MenuItemViewTestInsertXY inserts an item at index X and selects the
// item at index Y (after the insertion).  The tests here cover
// inserting at the beginning, middle, and end, crossbarred with
// selecting the first and last item.
typedef MenuItemViewTestInsert<0,0> MenuItemViewTestInsert00;
typedef MenuItemViewTestInsert<0,2> MenuItemViewTestInsert02;
typedef MenuItemViewTestInsert<1,0> MenuItemViewTestInsert10;
typedef MenuItemViewTestInsert<1,2> MenuItemViewTestInsert12;
typedef MenuItemViewTestInsert<2,0> MenuItemViewTestInsert20;
typedef MenuItemViewTestInsert<2,2> MenuItemViewTestInsert22;
VIEW_TEST(MenuItemViewTestInsert00, InsertItem00)
VIEW_TEST(MenuItemViewTestInsert02, InsertItem02)
VIEW_TEST(MenuItemViewTestInsert10, InsertItem10)
VIEW_TEST(MenuItemViewTestInsert12, InsertItem12)
VIEW_TEST(MenuItemViewTestInsert20, InsertItem20)
VIEW_TEST(MenuItemViewTestInsert22, InsertItem22)

// Test class for inserting a menu item while a submenu is open.
template<int INSERT_INDEX>
class MenuItemViewTestInsertWithSubmenu : public MenuItemViewTestBase {
 public:
  MenuItemViewTestInsertWithSubmenu() :
      last_command_(0),
      submenu_(NULL),
      inserted_item_(NULL) {
  }

  virtual ~MenuItemViewTestInsertWithSubmenu() {
  }

  // views::MenuDelegate implementation
  virtual void ExecuteCommand(int id) OVERRIDE {
    last_command_ = id;
  }

  // MenuItemViewTestBase implementation
  virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
    submenu_ = menu->AppendSubMenu(1, ASCIIToUTF16("My Submenu"));
    submenu_->AppendMenuItemWithLabel(101, ASCIIToUTF16("submenu item 1"));
    submenu_->AppendMenuItemWithLabel(101, ASCIIToUTF16("submenu item 2"));
    menu->AppendMenuItemWithLabel(2, ASCIIToUTF16("item 2"));
  }

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

  // Post submenu.
  void Step1() {
    Click(submenu_,
          CreateEventTask(this, &MenuItemViewTestInsertWithSubmenu::Step2));
  }

  // Insert item at INSERT_INDEX.
  void Step2() {
    inserted_item_ = menu_->AddMenuItemAt(INSERT_INDEX,
                                          1000,
                                          ASCIIToUTF16("inserted item"),
                                          string16(),
                                          string16(),
                                          gfx::ImageSkia(),
                                          views::MenuItemView::NORMAL,
                                          ui::NORMAL_SEPARATOR);
    ASSERT_TRUE(inserted_item_);
    menu_->ChildrenChanged();

    Click(inserted_item_,
          CreateEventTask(this, &MenuItemViewTestInsertWithSubmenu::Step3));
  }

  void Step3() {
    Done();
  }

 private:
  int last_command_;
  views::MenuItemView* submenu_;
  views::MenuItemView* inserted_item_;
};

// MenuItemViewTestInsertWithSubmenuX posts a menu and its submenu,
// then inserts an item in the top-level menu at X.
typedef MenuItemViewTestInsertWithSubmenu<0> MenuItemViewTestInsertWithSubmenu0;
typedef MenuItemViewTestInsertWithSubmenu<1> MenuItemViewTestInsertWithSubmenu1;
VIEW_TEST(MenuItemViewTestInsertWithSubmenu0, InsertItemWithSubmenu0)
VIEW_TEST(MenuItemViewTestInsertWithSubmenu1, InsertItemWithSubmenu1)

// Test class for removing a menu item while the menu is open.
template<int REMOVE_INDEX, int SELECT_INDEX>
class MenuItemViewTestRemove : public MenuItemViewTestBase {
 public:
  MenuItemViewTestRemove()
      : last_command_(0) {
  }

  virtual ~MenuItemViewTestRemove() {
  }

  // views::MenuDelegate implementation
  virtual void ExecuteCommand(int id) OVERRIDE {
    last_command_ = id;
  }

  // MenuItemViewTestBase implementation
  virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
    menu->AppendMenuItemWithLabel(1, ASCIIToUTF16("item 1"));
    menu->AppendMenuItemWithLabel(2, ASCIIToUTF16("item 2"));
    menu->AppendMenuItemWithLabel(3, ASCIIToUTF16("item 3"));
  }

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

  // Remove item at REMOVE_INDEX and click item at SELECT_INDEX.
  void Step1() {
    ASSERT_TRUE(menu_);

    views::SubmenuView* submenu = menu_->GetSubmenu();
    ASSERT_TRUE(submenu);
    ASSERT_TRUE(submenu->IsShowing());
    ASSERT_EQ(3, submenu->GetMenuItemCount());

    // remove
    menu_->RemoveMenuItemAt(REMOVE_INDEX);
    menu_->ChildrenChanged();

    // click
    views::MenuItemView* item = submenu->GetMenuItemAt(SELECT_INDEX);
    ASSERT_TRUE(item);
    Click(item, CreateEventTask(this, &MenuItemViewTestRemove::Step2));
  }

  // Check clicked item and complete test.
  void Step2() {
    ASSERT_TRUE(menu_);

    views::SubmenuView* submenu = menu_->GetSubmenu();
    ASSERT_TRUE(submenu);
    ASSERT_FALSE(submenu->IsShowing());
    ASSERT_EQ(2, submenu->GetMenuItemCount());

    if (SELECT_INDEX < REMOVE_INDEX)
      ASSERT_EQ(SELECT_INDEX + 1, last_command_);
    else
      ASSERT_EQ(SELECT_INDEX + 2, last_command_);

    Done();
  }

 private:
  int last_command_;
};

typedef MenuItemViewTestRemove<0,0> MenuItemViewTestRemove00;
typedef MenuItemViewTestRemove<0,1> MenuItemViewTestRemove01;
typedef MenuItemViewTestRemove<1,0> MenuItemViewTestRemove10;
typedef MenuItemViewTestRemove<1,1> MenuItemViewTestRemove11;
typedef MenuItemViewTestRemove<2,0> MenuItemViewTestRemove20;
typedef MenuItemViewTestRemove<2,1> MenuItemViewTestRemove21;
VIEW_TEST(MenuItemViewTestRemove00, RemoveItem00)
VIEW_TEST(MenuItemViewTestRemove01, RemoveItem01)
VIEW_TEST(MenuItemViewTestRemove10, RemoveItem10)
VIEW_TEST(MenuItemViewTestRemove11, RemoveItem11)
VIEW_TEST(MenuItemViewTestRemove20, RemoveItem20)
VIEW_TEST(MenuItemViewTestRemove21, RemoveItem21)

// Test class for removing a menu item while a submenu is open.
template<int REMOVE_INDEX>
class MenuItemViewTestRemoveWithSubmenu : public MenuItemViewTestBase {
 public:
  MenuItemViewTestRemoveWithSubmenu() :
      last_command_(0),
      submenu_(NULL) {
  }

  virtual ~MenuItemViewTestRemoveWithSubmenu() {
  }

  // views::MenuDelegate implementation
  virtual void ExecuteCommand(int id) OVERRIDE {
    last_command_ = id;
  }

  // MenuItemViewTestBase implementation
  virtual void BuildMenu(views::MenuItemView* menu) OVERRIDE {
    menu->AppendMenuItemWithLabel(1, ASCIIToUTF16("item 1"));
    submenu_ = menu->AppendSubMenu(2, ASCIIToUTF16("My Submenu"));
    submenu_->AppendMenuItemWithLabel(101, ASCIIToUTF16("submenu item 1"));
    submenu_->AppendMenuItemWithLabel(102, ASCIIToUTF16("submenu item 2"));
  }

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

  // Post submenu.
  void Step1() {
    ASSERT_TRUE(menu_);

    views::SubmenuView* submenu = menu_->GetSubmenu();
    ASSERT_TRUE(submenu);
    ASSERT_TRUE(submenu->IsShowing());

    Click(submenu_,
          CreateEventTask(this, &MenuItemViewTestRemoveWithSubmenu::Step2));
  }

  // Remove item at REMOVE_INDEX and select it to exit the menu loop.
  void Step2() {
    ASSERT_TRUE(menu_);

    views::SubmenuView* submenu = menu_->GetSubmenu();
    ASSERT_TRUE(submenu);
    ASSERT_TRUE(submenu->IsShowing());
    ASSERT_EQ(2, submenu->GetMenuItemCount());

    // remove
    menu_->RemoveMenuItemAt(REMOVE_INDEX);
    menu_->ChildrenChanged();

    // click
    Click(button_,
          CreateEventTask(this, &MenuItemViewTestRemoveWithSubmenu::Step3));
  }

  void Step3() {
    ASSERT_TRUE(menu_);

    views::SubmenuView* submenu = menu_->GetSubmenu();
    ASSERT_TRUE(submenu);
    ASSERT_FALSE(submenu->IsShowing());
    ASSERT_EQ(1, submenu->GetMenuItemCount());

    Done();
  }

 private:
  int last_command_;
  views::MenuItemView* submenu_;
};

typedef MenuItemViewTestRemoveWithSubmenu<0> MenuItemViewTestRemoveWithSubmenu0;
typedef MenuItemViewTestRemoveWithSubmenu<1> MenuItemViewTestRemoveWithSubmenu1;
VIEW_TEST(MenuItemViewTestRemoveWithSubmenu0, RemoveItemWithSubmenu0)
VIEW_TEST(MenuItemViewTestRemoveWithSubmenu1, RemoveItemWithSubmenu1)
