// 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 "ash/wm/ash_activation_controller.h"

#include "ash/launcher/launcher.h"
#include "ash/root_window_controller.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/wm/activation_controller.h"
#include "ash/wm/property_util.h"
#include "ash/wm/window_util.h"
#include "ash/wm/workspace_controller.h"
#include "ui/views/corewm/window_modality_controller.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace internal {

////////////////////////////////////////////////////////////////////////////////
// AshActivationController, public:

AshActivationController::AshActivationController() {
}

AshActivationController::~AshActivationController() {
}

////////////////////////////////////////////////////////////////////////////////
// AshActivationController, ActivationControllerDelegate implementation:

aura::Window* AshActivationController::WillActivateWindow(
    aura::Window* window) {
  aura::Window* window_modal_transient =
      views::corewm::GetModalTransient(window);
  if (window_modal_transient)
    return window_modal_transient;

  // Fallback to launcher
  if (!window)
    window = PrepareToActivateLauncher();

  // Restore minimized window. This needs to be done before CanReceiveEvents()
  // is called as that function checks window visibility.
  if (window && wm::IsWindowMinimized(window))
    window->Show();

  // If the screen is locked, just bring the window to top so that
  // it will be activated when the lock window is destroyed.
  // TODO(beng): Call EventClient directly here, rather than conflating with
  //             window visibility.
  if (window && !window->CanReceiveEvents())
    return NULL;

  // TODO(beng): could probably move to being a ActivationChangeObserver on
  //             Shell.
  if (window) {
    DCHECK(window->GetRootWindow());
    Shell::GetInstance()->set_active_root_window(window->GetRootWindow());
  }
  return window;
}

aura::Window* AshActivationController::WillFocusWindow(
    aura::Window* window) {
  aura::Window* window_modal_transient =
      views::corewm::GetModalTransient(window);
  if (window_modal_transient)
    return window_modal_transient;
  return window;
}

aura::Window* AshActivationController::PrepareToActivateLauncher() {
  // If workspace controller is not available, then it means that the root
  // window is being destroyed. We can't activate any window then.
  if (!GetRootWindowController(
      Shell::GetActiveRootWindow())->workspace_controller()) {
    return NULL;
  }
  // Fallback to a launcher only when Spoken feedback is enabled.
  if (!Shell::GetInstance()->delegate()->IsSpokenFeedbackEnabled())
    return NULL;
  ShelfWidget* shelf = GetRootWindowController(
      Shell::GetActiveRootWindow())->shelf();
  // Launcher's window may be already destroyed in shutting down process.
  if (!shelf)
    return NULL;
  // Notify launcher to allow activation via CanActivate().
  shelf->WillActivateAsFallback();
  return shelf->GetNativeWindow();
}

}  // namespace internal
}  // namespace ash
