// Copyright 2013 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/caption_buttons/frame_caption_button_container_view.h"

#include "ash/ash_switches.h"
#include "ash/test/ash_test_base.h"
#include "base/command_line.h"
#include "grit/ash_resources.h"
#include "ui/aura/root_window.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/views/border.h"
#include "ui/views/controls/button/custom_button.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

namespace ash {

namespace {

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

  virtual bool CanMaximize() const OVERRIDE {
    return can_maximize_;
  }

 private:
  bool can_maximize_;

  DISALLOW_COPY_AND_ASSIGN(TestWidgetDelegate);
};

}  // namespace

class FrameCaptionButtonContainerViewTest : public ash::test::AshTestBase {
 public:
  enum MaximizeAllowed {
    MAXIMIZE_ALLOWED,
    MAXIMIZE_DISALLOWED
  };

  FrameCaptionButtonContainerViewTest() {
  }

  virtual ~FrameCaptionButtonContainerViewTest() {
  }

  // Creates a widget which allows maximizing based on |maximize_allowed|.
  // The caller takes ownership of the returned widget.
  views::Widget* CreateTestWidget(
      MaximizeAllowed maximize_allowed) WARN_UNUSED_RESULT {
    views::Widget* widget = new views::Widget;
    views::Widget::InitParams params;
    params.delegate = new TestWidgetDelegate(
        maximize_allowed == MAXIMIZE_ALLOWED);
    params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
    params.context = CurrentContext();
    widget->Init(params);
    return widget;
  }

  // Tests that |leftmost| and |rightmost| are at |container|'s edges.
  bool CheckButtonsAtEdges(FrameCaptionButtonContainerView* container,
                           const views::CustomButton& leftmost,
                           const views::CustomButton& rightmost) {
    gfx::Rect expected(container->GetPreferredSize());
    expected.Inset(container->GetLeftInset(), 0, container->GetRightInset(), 0);

    gfx::Rect container_size(container->GetPreferredSize());
    if (leftmost.y() == rightmost.y() &&
        leftmost.height() == rightmost.height() &&
        leftmost.x() == expected.x() &&
        leftmost.y() == expected.y() &&
        leftmost.height() == expected.height() &&
        rightmost.bounds().right() == expected.right()) {
      return true;
    }

    LOG(ERROR) << "Buttons " << leftmost.bounds().ToString() << " "
               << rightmost.bounds().ToString() << " not at edges of "
               << expected.ToString();
    return false;
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(FrameCaptionButtonContainerViewTest);
};

class FrameCaptionButtonContainerViewTestOldStyle
    : public FrameCaptionButtonContainerViewTest {
 public:
  FrameCaptionButtonContainerViewTestOldStyle() {
  }

  virtual ~FrameCaptionButtonContainerViewTestOldStyle() {
  }

  // Returns true if the images for |button|'s states match the passed in ids.
  bool ImagesMatch(views::CustomButton* custom_button,
                   int normal_image_id,
                   int hovered_image_id,
                   int pressed_image_id) {
    views::ImageButton* button =
        static_cast<views::ImageButton*>(custom_button);
    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    gfx::ImageSkia* normal = rb.GetImageSkiaNamed(normal_image_id);
    gfx::ImageSkia* hovered = rb.GetImageSkiaNamed(hovered_image_id);
    gfx::ImageSkia* pressed = rb.GetImageSkiaNamed(pressed_image_id);
    using views::Button;
    gfx::ImageSkia actual_normal = button->GetImage(Button::STATE_NORMAL);
    gfx::ImageSkia actual_hovered = button->GetImage(Button::STATE_HOVERED);
    gfx::ImageSkia actual_pressed = button->GetImage(Button::STATE_PRESSED);
    return actual_normal.BackedBySameObjectAs(*normal) &&
        actual_hovered.BackedBySameObjectAs(*hovered) &&
        actual_pressed.BackedBySameObjectAs(*pressed);
  }

  virtual void SetUp() OVERRIDE {
    FrameCaptionButtonContainerViewTest::SetUp();
    CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kAshDisableAlternateFrameCaptionButtonStyle);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(FrameCaptionButtonContainerViewTestOldStyle);
};

// Test how the allowed actions affect which caption buttons are visible.
TEST_F(FrameCaptionButtonContainerViewTestOldStyle, ButtonVisibility) {
  // The minimize button should be hidden when both minimizing and maximizing
  // are allowed because the size button can do both.
  scoped_ptr<views::Widget> widget_can_maximize(
      CreateTestWidget(MAXIMIZE_ALLOWED));
  FrameCaptionButtonContainerView container1(widget_can_maximize.get(),
      FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
  container1.Layout();
  FrameCaptionButtonContainerView::TestApi t1(&container1);
  EXPECT_FALSE(t1.minimize_button()->visible());
  EXPECT_TRUE(t1.size_button()->visible());
  EXPECT_TRUE(t1.close_button()->visible());
  EXPECT_TRUE(CheckButtonsAtEdges(
      &container1, *t1.size_button(), *t1.close_button()));

  // The minimize button should be visible when minimizing is allowed but
  // maximizing is disallowed.
  scoped_ptr<views::Widget> widget_cannot_maximize(
      CreateTestWidget(MAXIMIZE_DISALLOWED));
  FrameCaptionButtonContainerView container2(widget_cannot_maximize.get(),
      FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
  container2.Layout();
  FrameCaptionButtonContainerView::TestApi t2(&container2);
  EXPECT_TRUE(t2.minimize_button()->visible());
  EXPECT_FALSE(t2.size_button()->visible());
  EXPECT_TRUE(t2.close_button()->visible());
  EXPECT_TRUE(CheckButtonsAtEdges(
      &container2, *t2.minimize_button(), *t2.close_button()));

  // Neither the minimize button nor the size button should be visible when
  // neither minimizing nor maximizing are allowed.
  FrameCaptionButtonContainerView container3(widget_cannot_maximize.get(),
      FrameCaptionButtonContainerView::MINIMIZE_DISALLOWED);
  container3.Layout();
  FrameCaptionButtonContainerView::TestApi t3(&container3);
  EXPECT_FALSE(t3.minimize_button()->visible());
  EXPECT_FALSE(t3.size_button()->visible());
  EXPECT_TRUE(t3.close_button()->visible());
  EXPECT_TRUE(CheckButtonsAtEdges(
      &container3, *t3.close_button(), *t3.close_button()));
}

// Test the layout when a border is set on the container.
TEST_F(FrameCaptionButtonContainerViewTestOldStyle, LayoutBorder) {
  const int kTopInset = 1;
  const int kLeftInset = 2;
  const int kBottomInset = 3;
  const int kRightInset = 4;

  scoped_ptr<views::Widget> widget(CreateTestWidget(MAXIMIZE_ALLOWED));
  FrameCaptionButtonContainerView container(widget.get(),
      FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
  container.set_border(views::Border::CreateEmptyBorder(
      kTopInset, kLeftInset, kBottomInset, kRightInset));
  container.Layout();
  FrameCaptionButtonContainerView::TestApi t(&container);

  EXPECT_EQ(kLeftInset, t.size_button()->x());
  EXPECT_EQ(kTopInset, t.close_button()->y());
  EXPECT_EQ(container.GetPreferredSize().height(),
            t.close_button()->bounds().bottom() + kBottomInset);
  EXPECT_EQ(container.GetPreferredSize().width(),
            t.close_button()->bounds().right() + kRightInset);
}

// Test how the header style affects which images are used for the buttons.
TEST_F(FrameCaptionButtonContainerViewTestOldStyle, HeaderStyle) {
  scoped_ptr<views::Widget> widget(CreateTestWidget(MAXIMIZE_ALLOWED));
  FrameCaptionButtonContainerView container(widget.get(),
      FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
  FrameCaptionButtonContainerView::TestApi t(&container);

  // Tall header style.
  container.set_header_style(
      FrameCaptionButtonContainerView::HEADER_STYLE_TALL);
  container.Layout();
  EXPECT_TRUE(ImagesMatch(t.size_button(),
                          IDR_AURA_WINDOW_MAXIMIZE,
                          IDR_AURA_WINDOW_MAXIMIZE_H,
                          IDR_AURA_WINDOW_MAXIMIZE_P));
  EXPECT_TRUE(ImagesMatch(t.close_button(),
                          IDR_AURA_WINDOW_CLOSE,
                          IDR_AURA_WINDOW_CLOSE_H,
                          IDR_AURA_WINDOW_CLOSE_P));

  // Short header style.
  container.set_header_style(
      FrameCaptionButtonContainerView::HEADER_STYLE_SHORT);
  container.Layout();
  EXPECT_TRUE(ImagesMatch(t.size_button(),
                          IDR_AURA_WINDOW_MAXIMIZED_RESTORE,
                          IDR_AURA_WINDOW_MAXIMIZED_RESTORE_H,
                          IDR_AURA_WINDOW_MAXIMIZED_RESTORE_P));
  EXPECT_TRUE(ImagesMatch(t.close_button(),
                          IDR_AURA_WINDOW_MAXIMIZED_CLOSE,
                          IDR_AURA_WINDOW_MAXIMIZED_CLOSE_H,
                          IDR_AURA_WINDOW_MAXIMIZED_CLOSE_P));

  // Maximized short header style.
  widget->Maximize();
  container.Layout();
  EXPECT_TRUE(ImagesMatch(t.size_button(),
                          IDR_AURA_WINDOW_MAXIMIZED_RESTORE2,
                          IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_H,
                          IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_P));
  EXPECT_TRUE(ImagesMatch(t.close_button(),
                          IDR_AURA_WINDOW_MAXIMIZED_CLOSE2,
                          IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_H,
                          IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_P));

  // The buttons are visible during a reveal of the top-of-window views in
  // immersive fullscreen. They should use the same images as maximized.
  widget->SetFullscreen(true);
  container.Layout();
  EXPECT_TRUE(ImagesMatch(t.size_button(),
                          IDR_AURA_WINDOW_MAXIMIZED_RESTORE2,
                          IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_H,
                          IDR_AURA_WINDOW_MAXIMIZED_RESTORE2_P));
  EXPECT_TRUE(ImagesMatch(t.close_button(),
                          IDR_AURA_WINDOW_MAXIMIZED_CLOSE2,
                          IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_H,
                          IDR_AURA_WINDOW_MAXIMIZED_CLOSE2_P));

  // AppNonClientFrameViewAsh has a dedicated set of images.
  container.set_header_style(
      FrameCaptionButtonContainerView::HEADER_STYLE_MAXIMIZED_HOSTED_APP);
  container.Layout();
  EXPECT_TRUE(ImagesMatch(t.size_button(),
                          IDR_AURA_WINDOW_FULLSCREEN_RESTORE,
                          IDR_AURA_WINDOW_FULLSCREEN_RESTORE_H,
                          IDR_AURA_WINDOW_FULLSCREEN_RESTORE_P));
  EXPECT_TRUE(ImagesMatch(t.close_button(),
                          IDR_AURA_WINDOW_FULLSCREEN_CLOSE,
                          IDR_AURA_WINDOW_FULLSCREEN_CLOSE_H,
                          IDR_AURA_WINDOW_FULLSCREEN_CLOSE_P));
}

class FrameCaptionButtonContainerViewTestAlternateStyle
    : public FrameCaptionButtonContainerViewTest {
 public:
  FrameCaptionButtonContainerViewTestAlternateStyle() {
  }

  virtual ~FrameCaptionButtonContainerViewTestAlternateStyle() {
  }

  virtual void SetUp() OVERRIDE {
    FrameCaptionButtonContainerViewTest::SetUp();
    CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kAshEnableAlternateFrameCaptionButtonStyle);
    ASSERT_TRUE(switches::UseAlternateFrameCaptionButtonStyle());
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(FrameCaptionButtonContainerViewTestAlternateStyle);
};

// Test how the alternate button style affects which buttons are visible in the
// default case.
TEST_F(FrameCaptionButtonContainerViewTestAlternateStyle, ButtonVisibility) {
  // Both the minimize button and the maximize button should be visible when
  // both minimizing and maximizing are allowed when using the alternate
  // button style.
  scoped_ptr<views::Widget> widget_can_maximize(
      CreateTestWidget(MAXIMIZE_ALLOWED));
  FrameCaptionButtonContainerView container(widget_can_maximize.get(),
      FrameCaptionButtonContainerView::MINIMIZE_ALLOWED);
  container.Layout();
  FrameCaptionButtonContainerView::TestApi t(&container);
  EXPECT_TRUE(t.minimize_button()->visible());
  EXPECT_TRUE(t.size_button()->visible());
  EXPECT_TRUE(t.close_button()->visible());
  EXPECT_TRUE(CheckButtonsAtEdges(
      &container, *t.minimize_button(), *t.close_button()));
}

}  // namespace ash
