// 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 "ash/wm/custom_frame_view_ash.h"

#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/maximize_bubble_controller.h"
#include "ash/wm/property_util.h"
#include "ash/wm/window_util.h"
#include "ash/wm/workspace/frame_maximize_button.h"
#include "ash/wm/workspace/snap_sizer.h"
#include "base/command_line.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/test/event_generator.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/base/events/event_utils.h"
#include "ui/base/gestures/gesture_configuration.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/test/test_views_delegate.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

namespace ash {
namespace internal {

namespace {


class CancelCallbackHandler {
 public:
  CancelCallbackHandler(int update_events_before_cancel,
                        FrameMaximizeButton* maximize_button) :
      update_events_before_cancel_(update_events_before_cancel),
      maximize_button_(maximize_button) {}
  virtual ~CancelCallbackHandler() {}

  void CountedCancelCallback(ui::EventType event_type,
                             const gfx::Vector2dF& pos) {
    if (event_type == ui::ET_GESTURE_SCROLL_UPDATE &&
        !(--update_events_before_cancel_)) {
      // Make sure that we are in the middle of a resizing operation, cancel it
      // and then test that it is exited.
      EXPECT_TRUE(maximize_button_->is_snap_enabled());
      maximize_button_->DestroyMaximizeMenu();
      EXPECT_FALSE(maximize_button_->is_snap_enabled());
    }
  }

 private:
  // When this counter reaches 0, the gesture maximize action gets cancelled.
  int update_events_before_cancel_;

  // The maximize button which needs to get informed of the gesture termination.
  FrameMaximizeButton* maximize_button_;

  DISALLOW_COPY_AND_ASSIGN(CancelCallbackHandler);
};

class ShellViewsDelegate : public views::TestViewsDelegate {
 public:
  ShellViewsDelegate() {}
  virtual ~ShellViewsDelegate() {}

  // Overridden from views::TestViewsDelegate:
  virtual views::NonClientFrameView* CreateDefaultNonClientFrameView(
      views::Widget* widget) OVERRIDE {
    // Always test CustomFrameViewAsh, which may not be the ash::Shell default.
    CustomFrameViewAsh* frame_view = new CustomFrameViewAsh;
    frame_view->Init(widget);
    return frame_view;
  }
  virtual bool UseTransparentWindows() const OVERRIDE {
    // Ash uses transparent window frames.
    return true;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(ShellViewsDelegate);
};

class TestWidgetDelegate : public views::WidgetDelegateView {
 public:
  TestWidgetDelegate() {}
  virtual ~TestWidgetDelegate() {}

  // Overridden from views::WidgetDelegate:
  virtual views::View* GetContentsView() OVERRIDE {
    return this;
  }
  virtual bool CanResize() const OVERRIDE {
    return true;
  }
  virtual bool CanMaximize() const OVERRIDE {
    return true;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate);
};

}  // namespace

class CustomFrameViewAshTest : public ash::test::AshTestBase {
 public:
  CustomFrameViewAshTest() {}
  virtual ~CustomFrameViewAshTest() {}

  views::Widget* CreateWidget() {
    views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
    views::Widget* widget = new views::Widget;
    params.context = CurrentContext();
    params.delegate = new TestWidgetDelegate;
    widget->Init(params);
    widget->Show();
    return widget;
  }

  CustomFrameViewAsh* GetCustomFrameViewAsh(views::Widget* widget) const {
    return static_cast<CustomFrameViewAsh*>(widget->non_client_view()->
        frame_view());
  }

  virtual void SetUp() OVERRIDE {
    AshTestBase::SetUp();
    if (!views::ViewsDelegate::views_delegate) {
      views_delegate_.reset(new ShellViewsDelegate);
      views::ViewsDelegate::views_delegate = views_delegate_.get();
    }
  }

  virtual void TearDown() OVERRIDE {
    if (views_delegate_) {
      views::ViewsDelegate::views_delegate = NULL;
      views_delegate_.reset();
    }
    AshTestBase::TearDown();
  }

 private:
  scoped_ptr<views::ViewsDelegate> views_delegate_;

  DISALLOW_COPY_AND_ASSIGN(CustomFrameViewAshTest);
};

// Tests that clicking on the resize-button toggles between maximize and normal
// state.
TEST_F(CustomFrameViewAshTest, ResizeButtonToggleMaximize) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  views::View* view = test.maximize_button();
  gfx::Point center = view->GetBoundsInScreen().CenterPoint();

  aura::test::EventGenerator generator(window->GetRootWindow(), center);

  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));

  generator.ClickLeftButton();
  RunAllPendingInMessageLoop();
  EXPECT_TRUE(ash::wm::IsWindowMaximized(window));

  center = view->GetBoundsInScreen().CenterPoint();
  generator.MoveMouseTo(center);
  generator.ClickLeftButton();
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));

  generator.GestureTapAt(view->GetBoundsInScreen().CenterPoint());
  EXPECT_TRUE(ash::wm::IsWindowMaximized(window));

  generator.GestureTapAt(view->GetBoundsInScreen().CenterPoint());
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));

  generator.GestureTapDownAndUp(view->GetBoundsInScreen().CenterPoint());
  EXPECT_TRUE(ash::wm::IsWindowMaximized(window));

  generator.GestureTapDownAndUp(view->GetBoundsInScreen().CenterPoint());
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));

  widget->Close();
}

#if defined(OS_WIN)
// RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
#define MAYBE_ResizeButtonDrag DISABLED_ResizeButtonDrag
#else
#define MAYBE_ResizeButtonDrag ResizeButtonDrag
#endif

// Tests that click+dragging on the resize-button tiles or minimizes the window.
TEST_F(CustomFrameViewAshTest, MAYBE_ResizeButtonDrag) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  views::View* view = test.maximize_button();
  gfx::Point center = view->GetBoundsInScreen().CenterPoint();

  aura::test::EventGenerator generator(window->GetRootWindow(), center);

  EXPECT_TRUE(ash::wm::IsWindowNormal(window));

  // Snap right.
  {
    generator.PressLeftButton();
    generator.MoveMouseBy(10, 0);
    generator.ReleaseLeftButton();
    RunAllPendingInMessageLoop();

    EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
    EXPECT_FALSE(ash::wm::IsWindowMinimized(window));
    internal::SnapSizer sizer(window, center,
        internal::SnapSizer::RIGHT_EDGE,
        internal::SnapSizer::OTHER_INPUT);
    EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString());
  }

  // Snap left.
  {
    center = view->GetBoundsInScreen().CenterPoint();
    generator.MoveMouseTo(center);
    generator.PressLeftButton();
    generator.MoveMouseBy(-10, 0);
    generator.ReleaseLeftButton();
    RunAllPendingInMessageLoop();

    EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
    EXPECT_FALSE(ash::wm::IsWindowMinimized(window));
    internal::SnapSizer sizer(window, center,
        internal::SnapSizer::LEFT_EDGE,
        internal::SnapSizer::OTHER_INPUT);
    EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString());
  }

  // Minimize.
  {
    center = view->GetBoundsInScreen().CenterPoint();
    generator.MoveMouseTo(center);
    generator.PressLeftButton();
    generator.MoveMouseBy(0, 10);
    generator.ReleaseLeftButton();
    RunAllPendingInMessageLoop();

    EXPECT_TRUE(ash::wm::IsWindowMinimized(window));
  }

  ash::wm::RestoreWindow(window);

  // Now test the same behaviour for gesture events.

  // Snap right.
  {
    center = view->GetBoundsInScreen().CenterPoint();
    gfx::Point end = center;
    end.Offset(40, 0);
    generator.GestureScrollSequence(center, end,
        base::TimeDelta::FromMilliseconds(100),
        3);
    RunAllPendingInMessageLoop();

    EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
    EXPECT_FALSE(ash::wm::IsWindowMinimized(window));
    // This is a short resizing distance and different touch behavior
    // applies which leads in half of the screen being used.
    EXPECT_EQ("400,0 400x552", window->bounds().ToString());
  }

  // Snap left.
  {
    center = view->GetBoundsInScreen().CenterPoint();
    gfx::Point end = center;
    end.Offset(-40, 0);
    generator.GestureScrollSequence(center, end,
        base::TimeDelta::FromMilliseconds(100),
        3);
    RunAllPendingInMessageLoop();

    EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
    EXPECT_FALSE(ash::wm::IsWindowMinimized(window));
    internal::SnapSizer sizer(window, center,
        internal::SnapSizer::LEFT_EDGE,
        internal::SnapSizer::OTHER_INPUT);
    EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString());
  }

  // Minimize.
  {
    center = view->GetBoundsInScreen().CenterPoint();
    gfx::Point end = center;
    end.Offset(0, 40);
    generator.GestureScrollSequence(center, end,
        base::TimeDelta::FromMilliseconds(100),
        3);
    RunAllPendingInMessageLoop();

    EXPECT_TRUE(ash::wm::IsWindowMinimized(window));
  }

  // Test with gesture events.

  widget->Close();
}

#if defined(OS_WIN)
// RootWindow and Display can't resize on Windows Ash. http://crbug.com/165962
#define MAYBE_TouchDragResizeCloseToCornerDiffersFromMouse \
        DISABLED_TouchDragResizeCloseToCornerDiffersFromMouse
#else
#define MAYBE_TouchDragResizeCloseToCornerDiffersFromMouse \
        TouchDragResizeCloseToCornerDiffersFromMouse
#endif

// Tests Left/Right snapping with resize button touch dragging - which should
// trigger dependent on the available drag distance.
TEST_F(CustomFrameViewAshTest,
       MAYBE_TouchDragResizeCloseToCornerDiffersFromMouse) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  views::View* view = test.maximize_button();

  gfx::Rect work_area = widget->GetWorkAreaBoundsInScreen();
  gfx::Rect bounds = window->bounds();
  bounds.set_x(work_area.width() - bounds.width());
  widget->SetBounds(bounds);

  gfx::Point start_point = view->GetBoundsInScreen().CenterPoint();
  // We want to move all the way to the right (the few pixels we have).
  gfx::Point end_point = gfx::Point(work_area.width(), start_point.y());

  aura::test::EventGenerator generator(window->GetRootWindow(), start_point);

  EXPECT_TRUE(ash::wm::IsWindowNormal(window));

  // Snap right with a touch drag.
  generator.GestureScrollSequence(start_point,
                                  end_point,
                                  base::TimeDelta::FromMilliseconds(100),
                                  10);
  RunAllPendingInMessageLoop();

  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
  EXPECT_FALSE(ash::wm::IsWindowMinimized(window));
  gfx::Rect touch_result = window->bounds();
  EXPECT_NE(bounds.ToString(), touch_result.ToString());

  // Set the position back to where it was before and re-try with a mouse.
  widget->SetBounds(bounds);

  generator.MoveMouseTo(start_point);
  generator.PressLeftButton();
  generator.MoveMouseTo(end_point, 10);
  generator.ReleaseLeftButton();
  RunAllPendingInMessageLoop();

  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
  EXPECT_FALSE(ash::wm::IsWindowMinimized(window));
  gfx::Rect mouse_result = window->bounds();

  // The difference between the two operations should be that the mouse
  // operation should have just started to resize and the touch operation is
  // already all the way down to the smallest possible size.
  EXPECT_NE(mouse_result.ToString(), touch_result.ToString());
  EXPECT_GT(mouse_result.width(), touch_result.width());
}


// Test that closing the (browser) window with an opened balloon does not
// crash the system. In other words: Make sure that shutting down the frame
// destroys the opened balloon in an orderly fashion.
TEST_F(CustomFrameViewAshTest, MaximizeButtonExternalShutDown) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
  maximize_button->set_bubble_appearance_delay_ms(0);
  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);

  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
  EXPECT_FALSE(maximize_button->maximizer());
  EXPECT_TRUE(ash::wm::IsWindowNormal(window));

  // Move the mouse cursor over the button to bring up the maximizer bubble.
  generator.MoveMouseTo(button_pos);
  EXPECT_TRUE(maximize_button->maximizer());

  // Even though the widget is closing the bubble menu should not crash upon
  // its delayed destruction.
  widget->CloseNow();
}

// Test that maximizing the browser after hovering in does not crash the system
// when the observer gets removed in the bubble destruction process.
TEST_F(CustomFrameViewAshTest, MaximizeOnHoverThenClick) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
  maximize_button->set_bubble_appearance_delay_ms(0);
  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);

  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
  EXPECT_FALSE(maximize_button->maximizer());
  EXPECT_TRUE(ash::wm::IsWindowNormal(window));

  // Move the mouse cursor over the button to bring up the maximizer bubble.
  generator.MoveMouseTo(button_pos);
  EXPECT_TRUE(maximize_button->maximizer());
  generator.ClickLeftButton();
  EXPECT_TRUE(ash::wm::IsWindowMaximized(window));
}

// Test that hovering over a button in the balloon dialog will show the phantom
// window. Moving then away from the button will hide it again. Then check that
// pressing and dragging the button itself off the button will also release the
// phantom window.
TEST_F(CustomFrameViewAshTest, MaximizeLeftButtonDragOut) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
  maximize_button->set_bubble_appearance_delay_ms(0);
  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);

  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
  EXPECT_FALSE(maximize_button->maximizer());
  EXPECT_TRUE(ash::wm::IsWindowNormal(window));
  EXPECT_FALSE(maximize_button->phantom_window_open());

  // Move the mouse cursor over the button to bring up the maximizer bubble.
  generator.MoveMouseTo(button_pos);
  EXPECT_TRUE(maximize_button->maximizer());

  // Move the mouse over the left maximize button.
  gfx::Point left_max_pos = maximize_button->maximizer()->
      GetButtonForUnitTest(SNAP_LEFT)->GetBoundsInScreen().CenterPoint();

  generator.MoveMouseTo(left_max_pos);
  // Expect the phantom window to be open.
  EXPECT_TRUE(maximize_button->phantom_window_open());

  // Move away to see the window being destroyed.
  generator.MoveMouseTo(off_pos);
  EXPECT_FALSE(maximize_button->phantom_window_open());

  // Move back over the button.
  generator.MoveMouseTo(button_pos);
  generator.MoveMouseTo(left_max_pos);
  EXPECT_TRUE(maximize_button->phantom_window_open());

  // Press button and drag out of dialog.
  generator.PressLeftButton();
  generator.MoveMouseTo(off_pos);
  generator.ReleaseLeftButton();

  // Check that the phantom window is also gone.
  EXPECT_FALSE(maximize_button->phantom_window_open());
}

// Test that clicking a button in the maximizer bubble (in this case the
// maximize left button) will do the requested action.
TEST_F(CustomFrameViewAshTest, MaximizeLeftByButton) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
  maximize_button->set_bubble_appearance_delay_ms(0);
  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);

  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
  EXPECT_FALSE(maximize_button->maximizer());
  EXPECT_TRUE(ash::wm::IsWindowNormal(window));
  EXPECT_FALSE(maximize_button->phantom_window_open());

  // Move the mouse cursor over the button to bring up the maximizer bubble.
  generator.MoveMouseTo(button_pos);
  EXPECT_TRUE(maximize_button->maximizer());

  // Move the mouse over the left maximize button.
  gfx::Point left_max_pos = maximize_button->maximizer()->
      GetButtonForUnitTest(SNAP_LEFT)->GetBoundsInScreen().CenterPoint();
  generator.MoveMouseTo(left_max_pos);
  EXPECT_TRUE(maximize_button->phantom_window_open());
  generator.ClickLeftButton();

  EXPECT_FALSE(maximize_button->maximizer());
  EXPECT_FALSE(maximize_button->phantom_window_open());

  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
  EXPECT_FALSE(ash::wm::IsWindowMinimized(window));
  internal::SnapSizer sizer(window, button_pos,
                            internal::SnapSizer::LEFT_EDGE,
                            internal::SnapSizer::OTHER_INPUT);
  sizer.SelectDefaultSizeAndDisableResize();
  EXPECT_EQ(sizer.target_bounds().ToString(), window->bounds().ToString());
}

// Test that the activation focus does not change when the bubble gets shown.
TEST_F(CustomFrameViewAshTest, MaximizeKeepFocus) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
  maximize_button->set_bubble_appearance_delay_ms(0);
  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);

  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
  EXPECT_FALSE(maximize_button->maximizer());
  EXPECT_TRUE(ash::wm::IsWindowNormal(window));

  aura::Window* active =
      aura::client::GetFocusClient(window)->GetFocusedWindow();

  // Move the mouse cursor over the button to bring up the maximizer bubble.
  generator.MoveMouseTo(button_pos);
  EXPECT_TRUE(maximize_button->maximizer());

  // Check that the focused window is still the same.
  EXPECT_EQ(active, aura::client::GetFocusClient(window)->GetFocusedWindow());
}

TEST_F(CustomFrameViewAshTest, MaximizeTap) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  aura::RootWindow* root_window = window->GetRootWindow();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();

  const int touch_default_radius =
      ui::GestureConfiguration::default_radius();
  ui::GestureConfiguration::set_default_radius(0);

  const int kTouchId = 2;
  ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
                       button_pos,
                       kTouchId,
                       ui::EventTimeForNow());
  root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&press);

  button_pos.Offset(9, 8);
  ui::TouchEvent release(
      ui::ET_TOUCH_RELEASED,
      button_pos,
      kTouchId,
      press.time_stamp() + base::TimeDelta::FromMilliseconds(50));
  root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&release);

  ui::GestureConfiguration::set_default_radius(touch_default_radius);
}

// Test that only the left button will activate the maximize button.
TEST_F(CustomFrameViewAshTest, OnlyLeftButtonMaximizes) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
  maximize_button->set_bubble_appearance_delay_ms(0);
  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);

  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
  EXPECT_FALSE(maximize_button->maximizer());
  EXPECT_TRUE(ash::wm::IsWindowNormal(window));
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));

  // Move the mouse cursor over the button.
  generator.MoveMouseTo(button_pos);
  EXPECT_TRUE(maximize_button->maximizer());
  EXPECT_FALSE(maximize_button->phantom_window_open());

  // After pressing the left button the button should get triggered.
  generator.PressLeftButton();
  RunAllPendingInMessageLoop();
  EXPECT_TRUE(maximize_button->is_snap_enabled());
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));

  // Pressing the right button then should cancel the operation.
  generator.PressRightButton();
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(maximize_button->maximizer());

  // After releasing the second button the window shouldn't be maximized.
  generator.ReleaseRightButton();
  generator.ReleaseLeftButton();
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));

  // Second experiment: Starting with right should also not trigger.
  generator.MoveMouseTo(off_pos);
  generator.MoveMouseTo(button_pos);
  EXPECT_TRUE(maximize_button->maximizer());

  // Pressing first the right button should not activate.
  generator.PressRightButton();
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(maximize_button->is_snap_enabled());

  // Pressing then additionally the left button shouldn't activate either.
  generator.PressLeftButton();
  RunAllPendingInMessageLoop();
  EXPECT_FALSE(maximize_button->is_snap_enabled());
  generator.ReleaseRightButton();
  generator.ReleaseLeftButton();
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
}

// Click a button of window maximize functionality.
// If |snap_type| is SNAP_NONE the FrameMaximizeButton gets clicked, otherwise
// the associated snap button.
// |Window| is the window which owns the maximize button.
// |maximize_button| is the FrameMaximizeButton which controls the window.
void ClickMaxButton(
    ash::FrameMaximizeButton* maximize_button,
    aura::Window* window,
    SnapType snap_type) {
  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);

  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
  generator.MoveMouseTo(off_pos);
  EXPECT_FALSE(maximize_button->maximizer());
  EXPECT_FALSE(maximize_button->phantom_window_open());

  // Move the mouse cursor over the button.
  generator.MoveMouseTo(button_pos);
  EXPECT_TRUE(maximize_button->maximizer());
  EXPECT_FALSE(maximize_button->phantom_window_open());

  if (snap_type != SNAP_NONE) {
    gfx::Point left_max_pos = maximize_button->maximizer()->
        GetButtonForUnitTest(snap_type)->GetBoundsInScreen().CenterPoint();
    generator.MoveMouseTo(left_max_pos);
    EXPECT_TRUE(maximize_button->phantom_window_open());
  }
  // After pressing the left button the button should get triggered.
  generator.ClickLeftButton();
  EXPECT_FALSE(maximize_button->maximizer());
}

// Test that the restore from left/right maximize is properly done.
TEST_F(CustomFrameViewAshTest, MaximizeLeftRestore) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  widget->SetBounds(gfx::Rect(10, 10, 100, 100));
  gfx::Rect initial_bounds = widget->GetWindowBoundsInScreen();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
  maximize_button->set_bubble_appearance_delay_ms(0);

  ClickMaxButton(maximize_button, window, SNAP_LEFT);
  // The window should not be maximized.
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
  // But the bounds should be different.
  gfx::Rect new_bounds = widget->GetWindowBoundsInScreen();
  EXPECT_EQ(0, new_bounds.x());
  EXPECT_EQ(0, new_bounds.y());

  // Now click the same button again to see that it restores.
  ClickMaxButton(maximize_button, window, SNAP_LEFT);
  // But the bounds should be restored.
  new_bounds = widget->GetWindowBoundsInScreen();
  EXPECT_EQ(new_bounds.x(), initial_bounds.x());
  EXPECT_EQ(new_bounds.y(), initial_bounds.x());
  EXPECT_EQ(new_bounds.width(), initial_bounds.width());
  EXPECT_EQ(new_bounds.height(), initial_bounds.height());
  // Make sure that there is no restore rectangle left.
  EXPECT_EQ(NULL, GetRestoreBoundsInScreen(window));
}

// Maximize, left/right maximize and then restore should works.
TEST_F(CustomFrameViewAshTest, MaximizeMaximizeLeftRestore) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  widget->SetBounds(gfx::Rect(10, 10, 100, 100));
  gfx::Rect initial_bounds = widget->GetWindowBoundsInScreen();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
  maximize_button->set_bubble_appearance_delay_ms(0);

  ClickMaxButton(maximize_button, window, SNAP_NONE);
  EXPECT_TRUE(ash::wm::IsWindowMaximized(window));

  ClickMaxButton(maximize_button, window, SNAP_LEFT);
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
  gfx::Rect new_bounds = widget->GetWindowBoundsInScreen();
  EXPECT_EQ(0, new_bounds.x());
  EXPECT_EQ(0, new_bounds.y());

  // Now click the same button again to see that it restores.
  ClickMaxButton(maximize_button, window, SNAP_LEFT);
  RunAllPendingInMessageLoop();
  // But the bounds should be restored.
  new_bounds = widget->GetWindowBoundsInScreen();
  EXPECT_EQ(new_bounds.x(), initial_bounds.x());
  EXPECT_EQ(new_bounds.y(), initial_bounds.x());
  EXPECT_EQ(new_bounds.width(), initial_bounds.width());
  EXPECT_EQ(new_bounds.height(), initial_bounds.height());
  // Make sure that there is no restore rectangle left.
  EXPECT_EQ(NULL, GetRestoreBoundsInScreen(window));
}

// Left/right maximize, maximize and then restore should work.
TEST_F(CustomFrameViewAshTest, MaximizeLeftMaximizeRestore) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  widget->SetBounds(gfx::Rect(10, 10, 100, 100));
  gfx::Rect initial_bounds = widget->GetWindowBoundsInScreen();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
  maximize_button->set_bubble_appearance_delay_ms(0);

  ClickMaxButton(maximize_button, window, SNAP_LEFT);
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));

  ClickMaxButton(maximize_button, window, SNAP_NONE);
  EXPECT_TRUE(ash::wm::IsWindowMaximized(window));

  ClickMaxButton(maximize_button, window, SNAP_NONE);
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));
  gfx::Rect new_bounds = widget->GetWindowBoundsInScreen();
  EXPECT_EQ(new_bounds.x(), initial_bounds.x());
  EXPECT_EQ(new_bounds.y(), initial_bounds.x());
  EXPECT_EQ(new_bounds.width(), initial_bounds.width());
  EXPECT_EQ(new_bounds.height(), initial_bounds.height());
  // Make sure that there is no restore rectangle left.
  EXPECT_EQ(NULL, GetRestoreBoundsInScreen(window));
}

// Starting with a window which has no restore bounds, maximize then left/right
// maximize should not be centered but left/right maximized.
TEST_F(CustomFrameViewAshTest, MaximizeThenLeftMaximize) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  widget->SetBounds(gfx::Rect(10, 10, 100, 100));
  gfx::Rect initial_bounds = widget->GetWindowBoundsInScreen();
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();
  maximize_button->set_bubble_appearance_delay_ms(0);
  // Make sure that there is no restore rectangle.
  EXPECT_EQ(NULL, GetRestoreBoundsInScreen(window));

  ClickMaxButton(maximize_button, window, SNAP_NONE);
  EXPECT_TRUE(ash::wm::IsWindowMaximized(window));

  ClickMaxButton(maximize_button, window, SNAP_LEFT);
  EXPECT_FALSE(ash::wm::IsWindowMaximized(window));

  gfx::Rect new_bounds = widget->GetWindowBoundsInScreen();
  EXPECT_EQ(new_bounds.x(), 0);
  EXPECT_EQ(new_bounds.y(), 0);
  // Make sure that the restore rectangle is the original rectangle.
  EXPECT_EQ(initial_bounds.ToString(),
            GetRestoreBoundsInScreen(window)->ToString());
}

// Test that minimizing the window per keyboard closes the maximize bubble.
TEST_F(CustomFrameViewAshTest, MinimizePerKeyClosesBubble) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  widget->SetBounds(gfx::Rect(10, 10, 100, 100));
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  ash::FrameMaximizeButton* maximize_button = test.maximize_button();

  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
  gfx::Point off_pos(button_pos.x() + 100, button_pos.y() + 100);

  aura::test::EventGenerator generator(window->GetRootWindow(), off_pos);
  generator.MoveMouseTo(off_pos);
  EXPECT_FALSE(maximize_button->maximizer());

  // Move the mouse cursor over the maximize button.
  generator.MoveMouseTo(button_pos);
  EXPECT_TRUE(maximize_button->maximizer());

  // We simulate the keystroke by calling minimizeWindow directly.
  wm::MinimizeWindow(window);

  EXPECT_TRUE(ash::wm::IsWindowMinimized(window));
  EXPECT_FALSE(maximize_button->maximizer());
}

// Tests that dragging down on the maximize button minimizes the window.
TEST_F(CustomFrameViewAshTest, MaximizeButtonDragDownMinimizes) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  widget->SetBounds(gfx::Rect(10, 10, 100, 100));
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  FrameMaximizeButton* maximize_button = test.maximize_button();

  // Drag down on a maximized window.
  wm::MaximizeWindow(window);
  EXPECT_TRUE(wm::IsWindowMaximized(window));
  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
  gfx::Point off_pos(button_pos.x(), button_pos.y() + 100);

  aura::test::EventGenerator generator(window->GetRootWindow());
  generator.GestureScrollSequence(button_pos, off_pos,
      base::TimeDelta::FromMilliseconds(0), 1);

  EXPECT_TRUE(wm::IsWindowMinimized(window));
  EXPECT_FALSE(maximize_button->maximizer());

  // Drag down on a restored window.
  wm::RestoreWindow(window);

  button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
  off_pos = gfx::Point(button_pos.x(), button_pos.y() + 200);
  generator.GestureScrollSequence(button_pos, off_pos,
      base::TimeDelta::FromMilliseconds(10), 1);
  EXPECT_TRUE(wm::IsWindowMinimized(window));
  EXPECT_FALSE(maximize_button->maximizer());
}

// Tests that dragging Left and pressing ESC does properly abort.
TEST_F(CustomFrameViewAshTest, MaximizeButtonDragLeftEscapeExits) {
  views::Widget* widget = CreateWidget();
  aura::Window* window = widget->GetNativeWindow();
  gfx::Rect window_position = gfx::Rect(10, 10, 100, 100);
  widget->SetBounds(window_position);
  CustomFrameViewAsh* frame = GetCustomFrameViewAsh(widget);
  CustomFrameViewAsh::TestApi test(frame);
  FrameMaximizeButton* maximize_button = test.maximize_button();

  gfx::Point button_pos = maximize_button->GetBoundsInScreen().CenterPoint();
  gfx::Point off_pos(button_pos.x() - button_pos.x() / 2, button_pos.y());

  const int kGestureSteps = 10;
  CancelCallbackHandler cancel_handler(kGestureSteps / 2, maximize_button);
  aura::test::EventGenerator generator(window->GetRootWindow());
  generator.GestureScrollSequenceWithCallback(
      button_pos,
      off_pos,
      base::TimeDelta::FromMilliseconds(0),
      kGestureSteps,
      base::Bind(&CancelCallbackHandler::CountedCancelCallback,
                 base::Unretained(&cancel_handler)));

  // Check that there was no size change.
  EXPECT_EQ(widget->GetWindowBoundsInScreen().size().ToString(),
            window_position.size().ToString());
  // Check that there is no phantom window left open.
  EXPECT_FALSE(maximize_button->phantom_window_open());
}

}  // namespace internal
}  // namespace ash
