// 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 <algorithm>
#include <vector>

#include "ash/common/ash_switches.h"
#include "ash/common/material_design/material_design_controller.h"
#include "ash/common/shelf/shelf.h"
#include "ash/common/shelf/shelf_widget.h"
#include "ash/display/display_manager.h"
#include "ash/shell.h"
#include "ash/test/ash_md_test_base.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_util.h"
#include "base/command_line.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/compositor/layer.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/shadow.h"
#include "ui/wm/core/shadow_controller.h"
#include "ui/wm/core/shadow_types.h"
#include "ui/wm/public/activation_client.h"

namespace ash {

using DIPTest = test::AshMDTestBase;

INSTANTIATE_TEST_CASE_P(
    /* prefix intentionally left blank due to only one parameterization */,
    DIPTest,
    testing::Values(MaterialDesignController::NON_MATERIAL,
                    MaterialDesignController::MATERIAL_NORMAL,
                    MaterialDesignController::MATERIAL_EXPERIMENTAL));

// Test if the WM sets correct work area under different density.
// TODO(msw): Broken on Windows. http://crbug.com/584038
#if defined(OS_CHROMEOS)
TEST_P(DIPTest, WorkArea) {
  const int height_offset = GetMdMaximizedWindowHeightOffset();
  UpdateDisplay("1000x900*1.0f");

  aura::Window* root = Shell::GetPrimaryRootWindow();
  const display::Display display =
      display::Screen::GetScreen()->GetDisplayNearestWindow(root);

  EXPECT_EQ("0,0 1000x900", display.bounds().ToString());
  gfx::Rect work_area = display.work_area();
  EXPECT_EQ(gfx::Rect(0, 0, 1000, 853 + height_offset).ToString(),
            work_area.ToString());
  EXPECT_EQ(gfx::Insets(0, 0, 47 - height_offset, 0).ToString(),
            display.bounds().InsetsFrom(work_area).ToString());

  UpdateDisplay("2000x1800*2.0f");
  display::Screen* screen = display::Screen::GetScreen();

  const display::Display display_2x = screen->GetDisplayNearestWindow(root);
  const DisplayInfo display_info_2x =
      Shell::GetInstance()->display_manager()->GetDisplayInfo(display_2x.id());

  // The |bounds_in_pixel()| should report bounds in pixel coordinate.
  EXPECT_EQ("1,1 2000x1800", display_info_2x.bounds_in_native().ToString());

  // Aura and views coordinates are in DIP, so they their bounds do not change.
  EXPECT_EQ("0,0 1000x900", display_2x.bounds().ToString());
  work_area = display_2x.work_area();
  EXPECT_EQ(gfx::Rect(0, 0, 1000, 853 + height_offset).ToString(),
            work_area.ToString());
  EXPECT_EQ(gfx::Insets(0, 0, 47 - height_offset, 0).ToString(),
            display_2x.bounds().InsetsFrom(work_area).ToString());

  // Sanity check if the workarea's inset hight is same as
  // the shelf's height.
  Shelf* shelf = Shelf::ForPrimaryDisplay();
  EXPECT_EQ(display_2x.bounds().InsetsFrom(work_area).height(),
            shelf->shelf_widget()->GetNativeView()->layer()->bounds().height());
}
#endif  // defined(OS_CHROMEOS)

}  // namespace ash
