// Copyright 2014 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 "athena/wm/window_manager_impl.h"

#include <algorithm>

#include "athena/screen/public/screen_manager.h"
#include "athena/util/container_priorities.h"
#include "athena/wm/public/window_manager_observer.h"
#include "athena/wm/split_view_controller.h"
#include "athena/wm/title_drag_controller.h"
#include "athena/wm/window_list_provider_impl.h"
#include "athena/wm/window_overview_mode.h"
#include "base/bind.h"
#include "base/logging.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/compositor/closure_animation_observer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"
#include "ui/wm/core/shadow_controller.h"
#include "ui/wm/core/transient_window_manager.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/core/wm_state.h"
#include "ui/wm/public/activation_client.h"
#include "ui/wm/public/window_types.h"

namespace athena {
namespace {
class WindowManagerImpl* instance = nullptr;

void SetWindowState(aura::Window* window,
                    const gfx::Rect& bounds,
                    const gfx::Transform& transform) {
  window->SetBounds(bounds);
  window->SetTransform(transform);
}

// Tests whether the given window can be maximized
bool CanWindowMaximize(const aura::Window* const window) {
  const aura::WindowDelegate* delegate = window->delegate();
  const bool no_max_size =
      !delegate || delegate->GetMaximumSize().IsEmpty();
  return no_max_size &&
         window->GetProperty(aura::client::kCanMaximizeKey) &&
         window->GetProperty(aura::client::kCanResizeKey);
}

}  // namespace

class AthenaContainerLayoutManager : public aura::LayoutManager {
 public:
  AthenaContainerLayoutManager();
  ~AthenaContainerLayoutManager() override;

 private:
  // aura::LayoutManager:
  void OnWindowResized() override;
  void OnWindowAddedToLayout(aura::Window* child) override;
  void OnWillRemoveWindowFromLayout(aura::Window* child) override;
  void OnWindowRemovedFromLayout(aura::Window* child) override;
  void OnChildWindowVisibilityChanged(aura::Window* child,
                                      bool visible) override;
  void SetChildBounds(aura::Window* child,
                      const gfx::Rect& requested_bounds) override;

  DISALLOW_COPY_AND_ASSIGN(AthenaContainerLayoutManager);
};

AthenaContainerLayoutManager::AthenaContainerLayoutManager() {
}

AthenaContainerLayoutManager::~AthenaContainerLayoutManager() {
}

void AthenaContainerLayoutManager::OnWindowResized() {
  // Resize all the existing windows.
  const aura::Window::Windows& list =
      instance->window_list_provider_->GetWindowList();
  const gfx::Size work_area =
      gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area().size();
  bool is_splitview = instance->split_view_controller_->IsSplitViewModeActive();
  gfx::Size split_size;
  if (is_splitview) {
    CHECK(instance->split_view_controller_->left_window());
    split_size =
        instance->split_view_controller_->left_window()->bounds().size();
  }

  for (aura::Window::Windows::const_iterator iter = list.begin();
       iter != list.end();
       ++iter) {
    aura::Window* window = *iter;
    if (is_splitview) {
      if (window == instance->split_view_controller_->left_window())
        window->SetBounds(gfx::Rect(split_size));
      else if (window == instance->split_view_controller_->right_window()) {
        window->SetBounds(
            gfx::Rect(gfx::Point(split_size.width(), 0), split_size));
      } else if (CanWindowMaximize(window))
          window->SetBounds(gfx::Rect(work_area));
    } else if (CanWindowMaximize(window)) {
      window->SetBounds(gfx::Rect(work_area));
    }
  }
}

void AthenaContainerLayoutManager::OnWindowAddedToLayout(aura::Window* child) {
  // TODO(oshima): Split view modes needs to take the transient window into
  // account.
  if (wm::GetTransientParent(child)) {
    wm::TransientWindowManager::Get(child)
        ->set_parent_controls_visibility(true);
  }
}

void AthenaContainerLayoutManager::OnWillRemoveWindowFromLayout(
    aura::Window* child) {
}

void AthenaContainerLayoutManager::OnWindowRemovedFromLayout(
    aura::Window* child) {
}

void AthenaContainerLayoutManager::OnChildWindowVisibilityChanged(
    aura::Window* child,
    bool visible) {
  if (visible && CanWindowMaximize(child)) {
    // Make sure we're resizing a window that actually exists in the window list
    // to avoid resizing the divider in the split mode.
    if(instance->window_list_provider_->IsWindowInList(child)) {
       child->SetBounds(
          gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area());
    }
  }
}

void AthenaContainerLayoutManager::SetChildBounds(
    aura::Window* child,
    const gfx::Rect& requested_bounds) {
  if (!requested_bounds.IsEmpty())
    SetChildBoundsDirect(child, requested_bounds);
}

WindowManagerImpl::WindowManagerImpl() {
  ScreenManager::ContainerParams params("DefaultContainer", CP_DEFAULT);
  params.can_activate_children = true;
  params.default_parent = true;
  params.modal_container_priority = CP_SYSTEM_MODAL;
  container_.reset(ScreenManager::Get()->CreateContainer(params));
  container_->SetLayoutManager(new AthenaContainerLayoutManager);
  container_->AddObserver(this);
  window_list_provider_.reset(new WindowListProviderImpl(container_.get()));
  window_list_provider_->AddObserver(this);
  split_view_controller_.reset(
      new SplitViewController(container_.get(), window_list_provider_.get()));
  AddObserver(split_view_controller_.get());
  title_drag_controller_.reset(new TitleDragController(container_.get(), this));
  wm_state_.reset(new wm::WMState());
  aura::client::ActivationClient* activation_client =
      aura::client::GetActivationClient(container_->GetRootWindow());
  DCHECK(container_->GetRootWindow());
  DCHECK(activation_client);
  shadow_controller_.reset(new wm::ShadowController(activation_client));
  instance = this;
  InstallAccelerators();
}

WindowManagerImpl::~WindowManagerImpl() {
  window_list_provider_->RemoveObserver(this);
  overview_.reset();
  RemoveObserver(split_view_controller_.get());
  split_view_controller_.reset();
  window_list_provider_.reset();
  if (container_)
    container_->RemoveObserver(this);

  // |title_drag_controller_| needs to be reset before |container_|.
  title_drag_controller_.reset();
  container_.reset();
  instance = nullptr;
}

void WindowManagerImpl::ToggleSplitView() {
  if (IsOverviewModeActive())
    return;

  if (split_view_controller_->IsSplitViewModeActive()) {
    split_view_controller_->DeactivateSplitMode();
    FOR_EACH_OBSERVER(WindowManagerObserver, observers_, OnSplitViewModeExit());
    // Relayout so that windows are maximzied.
    container_->layout_manager()->OnWindowResized();
  } else if (split_view_controller_->CanActivateSplitViewMode()) {
    FOR_EACH_OBSERVER(WindowManagerObserver,
                      observers_,
                      OnSplitViewModeEnter());
    split_view_controller_->ActivateSplitMode(nullptr, nullptr, nullptr);
  }
}

void WindowManagerImpl::EnterOverview() {
  if (IsOverviewModeActive())
    return;

  FOR_EACH_OBSERVER(WindowManagerObserver, observers_, OnOverviewModeEnter());

  // Note: The window_list_provider_ resembles the exact window list of the
  // container, so no re-stacking is required before showing the OverviewMode.
  overview_ = WindowOverviewMode::Create(
      container_.get(), window_list_provider_.get(),
      split_view_controller_.get(), this);
  AcceleratorManager::Get()->RegisterAccelerator(kEscAcceleratorData, this);
}

void WindowManagerImpl::ExitOverview() {
  if (!IsOverviewModeActive())
    return;

  ExitOverviewNoActivate();

  // Activate the window which was active prior to entering overview.
  const aura::Window::Windows windows = window_list_provider_->GetWindowList();
  if (!windows.empty()) {
    aura::Window* window_to_activate = windows.back();

    // Show the window in case the exit overview animation has finished and
    // |window| was hidden.
    window_to_activate->Show();
    wm::ActivateWindow(window_to_activate);
  }
}

bool WindowManagerImpl::IsOverviewModeActive() {
  return overview_;
}

void WindowManagerImpl::ExitOverviewNoActivate() {
  if (!IsOverviewModeActive())
    return;

  overview_.reset();
  FOR_EACH_OBSERVER(WindowManagerObserver, observers_, OnOverviewModeExit());
  AcceleratorManager::Get()->UnregisterAccelerator(kEscAcceleratorData, this);
}

void WindowManagerImpl::InstallAccelerators() {
  const AcceleratorData accelerator_data[] = {
      {TRIGGER_ON_PRESS,
       ui::VKEY_F6,
       ui::EF_NONE,
       CMD_TOGGLE_OVERVIEW,
       AF_NONE},
      {TRIGGER_ON_PRESS,
       ui::VKEY_F6,
       ui::EF_CONTROL_DOWN,
       CMD_TOGGLE_SPLIT_VIEW,
       AF_NONE},
      // Debug
      {TRIGGER_ON_PRESS,
       ui::VKEY_6,
       ui::EF_NONE,
       CMD_TOGGLE_OVERVIEW,
       AF_NONE | AF_DEBUG},
  };
  AcceleratorManager::Get()->RegisterAccelerators(
      accelerator_data, arraysize(accelerator_data), this);
}

void WindowManagerImpl::AddObserver(WindowManagerObserver* observer) {
  observers_.AddObserver(observer);
}

void WindowManagerImpl::RemoveObserver(WindowManagerObserver* observer) {
  observers_.RemoveObserver(observer);
}

void WindowManagerImpl::ToggleSplitViewForTest() {
  ToggleSplitView();
}

WindowListProvider* WindowManagerImpl::GetWindowListProvider() {
  return window_list_provider_.get();
}

void WindowManagerImpl::OnSelectWindow(aura::Window* window) {
  ExitOverviewNoActivate();

  // Show the window in case the exit overview animation has finished and
  // |window| was hidden.
  window->Show();

  wm::ActivateWindow(window);

  if (split_view_controller_->IsSplitViewModeActive()) {
    split_view_controller_->DeactivateSplitMode();
    FOR_EACH_OBSERVER(WindowManagerObserver, observers_, OnSplitViewModeExit());
  }
  // If |window| does not have the size of the work-area, then make sure it is
  // resized.
  const gfx::Size work_area =
      gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area().size();

  // Resize to the screen bounds only if the window is maximize-able, and
  // is not already maximized
  if (window->GetTargetBounds().size() != work_area &&
      CanWindowMaximize(window)) {
    const gfx::Rect& window_bounds = window->bounds();
    const gfx::Rect desired_bounds(work_area);
    gfx::Transform transform;
    transform.Translate(desired_bounds.x() - window_bounds.x(),
                        desired_bounds.y() - window_bounds.y());
    transform.Scale(desired_bounds.width() / window_bounds.width(),
                    desired_bounds.height() / window_bounds.height());
    ui::ScopedLayerAnimationSettings settings(window->layer()->GetAnimator());
    settings.SetPreemptionStrategy(
        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
    settings.AddObserver(
        new ui::ClosureAnimationObserver(base::Bind(&SetWindowState,
                                                    base::Unretained(window),
                                                    desired_bounds,
                                                    gfx::Transform())));
    window->SetTransform(transform);
  }
}

void WindowManagerImpl::OnSelectSplitViewWindow(aura::Window* left,
                                                aura::Window* right,
                                                aura::Window* to_activate) {
  ExitOverviewNoActivate();
  FOR_EACH_OBSERVER(WindowManagerObserver, observers_, OnSplitViewModeEnter());
  split_view_controller_->ActivateSplitMode(left, right, to_activate);
}

void WindowManagerImpl::OnWindowStackingChangedInList() {
}

void WindowManagerImpl::OnWindowAddedToList(aura::Window* child) {
  if (instance->split_view_controller_->IsSplitViewModeActive() &&
      !instance->IsOverviewModeActive()) {
    instance->split_view_controller_->ReplaceWindow(
        instance->split_view_controller_->left_window(), child);
  } else {
    gfx::Size size =
        gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().work_area().size();
    child->SetBounds(gfx::Rect(size));
  }

  if (instance->IsOverviewModeActive()) {
    // TODO(pkotwicz|oshima). Creating a new window should only exit overview
    // mode if the new window is activated. crbug.com/415266
    instance->OnSelectWindow(child);
  }
}

void WindowManagerImpl::OnWindowRemovedFromList(aura::Window* removed_window,
                                                int index) {
  aura::Window::Windows windows = window_list_provider_->GetWindowList();
  DCHECK(!window_list_provider_->IsWindowInList(removed_window));
  DCHECK_LE(index, static_cast<int>(windows.size()));

  // Splitted windows are handled in SplitViewController.
  if (split_view_controller_->IsSplitViewModeActive())
    return;

  // In overview mode, windows are handled in WindowOverviewMode class.
  if (!IsOverviewModeActive())
    return;

  // Shows the next window if the removed window was top.
  if (!windows.empty() && index == static_cast<int>(windows.size())) {
    aura::Window* next_window = windows.back();
    next_window->Show();

   // Don't activate the window here, since it should be done in focus manager.
  }
}

void WindowManagerImpl::OnWindowDestroying(aura::Window* window) {
  if (window == container_)
    container_.reset();
}

bool WindowManagerImpl::IsCommandEnabled(int command_id) const {
  return true;
}

bool WindowManagerImpl::OnAcceleratorFired(int command_id,
                                           const ui::Accelerator& accelerator) {
  switch (command_id) {
    case CMD_EXIT_OVERVIEW:
      ExitOverview();
      break;
    case CMD_TOGGLE_OVERVIEW:
      if (IsOverviewModeActive())
        ExitOverview();
      else
        EnterOverview();
      break;
    case CMD_TOGGLE_SPLIT_VIEW:
      ToggleSplitView();
      break;
  }
  return true;
}

aura::Window* WindowManagerImpl::GetWindowBehind(aura::Window* window) {
  const aura::Window::Windows& windows = window_list_provider_->GetWindowList();
  aura::Window::Windows::const_reverse_iterator iter =
      std::find(windows.rbegin(), windows.rend(), window);
  CHECK(iter != windows.rend());
  ++iter;
  aura::Window* behind = nullptr;
  if (iter != windows.rend())
    behind = *iter++;

  if (split_view_controller_->IsSplitViewModeActive()) {
    aura::Window* left = split_view_controller_->left_window();
    aura::Window* right = split_view_controller_->right_window();
    CHECK(window == left || window == right);
    if (behind == left || behind == right)
      behind = (iter == windows.rend()) ? nullptr : *iter;
  }

  return behind;
}

void WindowManagerImpl::OnTitleDragStarted(aura::Window* window) {
  aura::Window* next_window = GetWindowBehind(window);
  if (!next_window)
    return;
  // Make sure |window| is active.
  wm::ActivateWindow(window);

  // Make sure |next_window| is visibile.
  next_window->Show();

  // Position |next_window| correctly (left aligned if it's larger than
  // |window|, and center aligned otherwise).
  int dx = window->bounds().x() - next_window->bounds().x();
  if (next_window->bounds().width() < window->bounds().width())
    dx -= (next_window->bounds().width() - window->bounds().width()) / 2;

  if (dx) {
    gfx::Transform transform;
    transform.Translate(dx, 0);
    next_window->SetTransform(transform);
  }
}

void WindowManagerImpl::OnTitleDragCompleted(aura::Window* window) {
  aura::Window* next_window = GetWindowBehind(window);
  if (!next_window)
    return;
  if (split_view_controller_->IsSplitViewModeActive()) {
    split_view_controller_->ReplaceWindow(window, next_window);
  } else {
    ui::ScopedLayerAnimationSettings
        settings(next_window->layer()->GetAnimator());
    settings.AddObserver(new ui::ClosureAnimationObserver(
        base::Bind(&SetWindowState,
                   base::Unretained(next_window),
                   window->bounds(),
                   gfx::Transform())));

    gfx::Transform transform;
    transform.Scale(window->bounds().width() / next_window->bounds().width(),
                    window->bounds().height() / next_window->bounds().height());
    transform.Translate(window->bounds().x() - next_window->bounds().x(), 0);
    next_window->SetTransform(transform);

    wm::ActivateWindow(next_window);
  }
  window->Hide();
}

void WindowManagerImpl::OnTitleDragCanceled(aura::Window* window) {
  aura::Window* next_window = GetWindowBehind(window);
  if (!next_window)
    return;
  next_window->SetTransform(gfx::Transform());
  next_window->Hide();
}

// static
WindowManager* WindowManager::Create() {
  DCHECK(!instance);
  new WindowManagerImpl;
  DCHECK(instance);
  return instance;
}

// static
void WindowManager::Shutdown() {
  DCHECK(instance);
  delete instance;
  DCHECK(!instance);
}

// static
WindowManager* WindowManager::Get() {
  DCHECK(instance);
  return instance;
}

}  // namespace athena
