// 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_focus_rules.h"

#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/window_util.h"
#include "ui/aura/window.h"

namespace ash {
namespace wm {
namespace {

// These are the list of container ids of containers which may contain windows
// that need to be activated in the order that they should be activated.
const int kWindowContainerIds[] = {
    internal::kShellWindowId_LockSystemModalContainer,
    internal::kShellWindowId_SettingBubbleContainer,
    internal::kShellWindowId_LockScreenContainer,
    internal::kShellWindowId_SystemModalContainer,
    internal::kShellWindowId_AlwaysOnTopContainer,
    internal::kShellWindowId_AppListContainer,
    internal::kShellWindowId_DefaultContainer,

    // Docked, panel, launcher and status are intentionally checked after other
    // containers even though these layers are higher. The user expects their
    // windows to be focused before these elements.
    internal::kShellWindowId_DockedContainer,
    internal::kShellWindowId_PanelContainer,
    internal::kShellWindowId_ShelfContainer,
    internal::kShellWindowId_StatusContainer,
};

bool BelongsToContainerWithEqualOrGreaterId(const aura::Window* window,
                                            int container_id) {
  for (; window; window = window->parent()) {
    if (window->id() >= container_id)
      return true;
  }
  return false;
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// AshFocusRules, public:

AshFocusRules::AshFocusRules() {
}

AshFocusRules::~AshFocusRules() {
}

////////////////////////////////////////////////////////////////////////////////
// AshFocusRules, views::corewm::FocusRules:

bool AshFocusRules::SupportsChildActivation(aura::Window* window) const {
  if (window->id() == internal::kShellWindowId_DefaultContainer)
    return true;

  for (size_t i = 0; i < arraysize(kWindowContainerIds); i++) {
    if (window->id() == kWindowContainerIds[i])
      return true;
  }
  return false;
}

bool AshFocusRules::IsWindowConsideredVisibleForActivation(
    aura::Window* window) const {
  if (BaseFocusRules::IsWindowConsideredVisibleForActivation(window))
    return true;

  // Minimized windows are hidden in their minimized state, but they can always
  // be activated.
  if (wm::IsWindowMinimized(window))
    return true;

  return window->TargetVisibility() && (window->parent()->id() ==
      internal::kShellWindowId_DefaultContainer || window->parent()->id() ==
      internal::kShellWindowId_LockScreenContainer);
}

bool AshFocusRules::CanActivateWindow(aura::Window* window) const {
  // Clearing activation is always permissible.
  if (!window)
    return true;

  if (!BaseFocusRules::CanActivateWindow(window))
    return false;

  if (Shell::GetInstance()->IsSystemModalWindowOpen()) {
    return BelongsToContainerWithEqualOrGreaterId(
          window, internal::kShellWindowId_SystemModalContainer);
  }

  return true;
}

aura::Window* AshFocusRules::GetNextActivatableWindow(
    aura::Window* ignore) const {
  DCHECK(ignore);

  int starting_container_index = 0;
  // If the container of the window losing focus is in the list, start from that
  // container.
  aura::RootWindow* root = ignore->GetRootWindow();
  if (!root)
    root = Shell::GetActiveRootWindow();
  int container_count = static_cast<int>(arraysize(kWindowContainerIds));
  for (int i = 0; ignore && i < container_count; i++) {
    aura::Window* container = Shell::GetContainer(root, kWindowContainerIds[i]);
    if (container && container->Contains(ignore)) {
      starting_container_index = i;
      break;
    }
  }

  // Look for windows to focus in |ignore|'s container. If none are found, we
  // look in all the containers in front of |ignore|'s container, then all
  // behind.
  aura::Window* window = NULL;
  for (int i = starting_container_index; !window && i < container_count; i++)
    window = GetTopmostWindowToActivateForContainerIndex(i, ignore);
  if (!window && starting_container_index > 0) {
    for (int i = starting_container_index - 1; !window && i >= 0; i--)
      window = GetTopmostWindowToActivateForContainerIndex(i, ignore);
  }
  return window;
}

////////////////////////////////////////////////////////////////////////////////
// AshFocusRules, private:

aura::Window* AshFocusRules::GetTopmostWindowToActivateForContainerIndex(
    int index,
    aura::Window* ignore) const {
  aura::Window* window = NULL;
  aura::RootWindow* root = ignore ? ignore->GetRootWindow() : NULL;
  aura::Window::Windows containers = Shell::GetContainersFromAllRootWindows(
      kWindowContainerIds[index], root);
  for (aura::Window::Windows::const_iterator iter = containers.begin();
        iter != containers.end() && !window; ++iter) {
    window = GetTopmostWindowToActivateInContainer((*iter), ignore);
  }
  return window;
}

aura::Window* AshFocusRules::GetTopmostWindowToActivateInContainer(
    aura::Window* container,
    aura::Window* ignore) const {
  for (aura::Window::Windows::const_reverse_iterator i =
           container->children().rbegin();
       i != container->children().rend();
       ++i) {
    if (*i != ignore && CanActivateWindow(*i) && !wm::IsWindowMinimized(*i))
      return *i;
  }
  return NULL;
}

}  // namespace wm
}  // namespace ash
