// Copyright (c) 2009 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 "ui/base/win/mouse_wheel_util.h"

#include <windowsx.h>

#include "base/auto_reset.h"
#include "ui/base/view_prop.h"
#include "ui/gfx/win/hwnd_util.h"

namespace ui {

// Property used to indicate the HWND supports having mouse wheel messages
// rerouted to it.
static const char* const kHWNDSupportMouseWheelRerouting =
    "__HWND_MW_REROUTE_OK";

static bool WindowSupportsRerouteMouseWheel(HWND window) {
  while (GetWindowLong(window, GWL_STYLE) & WS_CHILD) {
    if (!IsWindow(window))
      break;

    if (ViewProp::GetValue(window, kHWNDSupportMouseWheelRerouting) != NULL) {
      return true;
    }
    window = GetParent(window);
  }
  return false;
}

static bool IsCompatibleWithMouseWheelRedirection(HWND window) {
  std::wstring class_name = gfx::GetClassName(window);
  // Mousewheel redirection to comboboxes is a surprising and
  // undesireable user behavior.
  return !(class_name == L"ComboBox" ||
           class_name == L"ComboBoxEx32");
}

static bool CanRedirectMouseWheelFrom(HWND window) {
  std::wstring class_name = gfx::GetClassName(window);

  // Older Thinkpad mouse wheel drivers create a window under mouse wheel
  // pointer. Detect if we are dealing with this window. In this case we
  // don't need to do anything as the Thinkpad mouse driver will send
  // mouse wheel messages to the right window.
  if ((class_name == L"Syn Visual Class") ||
     (class_name == L"SynTrackCursorWindowClass"))
    return false;

  return true;
}

ViewProp* SetWindowSupportsRerouteMouseWheel(HWND hwnd) {
  return new ViewProp(hwnd, kHWNDSupportMouseWheelRerouting,
                      reinterpret_cast<HANDLE>(true));
}

bool RerouteMouseWheel(HWND window, WPARAM w_param, LPARAM l_param) {
  // Since this is called from a subclass for every window, we can get
  // here recursively. This will happen if, for example, a control
  // reflects wheel scroll messages to its parent. Bail out if we got
  // here recursively.
  static bool recursion_break = false;
  if (recursion_break)
    return false;
  // Check if this window's class has a bad interaction with rerouting.
  if (!IsCompatibleWithMouseWheelRedirection(window))
    return false;

  DWORD current_process = GetCurrentProcessId();
  POINT wheel_location = { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) };
  HWND window_under_wheel = WindowFromPoint(wheel_location);

  if (!CanRedirectMouseWheelFrom(window_under_wheel))
    return false;

  // Find the lowest Chrome window in the hierarchy that can be the
  // target of mouse wheel redirection.
  while (window != window_under_wheel) {
    // If window_under_wheel is not a valid Chrome window, then return true to
    // suppress further processing of the message.
    if (!::IsWindow(window_under_wheel))
      return true;
    DWORD wheel_window_process = 0;
    GetWindowThreadProcessId(window_under_wheel, &wheel_window_process);
    if (current_process != wheel_window_process) {
      if (IsChild(window, window_under_wheel)) {
        // If this message is reflected from a child window in a different
        // process (happens with out of process windowed plugins) then
        // we don't want to reroute the wheel message.
        return false;
      } else {
        // The wheel is scrolling over an unrelated window. Make sure that we
        // have marked that window as supporting mouse wheel rerouting.
        // Otherwise, we cannot send random WM_MOUSEWHEEL messages to arbitrary
        // windows. So just drop the message.
        if (!WindowSupportsRerouteMouseWheel(window_under_wheel))
          return true;
      }
    }

    // If the child window is transparent, then it is not interested in
    // receiving wheel events.
    if (IsChild(window, window_under_wheel) &&
        ::GetWindowLong(
            window_under_wheel, GWL_EXSTYLE) & WS_EX_TRANSPARENT) {
      return false;
    }

    // window_under_wheel is a Chrome window.  If allowed, redirect.
    if (IsCompatibleWithMouseWheelRedirection(window_under_wheel)) {
      base::AutoReset<bool> auto_reset_recursion_break(&recursion_break, true);
      SendMessage(window_under_wheel, WM_MOUSEWHEEL, w_param, l_param);
      return true;
    }
    // If redirection is disallowed, try the parent.
    window_under_wheel = GetAncestor(window_under_wheel, GA_PARENT);
  }
  // If we traversed back to the starting point, we should process
  // this message normally; return false.
  return false;
}

}  // namespace ui
