#include "dpi_utils.h"

namespace flutter {

namespace {

constexpr UINT kDefaultDpi = 96;

// This is the MDT_EFFECTIVE_DPI value from MONITOR_DPI_TYPE, an enum declared
// in ShellScalingApi.h. Replicating here to avoid importing the library
// directly.
constexpr UINT kEffectiveDpiMonitorType = 0;

template <typename T>

/// Retrieves a function |name| from a given |comBaseModule| into |outProc|.
/// Returns a bool indicating whether the function was found.
bool AssignProcAddress(HMODULE comBaseModule, const char* name, T*& outProc) {
  outProc = reinterpret_cast<T*>(GetProcAddress(comBaseModule, name));
  return *outProc != nullptr;
}

/// A helper class for abstracting various Windows DPI related functions across
/// Windows OS versions.
class Win32DpiHelper {
 public:
  Win32DpiHelper();

  ~Win32DpiHelper();

  /// Returns the DPI for |hwnd|. Supports all DPI awareness modes, and is
  /// backward compatible down to Windows Vista. If |hwnd| is nullptr, returns
  /// the DPI for the primary monitor. If Per-Monitor DPI awareness is not
  /// available, returns the system's DPI.
  UINT GetDpiForWindow(HWND);

  /// Returns the DPI of a given monitor. Defaults to 96 if the API is not
  /// available.
  UINT GetDpiForMonitor(HMONITOR);

 private:
  using GetDpiForWindow_ = UINT __stdcall(HWND);
  using GetDpiForMonitor_ = HRESULT __stdcall(HMONITOR hmonitor,
                                              UINT dpiType,
                                              UINT* dpiX,
                                              UINT* dpiY);
  using EnableNonClientDpiScaling_ = BOOL __stdcall(HWND hwnd);

  GetDpiForWindow_* get_dpi_for_window_ = nullptr;
  GetDpiForMonitor_* get_dpi_for_monitor_ = nullptr;
  EnableNonClientDpiScaling_* enable_non_client_dpi_scaling_ = nullptr;

  HMODULE user32_module_ = nullptr;
  HMODULE shlib_module_ = nullptr;
  bool dpi_for_window_supported_ = false;
  bool dpi_for_monitor_supported_ = false;
};

Win32DpiHelper::Win32DpiHelper() {
  if ((user32_module_ = LoadLibraryA("User32.dll")) != nullptr) {
    dpi_for_window_supported_ = (AssignProcAddress(
        user32_module_, "GetDpiForWindow", get_dpi_for_window_));
  }
  if ((shlib_module_ = LoadLibraryA("Shcore.dll")) != nullptr) {
    dpi_for_monitor_supported_ = AssignProcAddress(
        shlib_module_, "GetDpiForMonitor", get_dpi_for_monitor_);
  }
}

Win32DpiHelper::~Win32DpiHelper() {
  if (user32_module_ != nullptr) {
    FreeLibrary(user32_module_);
  }
  if (shlib_module_ != nullptr) {
    FreeLibrary(shlib_module_);
  }
}

UINT Win32DpiHelper::GetDpiForWindow(HWND hwnd) {
  // GetDpiForWindow returns the DPI for any awareness mode. If not available,
  // or no |hwnd| is provided, fallback to a per monitor, system, or default
  // DPI.
  if (dpi_for_window_supported_ && hwnd != nullptr) {
    return get_dpi_for_window_(hwnd);
  }

  if (dpi_for_monitor_supported_) {
    HMONITOR monitor = nullptr;
    if (hwnd != nullptr) {
      monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
    }
    return GetDpiForMonitor(monitor);
  }
  HDC hdc = GetDC(hwnd);
  UINT dpi = GetDeviceCaps(hdc, LOGPIXELSX);
  ReleaseDC(hwnd, hdc);
  return dpi;
}

UINT Win32DpiHelper::GetDpiForMonitor(HMONITOR monitor) {
  if (dpi_for_monitor_supported_) {
    if (monitor == nullptr) {
      const POINT target_point = {0, 0};
      monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTOPRIMARY);
    }
    UINT dpi_x = 0, dpi_y = 0;
    HRESULT result =
        get_dpi_for_monitor_(monitor, kEffectiveDpiMonitorType, &dpi_x, &dpi_y);
    if (SUCCEEDED(result)) {
      return dpi_x;
    }
  }
  return kDefaultDpi;
}  // namespace

Win32DpiHelper* GetHelper() {
  static Win32DpiHelper* dpi_helper = new Win32DpiHelper();
  return dpi_helper;
}
}  // namespace

UINT GetDpiForHWND(HWND hwnd) {
  return GetHelper()->GetDpiForWindow(hwnd);
}

UINT GetDpiForMonitor(HMONITOR monitor) {
  return GetHelper()->GetDpiForMonitor(monitor);
}
}  // namespace flutter
