// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "renderer/unix/window_manager.h"

#include "testing/base/public/gunit.h"
#include "testing/base/public/gmock.h"
#include "renderer/unix/gtk_window_mock.h"
#include "renderer/unix/gtk_wrapper_mock.h"

using ::testing::Expectation;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::StrEq;
using ::testing::StrictMock;
using ::testing::_;

namespace mozc {
namespace renderer {
namespace gtk {

namespace {
MATCHER_P(PointEq, expected_point, "The expected point does not match") {
  return (arg.x == expected_point.x) && (arg.y == expected_point.y);
}
}  // namespace

TEST(WindowManagerTest, InitializeTest) {
  GtkWindowMock *candidate_window_mock = new GtkWindowMock();
  GtkWindowMock *infolist_window_mock = new GtkWindowMock();
  GtkWrapperMock *gtk_mock = new GtkWrapperMock();

  Expectation candidate_show
      = EXPECT_CALL(*candidate_window_mock, ShowWindow());
  EXPECT_CALL(*candidate_window_mock, HideWindow()).After(candidate_show);
  EXPECT_CALL(*candidate_window_mock, Initialize()).After(candidate_show);

  Expectation infolist_show = EXPECT_CALL(*infolist_window_mock, ShowWindow());
  EXPECT_CALL(*infolist_window_mock, HideWindow()).After(candidate_show);
  EXPECT_CALL(*infolist_window_mock, Initialize()).After(candidate_show);

  WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock);

  manager.Initialize();
}

TEST(WindowManagerTest, HideAllWindowsTest) {
  GtkWindowMock *candidate_window_mock = new GtkWindowMock();
  GtkWindowMock *infolist_window_mock = new GtkWindowMock();
  GtkWrapperMock *gtk_mock = new GtkWrapperMock();

  EXPECT_CALL(*candidate_window_mock, HideWindow());
  EXPECT_CALL(*infolist_window_mock, HideWindow());

  WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock);

  manager.HideAllWindows();
}

TEST(WindowManagerTest, ShowAllWindowsTest) {
  GtkWindowMock *candidate_window_mock = new GtkWindowMock();
  GtkWindowMock *infolist_window_mock = new GtkWindowMock();
  GtkWrapperMock *gtk_mock = new GtkWrapperMock();

  EXPECT_CALL(*candidate_window_mock, ShowWindow());
  EXPECT_CALL(*infolist_window_mock, ShowWindow());

  WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock);

  manager.ShowAllWindows();
}

TEST(WindowManagerTest, UpdateLayoutTest) {
  {
    SCOPED_TRACE("Empty candidates should hide window, and do nothing.");
    commands::RendererCommand command;

    GtkWindowMock *candidate_window_mock = new StrictMock<GtkWindowMock>();
    GtkWindowMock *infolist_window_mock = new StrictMock<GtkWindowMock>();
    GtkWrapperMock *gtk_mock = new StrictMock<GtkWrapperMock>();

    EXPECT_CALL(*candidate_window_mock, HideWindow());
    EXPECT_CALL(*infolist_window_mock, HideWindow());

    WindowManager manager(candidate_window_mock, infolist_window_mock,
                          gtk_mock);

    manager.UpdateLayout(command);
  }
  {
    // Other case of UpdateLayout test is break-downed as UpdateCandidateWindow
    // and UpdateInfolistWindow.
  }
}

TEST(WindowManagerTest, ActivateTest) {
  // TODO(nona): Implement activate.
}

TEST(WindowManagerTest, IsAvailable) {
  // TODO(nona): Implement IsAvailable.
}

TEST(WindowManagerTest, SetSendCommandInterfaceTest) {
  GtkWindowMock *candidate_window_mock = new GtkWindowMock();
  GtkWindowMock *infolist_window_mock = new GtkWindowMock();
  GtkWrapperMock *gtk_mock = new GtkWrapperMock();

  client::SendCommandInterface *send_command_interface
      = reinterpret_cast<client::SendCommandInterface *>(0x12345678);

  WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock);
  manager.SetSendCommandInterface(send_command_interface);

  EXPECT_EQ(send_command_interface, manager.send_command_interface_);
}

TEST(WindowManagerTest, SetWindowPosTest) {
  GtkWindowMock *candidate_window_mock = new GtkWindowMock();
  GtkWindowMock *infolist_window_mock = new GtkWindowMock();
  GtkWrapperMock *gtk_mock = new GtkWrapperMock();

  const Point direction(10, 20);
  EXPECT_CALL(*candidate_window_mock, Move(PointEq(direction)));

  WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock);
  manager.SetWindowPos(direction.x, direction.y);
}

TEST(WindowManagerTest, ShouldShowCandidateWindowTest) {
  {
    SCOPED_TRACE("If it is not visible, return false.");
    commands::RendererCommand command;
    command.set_visible(false);
    command.mutable_output()->mutable_candidates();

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_FALSE(manager.ShouldShowCandidateWindow(command));
  }
  {
    SCOPED_TRACE("If there is no Candidates message, return false.");
    commands::RendererCommand command;
    command.set_visible(true);
    command.mutable_output();

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_FALSE(manager.ShouldShowCandidateWindow(command));
  }
  {
    SCOPED_TRACE("If there are no candidates, return false.");
    commands::RendererCommand command;
    command.set_visible(true);
    command.mutable_output()->mutable_candidates();

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_FALSE(manager.ShouldShowCandidateWindow(command));
  }
  {
    commands::RendererCommand command;
    command.set_visible(true);
    commands::Candidates *candidates
        = command.mutable_output()->mutable_candidates();
    candidates->add_candidate();

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_TRUE(manager.ShouldShowCandidateWindow(command));
  }
}

TEST(WindowManagerTest, ShouldShowInfolistWindowTest) {
  {
    SCOPED_TRACE("If it is not visible, return false.");
    commands::RendererCommand command;
    command.set_visible(false);
    command.mutable_output()->mutable_candidates();

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_FALSE(manager.ShouldShowInfolistWindow(command));
  }
  {
    SCOPED_TRACE("If there is no Candidates message, return false.");
    commands::RendererCommand command;
    command.set_visible(true);
    command.mutable_output();

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_FALSE(manager.ShouldShowInfolistWindow(command));
  }
  {
    SCOPED_TRACE("If there are no candidates, return false.");
    commands::RendererCommand command;
    command.set_visible(true);
    command.mutable_output()->mutable_candidates();

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_FALSE(manager.ShouldShowInfolistWindow(command));
  }
  {
    SCOPED_TRACE("If there is no usages message, return false");
    commands::RendererCommand command;
    command.set_visible(true);
    commands::Candidates *candidates
        = command.mutable_output()->mutable_candidates();
    candidates->add_candidate();

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_FALSE(manager.ShouldShowInfolistWindow(command));
  }
  {
    SCOPED_TRACE("If there is no Information List message, return false");
    commands::RendererCommand command;
    command.set_visible(true);
    commands::Candidates *candidates
        = command.mutable_output()->mutable_candidates();
    candidates->add_candidate();

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_FALSE(manager.ShouldShowInfolistWindow(command));
  }
  {
    SCOPED_TRACE("If there are no information, return false");
    commands::RendererCommand command;
    command.set_visible(true);
    commands::Candidates *candidates
        = command.mutable_output()->mutable_candidates();
    candidates->add_candidate();
    commands::InformationList *usage = candidates->mutable_usages();
    usage->add_information();

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_FALSE(manager.ShouldShowInfolistWindow(command));
  }
  {
    SCOPED_TRACE("If focused index is out of range, return false");
    commands::RendererCommand command;
    command.set_visible(true);
    commands::Candidates *candidates
        = command.mutable_output()->mutable_candidates();
    candidates->add_candidate();
    commands::InformationList *usage = candidates->mutable_usages();
    usage->add_information();

    candidates->set_focused_index(3);

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_FALSE(manager.ShouldShowInfolistWindow(command));
  }
  {
    SCOPED_TRACE("If focused candidate has no information, return false");
    commands::RendererCommand command;
    command.set_visible(true);
    commands::Candidates *candidates
        = command.mutable_output()->mutable_candidates();
    commands::Candidates_Candidate *candidate = candidates->add_candidate();
    commands::InformationList *usage = candidates->mutable_usages();
    usage->add_information();

    candidates->set_focused_index(0);
    candidate->set_index(0);

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_FALSE(manager.ShouldShowInfolistWindow(command));
  }
  {
    commands::RendererCommand command;
    command.set_visible(true);
    commands::Candidates *candidates
        = command.mutable_output()->mutable_candidates();
    commands::Candidates_Candidate *candidate = candidates->add_candidate();

    commands::InformationList *usage = candidates->mutable_usages();
    usage->add_information();

    candidates->set_focused_index(0);
    candidate->set_information_id(0);

    WindowManager manager(NULL, NULL, NULL);
    EXPECT_TRUE(manager.ShouldShowInfolistWindow(command));
  }
}

TEST(WindowManagerTest, UpdateCandidateWindowTest) {
  // TODO(nona): Cleanup redundant codes.
  {
    SCOPED_TRACE("Use caret location");
    GtkWindowMock *candidate_window_mock = new GtkWindowMock();
    GtkWindowMock *infolist_window_mock = new GtkWindowMock();
    GtkWrapperMock *gtk_mock = new GtkWrapperMock();

    commands::RendererCommand command;
    command.set_visible(true);
    commands::Candidates *candidates
        = command.mutable_output()->mutable_candidates();
    candidates->set_focused_index(0);

    commands::Candidates_Candidate *candidate = candidates->add_candidate();
    candidate->set_information_id(0);

    commands::InformationList *usage = candidates->mutable_usages();
    usage->add_information();

    const Rect client_cord_rect(10, 20, 30, 40);
    const Point window_position(15, 25);
    const Size window_size(35, 45);
    const gint monitor = 0x7777;

    candidates->set_window_location(commands::Candidates::CARET);
    const Rect caret_rect(16, 26, 2, 13);
    commands::Rectangle *rectangle = candidates->mutable_caret_rectangle();
    rectangle->set_x(caret_rect.Left());
    rectangle->set_y(caret_rect.Top());
    rectangle->set_width(caret_rect.Width());
    rectangle->set_height(caret_rect.Height());
    const Point expected_window_position(
        caret_rect.Left() - client_cord_rect.Left(),
        caret_rect.Top() + caret_rect.Height());

    EXPECT_CALL(*candidate_window_mock, Update(_))
        .WillOnce(Return(window_size));
    EXPECT_CALL(*candidate_window_mock, GetCandidateColumnInClientCord())
        .WillOnce(Return(client_cord_rect));
    EXPECT_CALL(*candidate_window_mock, GetWindowPos())
        .WillOnce(Return(window_position));
    EXPECT_CALL(*candidate_window_mock,
                Move(PointEq(expected_window_position)));
    EXPECT_CALL(*candidate_window_mock, ShowWindow());

    GtkWidget *toplevel_widget = reinterpret_cast<GtkWidget*>(0x12345678);
    GdkScreen *toplevel_screen = reinterpret_cast<GdkScreen*>(0x87654321);
    const GdkRectangle monitor_rect = {0, 0, 4000, 4000};
    EXPECT_CALL(*gtk_mock, GtkWindowNew(GTK_WINDOW_TOPLEVEL))
        .WillOnce(Return(toplevel_widget));
    EXPECT_CALL(*gtk_mock, GtkWindowGetScreen(toplevel_widget))
        .WillOnce(Return(toplevel_screen));
    EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorAtPoint(toplevel_screen,
                                                      caret_rect.Left(),
                                                      caret_rect.Bottom()))
        .WillOnce(Return(monitor));
    EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorGeometry(toplevel_screen,
                                                       monitor,
                                                       NotNull()))
        .WillOnce(SetArgPointee<2>(monitor_rect));

    WindowManager manager(candidate_window_mock, infolist_window_mock,
                          gtk_mock);
    const Rect actual_rect = manager.UpdateCandidateWindow(command);

    EXPECT_EQ(actual_rect.origin.x, expected_window_position.x);
    EXPECT_EQ(actual_rect.origin.y, expected_window_position.y);
    EXPECT_EQ(actual_rect.size.width, window_size.width);
    EXPECT_EQ(actual_rect.size.height, window_size.height);
  }
  {
    SCOPED_TRACE("Use composition rectangle");
    GtkWindowMock *candidate_window_mock = new GtkWindowMock();
    GtkWindowMock *infolist_window_mock = new GtkWindowMock();
    GtkWrapperMock *gtk_mock = new GtkWrapperMock();

    commands::RendererCommand command;
    command.set_visible(true);
    commands::Candidates *candidates
        = command.mutable_output()->mutable_candidates();
    candidates->set_focused_index(0);

    commands::Candidates_Candidate *candidate = candidates->add_candidate();
    candidate->set_information_id(0);

    commands::InformationList *usage = candidates->mutable_usages();
    usage->add_information();

    const Rect client_cord_rect(10, 20, 30, 40);
    const Point window_position(15, 25);
    const Size window_size(35, 45);
    const gint monitor = 0x7777;

    candidates->set_window_location(commands::Candidates::COMPOSITION);
    const Rect comp_rect(16, 26, 2, 13);
    commands::Rectangle *rectangle
        = candidates->mutable_composition_rectangle();
    rectangle->set_x(comp_rect.Left());
    rectangle->set_y(comp_rect.Top());
    rectangle->set_width(comp_rect.Width());
    rectangle->set_height(comp_rect.Height());
    const Point expected_window_position(
        comp_rect.Left() - client_cord_rect.Left(),
        comp_rect.Top() + comp_rect.Height());

    EXPECT_CALL(*candidate_window_mock, Update(_))
        .WillOnce(Return(window_size));
    EXPECT_CALL(*candidate_window_mock, GetCandidateColumnInClientCord())
        .WillOnce(Return(client_cord_rect));
    EXPECT_CALL(*candidate_window_mock, GetWindowPos())
        .WillOnce(Return(window_position));
    EXPECT_CALL(*candidate_window_mock,
                Move(PointEq(expected_window_position)));
    EXPECT_CALL(*candidate_window_mock, ShowWindow());

    GtkWidget *toplevel_widget = reinterpret_cast<GtkWidget*>(0x12345678);
    GdkScreen *toplevel_screen = reinterpret_cast<GdkScreen*>(0x87654321);
    const GdkRectangle monitor_rect = {0, 0, 4000, 4000};
    EXPECT_CALL(*gtk_mock, GtkWindowNew(GTK_WINDOW_TOPLEVEL))
        .WillOnce(Return(toplevel_widget));
    EXPECT_CALL(*gtk_mock, GtkWindowGetScreen(toplevel_widget))
        .WillOnce(Return(toplevel_screen));
    EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorAtPoint(toplevel_screen,
                                                      comp_rect.Left(),
                                                      comp_rect.Bottom()))
        .WillOnce(Return(monitor));
    EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorGeometry(toplevel_screen,
                                                       monitor,
                                                       NotNull()))
        .WillOnce(SetArgPointee<2>(monitor_rect));

    WindowManager manager(candidate_window_mock, infolist_window_mock,
                          gtk_mock);
    const Rect actual_rect = manager.UpdateCandidateWindow(command);

    EXPECT_EQ(actual_rect.origin.x, expected_window_position.x);
    EXPECT_EQ(actual_rect.origin.y, expected_window_position.y);
    EXPECT_EQ(actual_rect.size.width, window_size.width);
    EXPECT_EQ(actual_rect.size.height, window_size.height);
  }
  {
    SCOPED_TRACE("Edge fixing");
    GtkWindowMock *candidate_window_mock = new GtkWindowMock();
    GtkWindowMock *infolist_window_mock = new GtkWindowMock();
    GtkWrapperMock *gtk_mock = new GtkWrapperMock();

    commands::RendererCommand command;
    commands::Candidates *candidates
        = command.mutable_output()->mutable_candidates();
    candidates->add_candidate();

    GtkWidget *toplevel_widget = reinterpret_cast<GtkWidget*>(0x12345678);
    GdkScreen *toplevel_screen = reinterpret_cast<GdkScreen*>(0x87654321);
    const Rect client_cord_rect(0, 0, 30, 40);
    const Point window_position(1000, 1000);
    const Size window_size(300, 400);
    const GdkRectangle monitor_rect = {0, 0, 1200, 1200};
    const gint monitor = 0x7777;

    EXPECT_CALL(*candidate_window_mock, Update(_))
        .WillOnce(Return(window_size));
    EXPECT_CALL(*candidate_window_mock, GetCandidateColumnInClientCord())
        .WillOnce(Return(client_cord_rect));
    EXPECT_CALL(*candidate_window_mock, GetWindowPos())
        .WillOnce(Return(window_position));
    EXPECT_CALL(*candidate_window_mock, Move(_));
    EXPECT_CALL(*candidate_window_mock, ShowWindow());

    EXPECT_CALL(*gtk_mock, GtkWindowNew(GTK_WINDOW_TOPLEVEL))
        .WillOnce(Return(toplevel_widget));
    EXPECT_CALL(*gtk_mock, GtkWindowGetScreen(toplevel_widget))
        .WillOnce(Return(toplevel_screen));
    EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorAtPoint(toplevel_screen,
                                                      window_position.x,
                                                      window_position.y))
        .WillOnce(Return(monitor));
    EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorGeometry(toplevel_screen,
                                                       monitor,
                                                       NotNull()))
        .WillOnce(SetArgPointee<2>(monitor_rect));

    WindowManager manager(candidate_window_mock, infolist_window_mock,
                          gtk_mock);
    const Rect actual_rect = manager.UpdateCandidateWindow(command);

    EXPECT_GE(actual_rect.Left(), monitor_rect.x);
    EXPECT_GE(actual_rect.Top(), monitor_rect.y);
    EXPECT_LE(actual_rect.Right(), monitor_rect.x + monitor_rect.width);
    EXPECT_LE(actual_rect.Bottom(), monitor_rect.y + monitor_rect.height);
  }
}

TEST(WindowManagerTest, UpdateInfolistWindowTest) {
  {
    SCOPED_TRACE("If there are no information, should hide and do nothing");
    GtkWindowMock *candidate_window_mock = new StrictMock<GtkWindowMock>();
    GtkWindowMock *infolist_window_mock = new StrictMock<GtkWindowMock>();
    GtkWrapperMock *gtk_mock = new StrictMock<GtkWrapperMock>();

    commands::RendererCommand command;
    command.set_visible(false);

    EXPECT_CALL(*infolist_window_mock, HideWindow());
    const Rect candidate_window_rect(10, 20, 30, 40);

    WindowManager manager(candidate_window_mock, infolist_window_mock,
                          gtk_mock);
    manager.UpdateInfolistWindow(command, candidate_window_rect);
  }
  {
    GtkWindowMock *candidate_window_mock = new GtkWindowMock();
    GtkWindowMock *infolist_window_mock = new GtkWindowMock();
    GtkWrapperMock *gtk_mock = new GtkWrapperMock();

    commands::RendererCommand command;
    command.set_visible(true);
    commands::Candidates *candidates
        = command.mutable_output()->mutable_candidates();
    commands::Candidates_Candidate *candidate = candidates->add_candidate();

    commands::InformationList *usage = candidates->mutable_usages();
    usage->add_information();

    candidates->set_focused_index(0);
    candidate->set_information_id(0);

    GtkWidget *toplevel_widget = reinterpret_cast<GtkWidget*>(0x12345678);
    GdkScreen *toplevel_screen = reinterpret_cast<GdkScreen*>(0x87654321);
    const GdkRectangle monitor_rect = {15, 25, 35, 45};
    const gint monitor = 0x7777;
    const Rect cand_window_rect(10, 20, 30, 40);

    EXPECT_CALL(*gtk_mock, GtkWindowNew(GTK_WINDOW_TOPLEVEL))
        .WillOnce(Return(toplevel_widget));
    EXPECT_CALL(*gtk_mock, GtkWindowGetScreen(toplevel_widget))
        .WillOnce(Return(toplevel_screen));
    EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorAtPoint(toplevel_screen,
                                                      cand_window_rect.Left(),
                                                      cand_window_rect.Top()))
        .WillOnce(Return(monitor));
    EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorGeometry(toplevel_screen,
                                                       monitor,
                                                       NotNull()))
        .WillOnce(SetArgPointee<2>(monitor_rect));


    // TODO(nona): Make precise expectation.
    const Size infolist_window_size(10, 20);
    EXPECT_CALL(*infolist_window_mock, Move(_));
    EXPECT_CALL(*infolist_window_mock, ShowWindow());
    EXPECT_CALL(*infolist_window_mock, HideWindow()).Times(0);
    EXPECT_CALL(*infolist_window_mock, Update(_))
        .WillOnce(Return(infolist_window_size));

    WindowManager manager(candidate_window_mock, infolist_window_mock,
                          gtk_mock);

    EXPECT_TRUE(manager.ShouldShowInfolistWindow(command));
    manager.UpdateInfolistWindow(command, cand_window_rect);
  }
}

TEST(WindowManagerTest, GetMonitorRectTest) {
  GtkWindowMock *candidate_window_mock = new GtkWindowMock();
  GtkWindowMock *infolist_window_mock = new GtkWindowMock();
  GtkWrapperMock *gtk_mock = new GtkWrapperMock();
  GtkWidget *toplevel_widget = reinterpret_cast<GtkWidget*>(0x12345678);
  GdkScreen *toplevel_screen = reinterpret_cast<GdkScreen*>(0x87654321);
  const gint monitor = 0x7777;
  const Point cursor(123, 456);

  const GdkRectangle monitor_rect = {10, 20, 35, 45};
  EXPECT_CALL(*gtk_mock, GtkWindowNew(GTK_WINDOW_TOPLEVEL))
      .WillOnce(Return(toplevel_widget));
  EXPECT_CALL(*gtk_mock, GtkWindowGetScreen(toplevel_widget))
      .WillOnce(Return(toplevel_screen));
  EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorAtPoint(toplevel_screen,
                                                    cursor.x,
                                                    cursor.y))
      .WillOnce(Return(monitor));
  EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorGeometry(toplevel_screen,
                                                     monitor,
                                                     NotNull()))
      .WillOnce(SetArgPointee<2>(monitor_rect));

  WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock);

  const Rect &actual_monitor_rect = manager.GetMonitorRect(cursor.x, cursor.y);
  EXPECT_EQ(monitor_rect.x, actual_monitor_rect.origin.x);
  EXPECT_EQ(monitor_rect.y, actual_monitor_rect.origin.y);
  EXPECT_EQ(monitor_rect.width, actual_monitor_rect.size.width);
  EXPECT_EQ(monitor_rect.height, actual_monitor_rect.size.height);
}

class FontUpdateTestableWindowManager : public WindowManager {
 public:
  FontUpdateTestableWindowManager(GtkWindowInterface *main_window,
                                  GtkWindowInterface *infolist_window,
                                  GtkWrapperInterface *gtk)
      : WindowManager(main_window, infolist_window, gtk) {}
  virtual ~FontUpdateTestableWindowManager() {}

  MOCK_METHOD1(ShouldShowCandidateWindow,
               bool(const commands::RendererCommand &command));
  MOCK_METHOD1(ShouldShowInfolistWindow,
               bool(const commands::RendererCommand &command));
  MOCK_METHOD1(UpdateCandidateWindow,
               Rect(const commands::RendererCommand &command));
  MOCK_METHOD2(UpdateInfolistWindow,
               void(const commands::RendererCommand &command,
                    const Rect &candidate_window_rect));
};

TEST(WindowManagerTest, FontReloadTest) {
  {
    GtkWindowMock *candidate_window_mock = new GtkWindowMock();
    GtkWindowMock *infolist_window_mock = new GtkWindowMock();
    GtkWrapperMock *gtk_mock = new GtkWrapperMock();

    const Rect kDummyRect(0, 0, 0, 0);
    const char kDummyFontDescription[] = "Foo,Bar,Baz";

    FontUpdateTestableWindowManager window_manager(
        candidate_window_mock, infolist_window_mock, gtk_mock);
    EXPECT_CALL(window_manager, ShouldShowCandidateWindow(_))
        .WillOnce(Return(true));
    EXPECT_CALL(*candidate_window_mock,
                ReloadFontConfig(StrEq(kDummyFontDescription)));
    EXPECT_CALL(*infolist_window_mock,
                ReloadFontConfig(StrEq(kDummyFontDescription)));
    EXPECT_CALL(window_manager, UpdateCandidateWindow(_))
        .WillOnce(Return(kDummyRect));

    EXPECT_CALL(window_manager, UpdateInfolistWindow(_, _));

    commands::RendererCommand command;

    commands::RendererCommand::ApplicationInfo *app_info =
        command.mutable_application_info();
    app_info->set_pango_font_description(kDummyFontDescription);

    window_manager.UpdateLayout(command);
  }
  {
    SCOPED_TRACE("Does not call reload function when the custom font setting "
                 "is not available");
    GtkWindowMock *candidate_window_mock = new GtkWindowMock();
    GtkWindowMock *infolist_window_mock = new GtkWindowMock();
    GtkWrapperMock *gtk_mock = new GtkWrapperMock();

    const Rect kDummyRect(0, 0, 0, 0);

    FontUpdateTestableWindowManager window_manager(
        candidate_window_mock, infolist_window_mock, gtk_mock);
    EXPECT_CALL(window_manager, ShouldShowCandidateWindow(_))
        .WillOnce(Return(true));
    EXPECT_CALL(*candidate_window_mock, ReloadFontConfig(_)).Times(0);
    EXPECT_CALL(*infolist_window_mock, ReloadFontConfig(_)).Times(0);
    EXPECT_CALL(window_manager, UpdateCandidateWindow(_))
        .WillOnce(Return(kDummyRect));

    EXPECT_CALL(window_manager, UpdateInfolistWindow(_, _));

    commands::RendererCommand command;
    command.mutable_application_info();

    window_manager.UpdateLayout(command);
  }
  {
    SCOPED_TRACE("Does not call reload function if previously loaded font"
                 "description is same as requested one.");
    GtkWindowMock *candidate_window_mock = new GtkWindowMock();
    GtkWindowMock *infolist_window_mock = new GtkWindowMock();
    GtkWrapperMock *gtk_mock = new GtkWrapperMock();

    const Rect kDummyRect(0, 0, 0, 0);
    const char kDummyFontDescription[] = "Foo,Bar,Baz";

    FontUpdateTestableWindowManager window_manager(
        candidate_window_mock, infolist_window_mock, gtk_mock);
    EXPECT_CALL(window_manager, ShouldShowCandidateWindow(_))
        .Times(2)
        .WillRepeatedly(Return(true));
    EXPECT_CALL(*candidate_window_mock,
                ReloadFontConfig(StrEq(kDummyFontDescription)));
    EXPECT_CALL(*infolist_window_mock,
                ReloadFontConfig(StrEq(kDummyFontDescription)));
    EXPECT_CALL(window_manager, UpdateCandidateWindow(_))
        .Times(2)
        .WillRepeatedly(Return(kDummyRect));

    EXPECT_CALL(window_manager, UpdateInfolistWindow(_, _)).Times(2);

    commands::RendererCommand command;

    commands::RendererCommand::ApplicationInfo *app_info =
        command.mutable_application_info();
    app_info->set_pango_font_description(kDummyFontDescription);

    window_manager.UpdateLayout(command);

    // Call again with same font description.
    window_manager.UpdateLayout(command);
  }
  {
    SCOPED_TRACE("Call reload function if previously loaded font description"
                 " is different from requested one.");
    GtkWindowMock *candidate_window_mock = new GtkWindowMock();
    GtkWindowMock *infolist_window_mock = new GtkWindowMock();
    GtkWrapperMock *gtk_mock = new GtkWrapperMock();

    const Rect kDummyRect(0, 0, 0, 0);
    const char kDummyFontDescription[] = "Foo,Bar,Baz";
    const char kDummyFontDescription2[] = "Foo,Bar";

    FontUpdateTestableWindowManager window_manager(
        candidate_window_mock, infolist_window_mock, gtk_mock);
    EXPECT_CALL(window_manager, ShouldShowCandidateWindow(_))
        .Times(2)
        .WillRepeatedly(Return(true));
    EXPECT_CALL(*candidate_window_mock,
                ReloadFontConfig(StrEq(kDummyFontDescription)));
    EXPECT_CALL(*infolist_window_mock,
                ReloadFontConfig(StrEq(kDummyFontDescription)));
    EXPECT_CALL(*candidate_window_mock,
                ReloadFontConfig(StrEq(kDummyFontDescription2)));
    EXPECT_CALL(*infolist_window_mock,
                ReloadFontConfig(StrEq(kDummyFontDescription2)));
    EXPECT_CALL(window_manager, UpdateCandidateWindow(_))
        .Times(2)
        .WillRepeatedly(Return(kDummyRect));

    EXPECT_CALL(window_manager, UpdateInfolistWindow(_, _)).Times(2);

    commands::RendererCommand command;

    commands::RendererCommand::ApplicationInfo *app_info =
        command.mutable_application_info();
    app_info->set_pango_font_description(kDummyFontDescription);

    window_manager.UpdateLayout(command);

    app_info->set_pango_font_description(kDummyFontDescription2);
    // Call again with different font description.
    window_manager.UpdateLayout(command);
  }
}
}  // namespace gtk
}  // namespace renderer
}  // namespace mozc
