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

#include "base/macros.h"
#include "ui/base/hit_test.h"
#include "ui/events/event_utils.h"
#include "ui/views/bubble/bubble_delegate.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/test/test_widget_observer.h"
#include "ui/views/test/views_test_base.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_observer.h"

namespace views {

namespace {

class TestBubbleDelegateView : public BubbleDelegateView {
 public:
  TestBubbleDelegateView(View* anchor_view)
      : BubbleDelegateView(anchor_view, BubbleBorder::TOP_LEFT),
        view_(new View()) {
    view_->SetFocusable(true);
    AddChildView(view_);
  }
  ~TestBubbleDelegateView() override {}

  void SetAnchorRectForTest(gfx::Rect rect) {
    SetAnchorRect(rect);
  }

  void SetAnchorViewForTest(View* view) {
    SetAnchorView(view);
  }

  // BubbleDelegateView overrides:
  View* GetInitiallyFocusedView() override { return view_; }
  gfx::Size GetPreferredSize() const override { return gfx::Size(200, 200); }

  BubbleFrameView* GetBubbleFrameViewForTest() const {
    return GetBubbleFrameView();
  }

 private:
  View* view_;

  DISALLOW_COPY_AND_ASSIGN(TestBubbleDelegateView);
};

class BubbleDelegateTest : public ViewsTestBase {
 public:
  BubbleDelegateTest() {}
  ~BubbleDelegateTest() override {}

  // Creates a test widget that owns its native widget.
  Widget* CreateTestWidget() {
    Widget* widget = new Widget();
    Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
    params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    widget->Init(params);
    return widget;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(BubbleDelegateTest);
};

}  // namespace

TEST_F(BubbleDelegateTest, CreateDelegate) {
  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
      anchor_widget->GetContentsView(), BubbleBorder::NONE);
  bubble_delegate->set_color(SK_ColorGREEN);
  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
  EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate());
  EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget());
  test::TestWidgetObserver bubble_observer(bubble_widget);
  bubble_widget->Show();

  BubbleBorder* border = bubble_delegate->GetBubbleFrameView()->bubble_border();
  EXPECT_EQ(bubble_delegate->arrow(), border->arrow());
  EXPECT_EQ(bubble_delegate->color(), border->background_color());

  EXPECT_FALSE(bubble_observer.widget_closed());
  bubble_widget->CloseNow();
  EXPECT_TRUE(bubble_observer.widget_closed());
}

TEST_F(BubbleDelegateTest, CloseAnchorWidget) {
  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
      anchor_widget->GetContentsView(), BubbleBorder::NONE);
  // Preventing close on deactivate should not prevent closing with the anchor.
  bubble_delegate->set_close_on_deactivate(false);
  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
  EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate());
  EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget());
  EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());
  test::TestWidgetObserver bubble_observer(bubble_widget);
  EXPECT_FALSE(bubble_observer.widget_closed());

  bubble_widget->Show();
  EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());
  EXPECT_FALSE(bubble_observer.widget_closed());

  // TODO(msw): Remove activation hack to prevent bookkeeping errors in:
  //            aura::test::TestActivationClient::OnWindowDestroyed().
  scoped_ptr<Widget> smoke_and_mirrors_widget(CreateTestWidget());
  EXPECT_FALSE(bubble_observer.widget_closed());

  // Ensure that closing the anchor widget also closes the bubble itself.
  anchor_widget->CloseNow();
  EXPECT_TRUE(bubble_observer.widget_closed());
}

// This test checks that the bubble delegate is capable to handle an early
// destruction of the used anchor view. (Animations and delayed closure of the
// bubble will call upon the anchor view to get its location).
TEST_F(BubbleDelegateTest, CloseAnchorViewTest) {
  // Create an anchor widget and add a view to be used as an anchor view.
  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
  scoped_ptr<View> anchor_view(new View());
  anchor_widget->GetContentsView()->AddChildView(anchor_view.get());
  TestBubbleDelegateView* bubble_delegate = new TestBubbleDelegateView(
      anchor_view.get());
  // Prevent flakes by avoiding closing on activation changes.
  bubble_delegate->set_close_on_deactivate(false);
  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);

  // Check that the anchor view is correct and set up an anchor view rect.
  // Make sure that this rect will get ignored (as long as the anchor view is
  // attached).
  EXPECT_EQ(anchor_view.get(), bubble_delegate->GetAnchorView());
  const gfx::Rect set_anchor_rect = gfx::Rect(10, 10, 100, 100);
  bubble_delegate->SetAnchorRectForTest(set_anchor_rect);
  const gfx::Rect view_rect = bubble_delegate->GetAnchorRect();
  EXPECT_NE(view_rect.ToString(), set_anchor_rect.ToString());

  // Create the bubble.
  bubble_widget->Show();
  EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());

  // Remove now the anchor view and make sure that the original found rect
  // is still kept, so that the bubble does not jump when the view gets deleted.
  anchor_widget->GetContentsView()->RemoveChildView(anchor_view.get());
  anchor_view.reset();
  EXPECT_EQ(NULL, bubble_delegate->GetAnchorView());
  EXPECT_EQ(view_rect.ToString(), bubble_delegate->GetAnchorRect().ToString());
}

// Testing that a move of the anchor view will lead to new bubble locations.
TEST_F(BubbleDelegateTest, TestAnchorRectMovesWithViewTest) {
  // Create an anchor widget and add a view to be used as anchor view.
  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
  TestBubbleDelegateView* bubble_delegate = new TestBubbleDelegateView(
      anchor_widget->GetContentsView());
  BubbleDelegateView::CreateBubble(bubble_delegate);

  anchor_widget->GetContentsView()->SetBounds(10, 10, 100, 100);
  const gfx::Rect view_rect = bubble_delegate->GetAnchorRect();

  anchor_widget->GetContentsView()->SetBounds(20, 10, 100, 100);
  const gfx::Rect view_rect_2 = bubble_delegate->GetAnchorRect();
  EXPECT_NE(view_rect.ToString(), view_rect_2.ToString());
}

TEST_F(BubbleDelegateTest, ResetAnchorWidget) {
  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
      anchor_widget->GetContentsView(), BubbleBorder::NONE);

  // Make sure the bubble widget is parented to a widget other than the anchor
  // widget so that closing the anchor widget does not close the bubble widget.
  scoped_ptr<Widget> parent_widget(CreateTestWidget());
  bubble_delegate->set_parent_window(parent_widget->GetNativeView());
  // Preventing close on deactivate should not prevent closing with the parent.
  bubble_delegate->set_close_on_deactivate(false);
  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
  EXPECT_EQ(bubble_delegate, bubble_widget->widget_delegate());
  EXPECT_EQ(bubble_widget, bubble_delegate->GetWidget());
  EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());
  test::TestWidgetObserver bubble_observer(bubble_widget);
  EXPECT_FALSE(bubble_observer.widget_closed());

  // Showing and hiding the bubble widget should have no effect on its anchor.
  bubble_widget->Show();
  EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());
  bubble_widget->Hide();
  EXPECT_EQ(anchor_widget.get(), bubble_delegate->anchor_widget());

  // Ensure that closing the anchor widget clears the bubble's reference to that
  // anchor widget, but the bubble itself does not close.
  anchor_widget->CloseNow();
  EXPECT_NE(anchor_widget.get(), bubble_delegate->anchor_widget());
  EXPECT_FALSE(bubble_observer.widget_closed());

  // TODO(msw): Remove activation hack to prevent bookkeeping errors in:
  //            aura::test::TestActivationClient::OnWindowDestroyed().
  scoped_ptr<Widget> smoke_and_mirrors_widget(CreateTestWidget());
  EXPECT_FALSE(bubble_observer.widget_closed());

  // Ensure that closing the parent widget also closes the bubble itself.
  parent_widget->CloseNow();
  EXPECT_TRUE(bubble_observer.widget_closed());
}

TEST_F(BubbleDelegateTest, InitiallyFocusedView) {
  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
      anchor_widget->GetContentsView(), BubbleBorder::NONE);
  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
  EXPECT_EQ(bubble_delegate->GetInitiallyFocusedView(),
            bubble_widget->GetFocusManager()->GetFocusedView());
  bubble_widget->CloseNow();
}

TEST_F(BubbleDelegateTest, NonClientHitTest) {
  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
  TestBubbleDelegateView* bubble_delegate =
      new TestBubbleDelegateView(anchor_widget->GetContentsView());
  BubbleDelegateView::CreateBubble(bubble_delegate);
  BubbleFrameView* frame = bubble_delegate->GetBubbleFrameView();
  const int border = frame->bubble_border()->GetBorderThickness();

  struct {
    const int point;
    const int hit;
  } cases[] = {
    { border,      HTNOWHERE },
    { border + 50, HTCLIENT  },
    { 1000,        HTNOWHERE },
  };

  for (size_t i = 0; i < arraysize(cases); ++i) {
    gfx::Point point(cases[i].point, cases[i].point);
    EXPECT_EQ(cases[i].hit, frame->NonClientHitTest(point))
        << " with border: " << border << ", at point " << cases[i].point;
  }
}

TEST_F(BubbleDelegateTest, VisibleWhenAnchorWidgetBoundsChanged) {
  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
      anchor_widget->GetContentsView(), BubbleBorder::NONE);
  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
  test::TestWidgetObserver bubble_observer(bubble_widget);
  EXPECT_FALSE(bubble_observer.widget_closed());

  anchor_widget->Show();
  bubble_widget->Show();
  EXPECT_TRUE(bubble_widget->IsVisible());
  anchor_widget->SetBounds(gfx::Rect(10, 10, 100, 100));
  EXPECT_TRUE(bubble_widget->IsVisible());
}

// Test that setting WidgetDelegate::set_can_activate() to false makes the
// widget created via BubbleDelegateView::CreateBubble() not activatable.
TEST_F(BubbleDelegateTest, NotActivatable) {
  scoped_ptr<Widget> anchor_widget(CreateTestWidget());
  BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
      anchor_widget->GetContentsView(), BubbleBorder::NONE);
  bubble_delegate->set_can_activate(false);
  Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
  bubble_widget->Show();
  EXPECT_FALSE(bubble_widget->CanActivate());
}

TEST_F(BubbleDelegateTest, CloseReasons) {
  {
    scoped_ptr<Widget> anchor_widget(CreateTestWidget());
    BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
        anchor_widget->GetContentsView(), BubbleBorder::NONE);
    bubble_delegate->set_close_on_deactivate(true);
    Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
    bubble_widget->Show();
    anchor_widget->Activate();
    EXPECT_TRUE(bubble_widget->IsClosed());
    EXPECT_EQ(BubbleDelegateView::CloseReason::DEACTIVATION,
              bubble_delegate->close_reason());
  }

  {
    scoped_ptr<Widget> anchor_widget(CreateTestWidget());
    BubbleDelegateView* bubble_delegate = new BubbleDelegateView(
        anchor_widget->GetContentsView(), BubbleBorder::NONE);
    bubble_delegate->set_close_on_esc(true);
    Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
    bubble_widget->Show();
    // Cast as a test hack to access AcceleratorPressed() (which is protected
    // in BubbleDelegate).
    static_cast<View*>(bubble_delegate)
        ->AcceleratorPressed(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE));
    EXPECT_TRUE(bubble_widget->IsClosed());
    EXPECT_EQ(BubbleDelegateView::CloseReason::ESCAPE,
              bubble_delegate->close_reason());
  }

  {
    scoped_ptr<Widget> anchor_widget(CreateTestWidget());
    TestBubbleDelegateView* bubble_delegate =
        new TestBubbleDelegateView(anchor_widget->GetContentsView());
    Widget* bubble_widget = BubbleDelegateView::CreateBubble(bubble_delegate);
    bubble_widget->Show();
    BubbleFrameView* frame_view = bubble_delegate->GetBubbleFrameViewForTest();
    LabelButton* close_button = frame_view->close_;
    ASSERT_TRUE(close_button);
    frame_view->ButtonPressed(
        close_button,
        ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::Point(0, 0), gfx::Point(0, 0),
                       ui::EventTimeForNow(), ui::EF_NONE, ui::EF_NONE));
    EXPECT_TRUE(bubble_widget->IsClosed());
    EXPECT_EQ(BubbleDelegateView::CloseReason::CLOSE_BUTTON,
              bubble_delegate->close_reason());
  }
}

}  // namespace views
