// Copyright (c) 2011 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 "chrome/browser/fullscreen.h"

#include <windows.h>
#include <shellapi.h>

#include "base/logging.h"
#include "base/win/win_util.h"
#include "base/win/windows_version.h"

#if defined(USE_ASH)
#include "ash/root_window_controller.h"
#include "chrome/browser/ui/host_desktop.h"
#endif

static bool IsPlatformFullScreenMode() {
  // SHQueryUserNotificationState is only available for Vista and above.
#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_VISTA)
  if (base::win::GetVersion() < base::win::VERSION_VISTA)
    return false;

  typedef HRESULT(WINAPI *SHQueryUserNotificationStatePtr)(
      QUERY_USER_NOTIFICATION_STATE* state);

  HMODULE shell32_base = ::GetModuleHandle(L"shell32.dll");
  if (!shell32_base) {
    NOTREACHED();
    return false;
  }
  SHQueryUserNotificationStatePtr query_user_notification_state_ptr =
        reinterpret_cast<SHQueryUserNotificationStatePtr>
            (::GetProcAddress(shell32_base, "SHQueryUserNotificationState"));
  if (!query_user_notification_state_ptr) {
    NOTREACHED();
    return false;
  }

  QUERY_USER_NOTIFICATION_STATE state;
  if (FAILED((*query_user_notification_state_ptr)(&state)))
    return false;
  return state == QUNS_RUNNING_D3D_FULL_SCREEN ||
         state == QUNS_PRESENTATION_MODE;
#else
  return false;
#endif
}

static bool IsFullScreenWindowMode() {
  // Get the foreground window which the user is currently working on.
  HWND wnd = ::GetForegroundWindow();
  if (!wnd)
    return false;

  // Get the monitor where the window is located.
  RECT wnd_rect;
  if (!::GetWindowRect(wnd, &wnd_rect))
    return false;
  HMONITOR monitor = ::MonitorFromRect(&wnd_rect, MONITOR_DEFAULTTONULL);
  if (!monitor)
    return false;
  MONITORINFO monitor_info = { sizeof(monitor_info) };
  if (!::GetMonitorInfo(monitor, &monitor_info))
    return false;

  // It should be the main monitor.
  if (!(monitor_info.dwFlags & MONITORINFOF_PRIMARY))
    return false;

  // The window should be at least as large as the monitor.
  if (!::IntersectRect(&wnd_rect, &wnd_rect, &monitor_info.rcMonitor))
    return false;
  if (!::EqualRect(&wnd_rect, &monitor_info.rcMonitor))
    return false;

  // At last, the window style should not have WS_DLGFRAME and WS_THICKFRAME and
  // its extended style should not have WS_EX_WINDOWEDGE and WS_EX_TOOLWINDOW.
  LONG style = ::GetWindowLong(wnd, GWL_STYLE);
  LONG ext_style = ::GetWindowLong(wnd, GWL_EXSTYLE);
  return !((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
           (ext_style & (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW)));
}

static bool IsFullScreenConsoleMode() {
  // We detect this by attaching the current process to the console of the
  // foreground window and then checking if it is in full screen mode.
  DWORD pid = 0;
  ::GetWindowThreadProcessId(::GetForegroundWindow(), &pid);
  if (!pid)
    return false;

  if (!::AttachConsole(pid))
    return false;

  DWORD modes = 0;
  ::GetConsoleDisplayMode(&modes);
  ::FreeConsole();

  return (modes & (CONSOLE_FULLSCREEN | CONSOLE_FULLSCREEN_HARDWARE)) != 0;
}

bool IsFullScreenMode() {
#if defined(USE_ASH)
  if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH) {
    ash::RootWindowController* controller =
        ash::RootWindowController::ForTargetRootWindow();
    return controller && controller->GetWindowForFullscreenMode();
  }
#endif
  return IsPlatformFullScreenMode() ||
         IsFullScreenWindowMode() ||
         IsFullScreenConsoleMode();
}
