// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "gui/base/win_util.h"

#ifdef OS_WIN
#define NTDDI_VERSION NTDDI_WIN7  // for JumpList.
#include <dwmapi.h>
#include <uxtheme.h>
#include <vssym32.h>
#include <windows.h>
#include <winuser.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlstr.h>
#include <atlwin.h>

#include <knownfolders.h>
#include <objectarray.h>
#include <propkey.h>
#include <propvarutil.h>
#include <shlobj.h>
#include <shobjidl.h>
#endif  // OS_WIN

#include <QtCore/QFile>
#include <QtCore/QLibrary>
#include <QtCore/QList>
#include <QtCore/QPointer>
#include <QtGui/QApplication>
#include <QtGui/QDesktopWidget>
#include <QtGui/QPainter>
#include <QtGui/QPaintEngine>
#include <QtGui/QWidget>

#ifdef OS_WIN
#include "base/const.h"
#endif  // OS_WIN
#include "base/logging.h"
#include "base/singleton.h"
#include "base/system_util.h"
#include "base/util.h"
#include "base/win_util.h"

#ifdef OS_WIN
#ifndef WM_DWMCOMPOSITIONCHANGED
#define WM_DWMCOMPOSITIONCHANGED        0x031E
#endif  // WM_DWMCOMPOSITIONCHANGED

// DWM API
typedef HRESULT (WINAPI *FPDwmIsCompositionEnabled)
    (BOOL *pfEnabled);
typedef HRESULT (WINAPI *FPDwmExtendFrameIntoClientArea)
    (HWND hWnd,
     const MARGINS *pMarInset);
typedef HRESULT (WINAPI *FPDwmEnableBlurBehindWindow)
    (HWND hWnd,
     const DWM_BLURBEHIND *pBlurBehind);

// Theme API
typedef HANDLE (WINAPI *FPOpenThemeData)
    (HWND hwnd, LPCWSTR pszClassList);
typedef HRESULT (WINAPI *FPCloseThemeData)
    (HANDLE hTheme);
typedef HRESULT (WINAPI *FPDrawThemeTextEx)
    (HANDLE hTheme, HDC hdc, int iPartId, int iStateId,
     LPCWSTR pszText, int cchText, DWORD dwTextFlags,
     LPRECT pRect, const DTTOPTS *pOptions);
typedef HRESULT (WINAPI *FPGetThemeSysFont)
    (HANDLE hTheme, int iFontId, LOGFONTW *plf);

#endif  // OS_WIN

namespace mozc {
namespace gui {

#ifdef OS_WIN
namespace {

FPDwmIsCompositionEnabled      gDwmIsCompositionEnabled      = NULL;
FPDwmEnableBlurBehindWindow    gDwmEnableBlurBehindWindow    = NULL;
FPDwmExtendFrameIntoClientArea gDwmExtendFrameIntoClientArea = NULL;
FPOpenThemeData                gOpenThemeData                = NULL;
FPCloseThemeData               gCloseThemeData               = NULL;
FPDrawThemeTextEx              gDrawThemeTextEx              = NULL;
FPGetThemeSysFont              gGetThemeSysFont              = NULL;

class WindowNotifier : public QWidget {
 public:
  WindowNotifier() {
    winId();   // to make a window handle
  }

  virtual ~WindowNotifier() {}

  void AddWidget(QWidget *widget) {
    widgets_.append(widget);
  }

  void RemoveWidget(QWidget *widget) {
    widgets_.removeAll(widget);
  }

  bool winEvent(MSG *message, long *result);

  void InstallStyleSheets(const QString &dwm_on_style,
                          const QString &dwm_off_style) {
    dwm_on_style_ = dwm_on_style;
    dwm_off_style_ = dwm_off_style;
  }

  static WindowNotifier *Get() {
    return Singleton<WindowNotifier>::get();
  }

 private:
  QWidgetList widgets_;
  QString dwm_on_style_;
  QString dwm_off_style_;
};

class DwmResolver {
 public:
  DwmResolver() : dwmlib_(NULL), themelib_(NULL) {
    dwmlib_ = mozc::WinUtil::LoadSystemLibrary(L"dwmapi.dll");
    themelib_ = mozc::WinUtil::LoadSystemLibrary(L"uxtheme.dll");

    if (NULL != dwmlib_) {
      gDwmIsCompositionEnabled =
          reinterpret_cast<FPDwmIsCompositionEnabled>
          (::GetProcAddress(dwmlib_,
                            "DwmIsCompositionEnabled"));
      gDwmExtendFrameIntoClientArea =
          reinterpret_cast<FPDwmExtendFrameIntoClientArea>
          (::GetProcAddress(dwmlib_,
                            "DwmExtendFrameIntoClientArea"));
      gDwmEnableBlurBehindWindow =
          reinterpret_cast<FPDwmEnableBlurBehindWindow>
          (::GetProcAddress(dwmlib_,
                            "DwmEnableBlurBehindWindow"));
    }

    if (NULL != themelib_) {
      gOpenThemeData =
          reinterpret_cast<FPOpenThemeData>(
              ::GetProcAddress(themelib_, "OpenThemeData"));
      gCloseThemeData =
          reinterpret_cast<FPCloseThemeData>(
              ::GetProcAddress(themelib_, "CloseThemeData"));
      gDrawThemeTextEx =
          reinterpret_cast<FPDrawThemeTextEx>(
              ::GetProcAddress(themelib_, "DrawThemeTextEx"));
      gGetThemeSysFont =
          reinterpret_cast<FPGetThemeSysFont>(
              ::GetProcAddress(themelib_, "GetThemeSysFont"));
    }
  }

  bool IsAvailable() const {
    return (gDwmIsCompositionEnabled != NULL &&
            gDwmExtendFrameIntoClientArea != NULL &&
            gDwmEnableBlurBehindWindow != NULL &&
            gOpenThemeData != NULL &&
            gCloseThemeData != NULL &&
            gDrawThemeTextEx != NULL &&
            gGetThemeSysFont != NULL);
  }

  static bool ResolveLibs() {
    return Singleton<DwmResolver>::get()->IsAvailable();
  }

 private:
  HMODULE dwmlib_;
  HMODULE themelib_;
};

CComPtr<IShellLink> InitializeShellLinkItem(const char *argument,
                                            const char *item_title) {
  HRESULT hr = S_OK;
  CComPtr<IShellLink> link;
  hr = link.CoCreateInstance(CLSID_ShellLink);
  if (FAILED(hr)) {
    DLOG(INFO) << "Failed to instanciate CLSID_ShellLink. hr = " << hr;
    return NULL;
  }

  {
    wstring mozc_tool_path_wide;
    Util::UTF8ToWide(SystemUtil::GetToolPath(), &mozc_tool_path_wide);
    hr = link->SetPath(mozc_tool_path_wide.c_str());
    if (FAILED(hr)) {
      DLOG(ERROR) << "SetPath failed. hr = " << hr;
      return NULL;
    }
  }

  {
    wstring argument_wide;
    Util::UTF8ToWide(argument, &argument_wide);
    hr = link->SetArguments(argument_wide.c_str());
    if (FAILED(hr)) {
      DLOG(ERROR) << "SetArguments failed. hr = " << hr;
      return NULL;
    }
  }

  CComQIPtr<IPropertyStore> property_store(link);
  if (property_store == NULL) {
    DLOG(ERROR) << "QueryInterface failed.";
    return NULL;
  }

  {
    wstring item_title_wide;
    Util::UTF8ToWide(item_title, &item_title_wide);
    PROPVARIANT prop_variant;
    hr = ::InitPropVariantFromString(item_title_wide.c_str(), &prop_variant);
    if (FAILED(hr)) {
      DLOG(ERROR) << "QueryInterface failed. hr = " << hr;
      return NULL;
    }
    hr = property_store->SetValue(PKEY_Title, prop_variant);
    ::PropVariantClear(&prop_variant);
  }

  if (FAILED(hr)) {
    DLOG(ERROR) << "SetValue failed. hr = " << hr;
    return NULL;
  }

  hr = property_store->Commit();
  if (FAILED(hr)) {
    DLOG(ERROR) << "Commit failed. hr = " << hr;
    return NULL;
  }

  return link;
}

struct LinkInfo {
  const char *argument;
  const char *title_english;
  const char *title_japanese;
};

bool AddTasksToList(CComPtr<ICustomDestinationList> destination_list) {
  HRESULT hr = S_OK;
  CComPtr<IObjectCollection> object_collection;

  hr = object_collection.CoCreateInstance(CLSID_EnumerableObjectCollection);
  if (FAILED(hr)) {
    DLOG(INFO) << "Failed to instanciate CLSID_EnumerableObjectCollection."
                  " hr = " << hr;
    return false;
  }

  // TODO(yukawa): Investigate better way to localize strings.
  const LinkInfo kLinks[] = {
    // "手書き文字入力"
    {"--mode=hand_writing",
     "Hand Wrinting",
     "\xE6\x89\x8B\xE6\x9B\xB8\xE3\x81\x8D\xE6\x96\x87\xE5\xAD\x97"
     "\xE5\x85\xA5\xE5\x8A\x9B"},
    // "文字パレット"
    {"--mode=character_palette",
     "Character Palette",
     "\xE6\x96\x87\xE5\xAD\x97\xE3\x83\x91\xE3\x83\xAC\xE3\x83\x83"
     "\xE3\x83\x88"},
    // "辞書ツール"
    {"--mode=dictionary_tool",
     "Dictionary Tool",
     "\xE8\xBE\x9E\xE6\x9B\xB8\xE3\x83\x84\xE3\x83\xBC\xE3\x83\xAB"},
    // "単語登録"
    {"--mode=word_register_dialog",
     "Add Word",
     "\xE5\x8D\x98\xE8\xAA\x9E\xE7\x99\xBB\xE9\x8C\xB2"},
    // "プロパティ"
    {"--mode=config_dialog",
     "Properties",
     "\xE3\x83\x97\xE3\x83\xAD\xE3\x83\x91\xE3\x83\x86\xE3\x82\xA3"},
  };

  const LANGID kJapaneseLangId = MAKELANGID(LANG_JAPANESE,
                                            SUBLANG_JAPANESE_JAPAN);
  const bool use_japanese_ui =
      (kJapaneseLangId == ::GetUserDefaultUILanguage());

  for (size_t i = 0; i < arraysize(kLinks); ++i) {
    CComPtr<IShellLink> link;
    if (use_japanese_ui) {
      link = InitializeShellLinkItem(kLinks[i].argument,
                                     kLinks[i].title_japanese);
    } else {
      link = InitializeShellLinkItem(kLinks[i].argument,
                                     kLinks[i].title_english);
    }
    if (link != NULL) {
      object_collection->AddObject(link);
    }
  }

  CComQIPtr<IObjectArray> object_array(object_collection);
  if (object_array == NULL) {
    DLOG(ERROR) << "QueryInterface failed.";
    return false;
  }

  hr = destination_list->AddUserTasks(object_array);
  if (FAILED(hr)) {
    DLOG(ERROR) << "AddUserTasks failed. hr = " << hr;
    return false;
  }

  return true;
}

void InitializeJumpList() {
  HRESULT hr = S_OK;

  CComPtr<ICustomDestinationList> destination_list;
  hr = destination_list.CoCreateInstance(CLSID_DestinationList);
  if (FAILED(hr)) {
    DLOG(INFO) << "Failed to instanciate CLSID_DestinationList. hr = " << hr;
    return;
  }

  UINT min_slots = 0;
  CComPtr<IObjectArray> removed_objects;
  hr = destination_list->BeginList(&min_slots, IID_IObjectArray,
                                   reinterpret_cast<void **>(&removed_objects));
  if (FAILED(hr)) {
    DLOG(INFO) << "BeginList failed. hr = " << hr;
    return;
  }

  if (!AddTasksToList(destination_list)) {
    return;
  }

  hr = destination_list->CommitList();
  if (FAILED(hr)) {
    DLOG(INFO) << "Commit failed. hr = " << hr;
    return;
  }
}
}  // namespace
#endif  // OS_WIN

bool WinUtil::IsCompositionEnabled() {
#ifdef OS_WIN
  if (!DwmResolver::ResolveLibs()) {
    return false;
  }

  HRESULT hr = S_OK;
  BOOL is_enabled = false;
  hr = gDwmIsCompositionEnabled(&is_enabled);
  if (SUCCEEDED(hr)) {
    return is_enabled;
  } else {
    LOG(ERROR) << "DwmIsCompositionEnabled() failed: "
               << static_cast<long>(hr);
  }
#endif  // OS_WIN

  return false;
}

bool WinUtil::ExtendFrameIntoClientArea(QWidget *widget,
                                        int left, int top,
                                        int right, int bottom) {
  DCHECK(widget);

#ifdef OS_WIN
  if (!DwmResolver::ResolveLibs()) {
    return false;
  }

  HRESULT hr = S_OK;
  MARGINS margin = { left, top, right, bottom };
  hr = gDwmExtendFrameIntoClientArea(widget->winId(), &margin);
  if (SUCCEEDED(hr)) {
    WindowNotifier::Get()->AddWidget(widget);
    widget->setAttribute(Qt::WA_TranslucentBackground, true);
    return true;
  } else {
    LOG(ERROR) << "DwmExtendFrameIntoClientArea() failed: "
               << static_cast<long>(hr);
  }
#endif  // OS_WIN

  return false;
}

#ifdef OS_WIN
bool WindowNotifier::winEvent(MSG *message, long *result) {
  if (message != NULL && message->message == WM_DWMCOMPOSITIONCHANGED) {
    const bool composition_enabled = WinUtil::IsCompositionEnabled();

    // switch styles if need be
    if (!dwm_on_style_.isEmpty() && !dwm_off_style_.isEmpty()) {
      if (composition_enabled) {
        qApp->setStyleSheet(dwm_on_style_);
      } else {
        qApp->setStyleSheet(dwm_off_style_);
      }
    }

    foreach(QWidget *widget, widgets_) {
      if (widget != NULL) {
        widget->setAttribute(Qt::WA_NoSystemBackground,
                             composition_enabled);
        // TODO(taku): left/top/right/bottom are not updated.
        // need to be fixed.
        if (composition_enabled) {
          MARGINS margin = { -1, 0, 0, 0 };
          gDwmExtendFrameIntoClientArea(widget->winId(), &margin);
          widget->setAttribute(Qt::WA_TranslucentBackground, true);
        }
        widget->update();
      }
    }
  }

  // call default
  return QWidget::winEvent(message, result);
}
#endif  // OS_WIN

QRect WinUtil::GetTextRect(QWidget *widget, const QString &text) {
  DCHECK(widget);
  const QFont font = QApplication::font(widget);
  const QFontMetrics fontMetrics(font);
  return fontMetrics.boundingRect(text);
}

void WinUtil::InstallStyleSheets(const QString &dwm_on_style,
                                 const QString &dwm_off_style) {
#ifdef OS_WIN
  WindowNotifier::Get()->InstallStyleSheets(dwm_on_style,
                                            dwm_off_style);
#endif  // OS_WIN
}

void WinUtil::InstallStyleSheetsFiles(const QString &dwm_on_style_file,
                                      const QString &dwm_off_style_file) {
#ifdef OS_WIN
  QFile file1(dwm_on_style_file);
  file1.open(QFile::ReadOnly);
  QFile file2(dwm_off_style_file);
  file2.open(QFile::ReadOnly);
  WinUtil::InstallStyleSheets(QLatin1String(file1.readAll()),
                              QLatin1String(file2.readAll()));
#endif  // OS_WIN
}

void WinUtil::DrawThemeText(const QString &text,
                            const QRect &rect,
                            int glow_size,
                            QPainter *painter) {
  DCHECK(painter);

#ifdef OS_WIN
  if (!DwmResolver::ResolveLibs()) {
    return;
  }

  HDC hdc = painter->paintEngine()->getDC();
  if (NULL == hdc) {
    LOG(ERROR) << "hdc is NULL";
    return;
  }

  HANDLE theme = gOpenThemeData(qApp->desktop()->winId(), L"WINDOW");
  if (theme == NULL) {
    LOG(ERROR) << "::OpenThemaData() failed";
    return;
  }

  // Set up a memory DC and bitmap that we'll draw into
  HDC dc_mem = ::CreateCompatibleDC(hdc);
  if (dc_mem == NULL) {
    gCloseThemeData(theme);
    LOG(ERROR) << "::CreateCompatibleDC() failed: " << ::GetLastError();
    return;
  }

  BITMAPINFO dib = { 0 };
  dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  dib.bmiHeader.biWidth = rect.width();
  dib.bmiHeader.biHeight = -rect.height();
  dib.bmiHeader.biPlanes = 1;
  dib.bmiHeader.biBitCount = 32;
  dib.bmiHeader.biCompression = BI_RGB;

  HBITMAP bmp = ::CreateDIBSection(hdc, &dib,
                                   DIB_RGB_COLORS, NULL, NULL, 0);
  if (NULL == bmp) {
    ::DeleteDC(dc_mem);
    gCloseThemeData(theme);
    LOG(ERROR) << "::CreateDIBSection() failed: " << ::GetLastError();
    return;
  }

  LOGFONT lf = { 0 };
  if (NULL != theme) {
    gGetThemeSysFont(theme, TMT_CAPTIONFONT, &lf);
  } else {
    NONCLIENTMETRICS ncm = { sizeof(NONCLIENTMETRICS) };
    ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
                           sizeof(NONCLIENTMETRICS), &ncm, false);
    lf = ncm.lfMessageFont;
  }

  HFONT caption_font = ::CreateFontIndirect(&lf);
  HBITMAP old_bmp = reinterpret_cast<HBITMAP>(
      ::SelectObject(dc_mem,
                     reinterpret_cast<HGDIOBJ>(bmp)));
  HFONT old_font = reinterpret_cast<HFONT>(
      ::SelectObject(dc_mem,
                     reinterpret_cast<HGDIOBJ>(caption_font)));

  DTTOPTS dto = { sizeof(DTTOPTS) };
  const UINT format = DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX;
  RECT rctext = { 0, 0, rect.width(), rect.height() };

  dto.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE;
  dto.iGlowSize = glow_size;

  const HRESULT hr =
      gDrawThemeTextEx(theme, dc_mem, 0, 0,
                       reinterpret_cast<LPCWSTR>(text.utf16()),
                       -1, format, &rctext, &dto);
  if (SUCCEEDED(hr)) {
    // Copy to the painter's HDC
    if (!::BitBlt(hdc, rect.left(), rect.top(), rect.width(), rect.height(),
                  dc_mem, 0, 0, SRCCOPY)) {
      LOG(ERROR) << "::BitBlt() failed: " << ::GetLastError();
    }
  } else {
    LOG(ERROR) << "::DrawThemeTextEx() failed: " << static_cast<long>(hr);
  }

  ::SelectObject(dc_mem, reinterpret_cast<HGDIOBJ>(old_bmp));
  ::SelectObject(dc_mem, reinterpret_cast<HGDIOBJ>(old_font));
  ::DeleteObject(bmp);
  ::DeleteObject(caption_font);
  ::DeleteDC(dc_mem);
  gCloseThemeData(theme);

#endif  // OS_WIN
}

#ifdef OS_WIN
namespace {

struct FindVisibleWindowInfo {
  HWND found_window_handle;
  DWORD target_process_id;
};

BOOL CALLBACK FindVisibleWindowProc(HWND hwnd, LPARAM lp) {
  DWORD process_id = 0;
  ::GetWindowThreadProcessId(hwnd, &process_id);
  FindVisibleWindowInfo *info = reinterpret_cast<FindVisibleWindowInfo *>(lp);
  if (process_id != info->target_process_id) {
    // continue enum
    return TRUE;
  }
  if (::IsWindowVisible(hwnd) == FALSE) {
    // continue enum
    return TRUE;
  }
  info->found_window_handle = hwnd;
  return FALSE;
}

}  // namespace
#endif  // OS_WIN

void WinUtil::ActivateWindow(uint32 process_id) {
#ifdef OS_WIN
  FindVisibleWindowInfo info = {};
  info.target_process_id = process_id;

  // The target process may contain several top-level windows.
  // We do not care about the invisible windows.
  if (::EnumWindows(FindVisibleWindowProc,
                    reinterpret_cast<LPARAM>(&info)) != 0) {
    LOG(ERROR) << "Could not find the exsisting window.";
  }
  const CWindow window(info.found_window_handle);
  wstring window_title_wide;
  {
    CString buf;
    window.GetWindowTextW(buf);
    window_title_wide.assign(buf.GetString(), buf.GetLength());
  }
  string window_title_utf8;
  Util::WideToUTF8(window_title_wide, &window_title_utf8);
  LOG(INFO) << "A visible window found. hwnd: " << window.m_hWnd
            << ", title: " << window_title_utf8;

  // SetForegroundWindow API does not automatically restore the minimized
  // window. Use explicitly OpenIcon API in this case.
  if (window.IsIconic()) {
    if (::OpenIcon(window.m_hWnd) == FALSE) {
      LOG(ERROR) << "::OpenIcon() failed.";
    }
  }

  // SetForegroundWindow API works wll iff the caller process satisfies the
  // condition described in the following document.
  // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633539.aspx
  // Never use AttachThreadInput API to work around this restriction.
  // http://blogs.msdn.com/b/oldnewthing/archive/2008/08/01/8795860.aspx
  if (::SetForegroundWindow(window.m_hWnd) == FALSE) {
    LOG(ERROR) << "::SetForegroundWindow() failed.";
  }
#endif  // OS_WIN
}

#ifdef OS_WIN
namespace {
const wchar_t kIMEHotKeyEntryKey[]   = L"Keyboard Layout\\Toggle";
const wchar_t kIMEHotKeyEntryValue[] = L"Layout Hotkey";
const wchar_t kIMEHotKeyEntryData[]  = L"3";
}
#endif  // OS_WIN

// static
bool WinUtil::GetIMEHotKeyDisabled() {
#ifdef OS_WIN
  CRegKey key;
  LONG result = key.Open(HKEY_CURRENT_USER, kIMEHotKeyEntryKey, KEY_READ);

  // When the key doesn't exist, can return |false| as well.
  if (ERROR_SUCCESS != result) {
    return false;
  }

  wchar_t data[4] = {};
  ULONG num_chars = arraysize(data);
  result = key.QueryStringValue(kIMEHotKeyEntryValue, data, &num_chars);
  // Returned |num_char| includes NULL character.

  // This is only the condition when this function
  // can return |true|
  if (ERROR_SUCCESS == result &&
      num_chars < arraysize(data) &&
      wstring(data) == kIMEHotKeyEntryData) {
    return true;
  }

  return false;
#else   // OS_WIN
  return false;
#endif  // OS_WIN
}

// static
bool WinUtil::SetIMEHotKeyDisabled(bool disabled) {
#ifdef OS_WIN
  if (WinUtil::GetIMEHotKeyDisabled() == disabled) {
    // Do not need to update this entry.
    return true;
  }

  if (disabled) {
    CRegKey key;
    LONG result = key.Create(HKEY_CURRENT_USER, kIMEHotKeyEntryKey);
    if (ERROR_SUCCESS != result) {
      return false;
    }

    // set "3"
    result = key.SetStringValue(kIMEHotKeyEntryValue, kIMEHotKeyEntryData);

    return ERROR_SUCCESS == result;
  } else {
    CRegKey key;
    LONG result = key.Open(HKEY_CURRENT_USER, kIMEHotKeyEntryKey,
                           KEY_SET_VALUE | DELETE);
    if (result == ERROR_FILE_NOT_FOUND) {
      return true;  // default value will be used.
    }

    if (ERROR_SUCCESS != result) {
      return false;
    }

    result = key.DeleteValue(kIMEHotKeyEntryValue);

    return (ERROR_SUCCESS == result || ERROR_FILE_NOT_FOUND == result);
  }
#endif  // OS_WIN

  return false;
}

void WinUtil::KeepJumpListUpToDate() {
#ifdef OS_WIN
  HRESULT hr = S_OK;

  hr = ::CoInitializeEx(NULL,
                        COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
  if (FAILED(hr)) {
    DLOG(INFO) << "CoInitializeEx failed. hr = " << hr;
    return;
  }
  InitializeJumpList();
  ::CoUninitialize();
#endif  // OS_WIN
}
}  // namespace gui
}  // namespace mozc
