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

#include "ash/accelerators/accelerator_controller.h"
#include "ash/shell.h"
#include "ash/wm/window_state.h"
#include "ui/aura/root_window.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/accelerators/accelerator_manager.h"
#include "ui/events/event.h"
#include "ui/views/corewm/window_util.h"

namespace ash {
namespace {

const int kModifierFlagMask = (ui::EF_SHIFT_DOWN |
                               ui::EF_CONTROL_DOWN |
                               ui::EF_ALT_DOWN);

// Returns true if |key_code| is a key usually handled directly by the shell.
bool IsSystemKey(ui::KeyboardCode key_code) {
#if defined(OS_CHROMEOS)
  switch (key_code) {
    case ui::VKEY_MEDIA_LAUNCH_APP2:  // Fullscreen button.
    case ui::VKEY_MEDIA_LAUNCH_APP1:  // Overview button.
    case ui::VKEY_BRIGHTNESS_DOWN:
    case ui::VKEY_BRIGHTNESS_UP:
    case ui::VKEY_KBD_BRIGHTNESS_DOWN:
    case ui::VKEY_KBD_BRIGHTNESS_UP:
    case ui::VKEY_VOLUME_MUTE:
    case ui::VKEY_VOLUME_DOWN:
    case ui::VKEY_VOLUME_UP:
      return true;
    default:
      return false;
  }
#endif  // defined(OS_CHROMEOS)
  return false;
}

// Returns true if the window should be allowed a chance to handle system keys.
// Uses the top level window so if the target is a web contents window the
// containing parent window will be checked for the property.
bool CanConsumeSystemKeys(aura::Window* target) {
  if (!target)  // Can be NULL in tests.
    return false;
  aura::Window* top_level = views::corewm::GetToplevelWindow(target);
  return top_level && wm::GetWindowState(top_level)->can_consume_system_keys();
}

// Returns true if the |accelerator| should be processed now, inside Ash's env
// event filter.
bool ShouldProcessAcceleratorsNow(const ui::Accelerator& accelerator,
                                  aura::Window* target) {
  if (!target)
    return true;

  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  if (std::find(root_windows.begin(), root_windows.end(), target) !=
      root_windows.end())
    return true;

  // A full screen window should be able to handle all key events including the
  // reserved ones.
  if (wm::GetWindowState(target)->IsFullscreen()) {
    // TODO(yusukes): On Chrome OS, only browser and flash windows can be full
    // screen. Launching an app in "open full-screen" mode is not supported yet.
    // That makes the IsWindowFullscreen() check above almost meaningless
    // because a browser and flash window do handle Ash accelerators anyway
    // before they're passed to a page or flash content.
    return false;
  }

  if (Shell::GetInstance()->GetAppListTargetVisibility())
    return true;

  // Unless |target| is in the full screen state, handle reserved accelerators
  // such as Alt+Tab now.
  return Shell::GetInstance()->accelerator_controller()->IsReservedAccelerator(
      accelerator);
}

}  // namespace

namespace internal {

////////////////////////////////////////////////////////////////////////////////
// AcceleratorFilter, public:

AcceleratorFilter::AcceleratorFilter() {
}

AcceleratorFilter::~AcceleratorFilter() {
}

////////////////////////////////////////////////////////////////////////////////
// AcceleratorFilter, EventFilter implementation:

void AcceleratorFilter::OnKeyEvent(ui::KeyEvent* event) {
  const ui::EventType type = event->type();
  if (type != ui::ET_KEY_PRESSED && type != ui::ET_KEY_RELEASED)
    return;
  if (event->is_char())
    return;

  ui::Accelerator accelerator(event->key_code(),
                              event->flags() & kModifierFlagMask);
  accelerator.set_type(type);

  // Fill out context object so AcceleratorController will know what
  // was the previous accelerator or if the current accelerator is repeated.
  AcceleratorController* accelerator_controller =
      Shell::GetInstance()->accelerator_controller();
  accelerator_controller->context()->UpdateContext(accelerator);

  aura::Window* target = static_cast<aura::Window*>(event->target());
  // Handle special hardware keys like brightness and volume. However, some
  // windows can override this behavior (e.g. Chrome v1 apps by default and
  // Chrome v2 apps with permission) by setting a window property.
  if (IsSystemKey(event->key_code()) && !CanConsumeSystemKeys(target)) {
    accelerator_controller->Process(accelerator);
    // These keys are always consumed regardless of whether they trigger an
    // accelerator to prevent windows from seeing unexpected key up events.
    event->StopPropagation();
    return;
  }
  if (!ShouldProcessAcceleratorsNow(accelerator, target))
    return;
  if (accelerator_controller->Process(accelerator))
    event->StopPropagation();
}

}  // namespace internal
}  // namespace ash
