/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#if SDL_VIDEO_DRIVER_WINDOWS

#include "SDL_windowsvideo.h"

#include "../../events/SDL_keyboard_c.h"
#include "../../events/scancodes_windows.h"

#include <imm.h>
#include <oleauto.h>

#ifndef SDL_DISABLE_WINDOWS_IME
static void IME_Init(SDL_VideoData *videodata, HWND hwnd);
static void IME_Enable(SDL_VideoData *videodata, HWND hwnd);
static void IME_Disable(SDL_VideoData *videodata, HWND hwnd);
static void IME_Quit(SDL_VideoData *videodata);
#endif /* !SDL_DISABLE_WINDOWS_IME */

#ifndef MAPVK_VK_TO_VSC
#define MAPVK_VK_TO_VSC     0
#endif
#ifndef MAPVK_VSC_TO_VK
#define MAPVK_VSC_TO_VK     1
#endif
#ifndef MAPVK_VK_TO_CHAR
#define MAPVK_VK_TO_CHAR    2
#endif

/* Alphabetic scancodes for PC keyboards */
void
WIN_InitKeyboard(_THIS)
{
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;

    data->ime_com_initialized = SDL_FALSE;
    data->ime_threadmgr = 0;
    data->ime_initialized = SDL_FALSE;
    data->ime_enabled = SDL_FALSE;
    data->ime_available = SDL_FALSE;
    data->ime_hwnd_main = 0;
    data->ime_hwnd_current = 0;
    data->ime_himc = 0;
    data->ime_composition[0] = 0;
    data->ime_readingstring[0] = 0;
    data->ime_cursor = 0;

    data->ime_candlist = SDL_FALSE;
    SDL_memset(data->ime_candidates, 0, sizeof(data->ime_candidates));
    data->ime_candcount = 0;
    data->ime_candref = 0;
    data->ime_candsel = 0;
    data->ime_candpgsize = 0;
    data->ime_candlistindexbase = 0;
    data->ime_candvertical = SDL_TRUE;

    data->ime_dirty = SDL_FALSE;
    SDL_memset(&data->ime_rect, 0, sizeof(data->ime_rect));
    SDL_memset(&data->ime_candlistrect, 0, sizeof(data->ime_candlistrect));
    data->ime_winwidth = 0;
    data->ime_winheight = 0;

    data->ime_hkl = 0;
    data->ime_himm32 = 0;
    data->GetReadingString = 0;
    data->ShowReadingWindow = 0;
    data->ImmLockIMC = 0;
    data->ImmUnlockIMC = 0;
    data->ImmLockIMCC = 0;
    data->ImmUnlockIMCC = 0;
    data->ime_uiless = SDL_FALSE;
    data->ime_threadmgrex = 0;
    data->ime_uielemsinkcookie = TF_INVALID_COOKIE;
    data->ime_alpnsinkcookie = TF_INVALID_COOKIE;
    data->ime_openmodesinkcookie = TF_INVALID_COOKIE;
    data->ime_convmodesinkcookie = TF_INVALID_COOKIE;
    data->ime_uielemsink = 0;
    data->ime_ippasink = 0;

    WIN_UpdateKeymap();

    SDL_SetScancodeName(SDL_SCANCODE_APPLICATION, "Menu");
    SDL_SetScancodeName(SDL_SCANCODE_LGUI, "Left Windows");
    SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Windows");

    /* Are system caps/num/scroll lock active? Set our state to match. */
    SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0);
    SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0);
}

void
WIN_UpdateKeymap()
{
    int i;
    SDL_Scancode scancode;
    SDL_Keycode keymap[SDL_NUM_SCANCODES];

    SDL_GetDefaultKeymap(keymap);

    for (i = 0; i < SDL_arraysize(windows_scancode_table); i++) {
        int vk;
        /* Make sure this scancode is a valid character scancode */
        scancode = windows_scancode_table[i];
        if (scancode == SDL_SCANCODE_UNKNOWN ) {
            continue;
        }

        /* If this key is one of the non-mappable keys, ignore it */
        /* Not mapping numbers fixes the French layout, giving numeric keycodes for the number keys, which is the expected behavior */
        if ((keymap[scancode] & SDLK_SCANCODE_MASK) ||
            /*  scancode == SDL_SCANCODE_GRAVE || */ /* Uncomment this line to re-enable the behavior of not mapping the "`"(grave) key to the users actual keyboard layout */
            (scancode >= SDL_SCANCODE_1 && scancode <= SDL_SCANCODE_0) ) {
            continue;
        }

        vk =  MapVirtualKey(i, MAPVK_VSC_TO_VK);
        if ( vk ) {
            int ch = (MapVirtualKey( vk, MAPVK_VK_TO_CHAR ) & 0x7FFF);
            if ( ch ) {
                if ( ch >= 'A' && ch <= 'Z' ) {
                    keymap[scancode] =  SDLK_a + ( ch - 'A' );
                } else {
                    keymap[scancode] = ch;
                }
            }
        }
    }

    SDL_SetKeymap(0, keymap, SDL_NUM_SCANCODES);
}

void
WIN_QuitKeyboard(_THIS)
{
#ifndef SDL_DISABLE_WINDOWS_IME
    IME_Quit((SDL_VideoData *)_this->driverdata);
#endif
}

void
WIN_StartTextInput(_THIS)
{
#ifndef SDL_DISABLE_WINDOWS_IME
    SDL_Window *window = SDL_GetKeyboardFocus();
    if (window) {
        HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
        SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
        SDL_GetWindowSize(window, &videodata->ime_winwidth, &videodata->ime_winheight);
        IME_Init(videodata, hwnd);
        IME_Enable(videodata, hwnd);
    }
#endif /* !SDL_DISABLE_WINDOWS_IME */
}

void
WIN_StopTextInput(_THIS)
{
#ifndef SDL_DISABLE_WINDOWS_IME
    SDL_Window *window = SDL_GetKeyboardFocus();
    if (window) {
        HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
        SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
        IME_Init(videodata, hwnd);
        IME_Disable(videodata, hwnd);
    }
#endif /* !SDL_DISABLE_WINDOWS_IME */
}

void
WIN_SetTextInputRect(_THIS, SDL_Rect *rect)
{
    SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
    HIMC himc = 0;

    if (!rect) {
        SDL_InvalidParamError("rect");
        return;
    }

    videodata->ime_rect = *rect;

    himc = ImmGetContext(videodata->ime_hwnd_current);
    if (himc)
    {
        COMPOSITIONFORM cf;
        cf.ptCurrentPos.x = videodata->ime_rect.x;
        cf.ptCurrentPos.y = videodata->ime_rect.y;
        cf.dwStyle = CFS_FORCE_POSITION;
        ImmSetCompositionWindow(himc, &cf);
        ImmReleaseContext(videodata->ime_hwnd_current, himc);
    }
}

#ifdef SDL_DISABLE_WINDOWS_IME


SDL_bool
IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata)
{
    return SDL_FALSE;
}

void IME_Present(SDL_VideoData *videodata)
{
}

#else

#ifdef _SDL_msctf_h
#define USE_INIT_GUID
#elif defined(__GNUC__)
#define USE_INIT_GUID
#endif
#ifdef USE_INIT_GUID
#undef DEFINE_GUID
#define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) static const GUID n = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
DEFINE_GUID(IID_ITfInputProcessorProfileActivationSink,        0x71C6E74E,0x0F28,0x11D8,0xA8,0x2A,0x00,0x06,0x5B,0x84,0x43,0x5C);
DEFINE_GUID(IID_ITfUIElementSink,                              0xEA1EA136,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
DEFINE_GUID(GUID_TFCAT_TIP_KEYBOARD,                           0x34745C63,0xB2F0,0x4784,0x8B,0x67,0x5E,0x12,0xC8,0x70,0x1A,0x31);
DEFINE_GUID(IID_ITfSource,                                     0x4EA48A35,0x60AE,0x446F,0x8F,0xD6,0xE6,0xA8,0xD8,0x24,0x59,0xF7);
DEFINE_GUID(IID_ITfUIElementMgr,                               0xEA1EA135,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
DEFINE_GUID(IID_ITfCandidateListUIElement,                     0xEA1EA138,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
DEFINE_GUID(IID_ITfReadingInformationUIElement,                0xEA1EA139,0x19DF,0x11D7,0xA6,0xD2,0x00,0x06,0x5B,0x84,0x43,0x5C);
DEFINE_GUID(IID_ITfThreadMgr,                                  0xAA80E801,0x2021,0x11D2,0x93,0xE0,0x00,0x60,0xB0,0x67,0xB8,0x6E);
DEFINE_GUID(CLSID_TF_ThreadMgr,                                0x529A9E6B,0x6587,0x4F23,0xAB,0x9E,0x9C,0x7D,0x68,0x3E,0x3C,0x50);
DEFINE_GUID(IID_ITfThreadMgrEx,                                0x3E90ADE3,0x7594,0x4CB0,0xBB,0x58,0x69,0x62,0x8F,0x5F,0x45,0x8C);
#endif

#define LANG_CHT MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL)
#define LANG_CHS MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)

#define MAKEIMEVERSION(major,minor) ((DWORD) (((BYTE)(major) << 24) | ((BYTE)(minor) << 16) ))
#define IMEID_VER(id) ((id) & 0xffff0000)
#define IMEID_LANG(id) ((id) & 0x0000ffff)

#define CHT_HKL_DAYI            ((HKL)0xE0060404)
#define CHT_HKL_NEW_PHONETIC    ((HKL)0xE0080404)
#define CHT_HKL_NEW_CHANG_JIE   ((HKL)0xE0090404)
#define CHT_HKL_NEW_QUICK       ((HKL)0xE00A0404)
#define CHT_HKL_HK_CANTONESE    ((HKL)0xE00B0404)
#define CHT_IMEFILENAME1        "TINTLGNT.IME"
#define CHT_IMEFILENAME2        "CINTLGNT.IME"
#define CHT_IMEFILENAME3        "MSTCIPHA.IME"
#define IMEID_CHT_VER42         (LANG_CHT | MAKEIMEVERSION(4, 2))
#define IMEID_CHT_VER43         (LANG_CHT | MAKEIMEVERSION(4, 3))
#define IMEID_CHT_VER44         (LANG_CHT | MAKEIMEVERSION(4, 4))
#define IMEID_CHT_VER50         (LANG_CHT | MAKEIMEVERSION(5, 0))
#define IMEID_CHT_VER51         (LANG_CHT | MAKEIMEVERSION(5, 1))
#define IMEID_CHT_VER52         (LANG_CHT | MAKEIMEVERSION(5, 2))
#define IMEID_CHT_VER60         (LANG_CHT | MAKEIMEVERSION(6, 0))
#define IMEID_CHT_VER_VISTA     (LANG_CHT | MAKEIMEVERSION(7, 0))

#define CHS_HKL                 ((HKL)0xE00E0804)
#define CHS_IMEFILENAME1        "PINTLGNT.IME"
#define CHS_IMEFILENAME2        "MSSCIPYA.IME"
#define IMEID_CHS_VER41         (LANG_CHS | MAKEIMEVERSION(4, 1))
#define IMEID_CHS_VER42         (LANG_CHS | MAKEIMEVERSION(4, 2))
#define IMEID_CHS_VER53         (LANG_CHS | MAKEIMEVERSION(5, 3))

#define LANG() LOWORD((videodata->ime_hkl))
#define PRIMLANG() ((WORD)PRIMARYLANGID(LANG()))
#define SUBLANG() SUBLANGID(LANG())

static void IME_UpdateInputLocale(SDL_VideoData *videodata);
static void IME_ClearComposition(SDL_VideoData *videodata);
static void IME_SetWindow(SDL_VideoData* videodata, HWND hwnd);
static void IME_SetupAPI(SDL_VideoData *videodata);
static DWORD IME_GetId(SDL_VideoData *videodata, UINT uIndex);
static void IME_SendEditingEvent(SDL_VideoData *videodata);
static void IME_DestroyTextures(SDL_VideoData *videodata);

#define SDL_IsEqualIID(riid1, riid2) SDL_IsEqualGUID(riid1, riid2)
#define SDL_IsEqualGUID(rguid1, rguid2) (!SDL_memcmp(rguid1, rguid2, sizeof(GUID)))

static SDL_bool UILess_SetupSinks(SDL_VideoData *videodata);
static void UILess_ReleaseSinks(SDL_VideoData *videodata);
static void UILess_EnableUIUpdates(SDL_VideoData *videodata);
static void UILess_DisableUIUpdates(SDL_VideoData *videodata);

static void
IME_Init(SDL_VideoData *videodata, HWND hwnd)
{
    if (videodata->ime_initialized)
        return;

    videodata->ime_hwnd_main = hwnd;
    if (SUCCEEDED(WIN_CoInitialize())) {
        videodata->ime_com_initialized = SDL_TRUE;
        CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgr, (LPVOID *)&videodata->ime_threadmgr);
    }
    videodata->ime_initialized = SDL_TRUE;
    videodata->ime_himm32 = SDL_LoadObject("imm32.dll");
    if (!videodata->ime_himm32) {
        videodata->ime_available = SDL_FALSE;
        return;
    }
    videodata->ImmLockIMC = (LPINPUTCONTEXT2 (WINAPI *)(HIMC))SDL_LoadFunction(videodata->ime_himm32, "ImmLockIMC");
    videodata->ImmUnlockIMC = (BOOL (WINAPI *)(HIMC))SDL_LoadFunction(videodata->ime_himm32, "ImmUnlockIMC");
    videodata->ImmLockIMCC = (LPVOID (WINAPI *)(HIMCC))SDL_LoadFunction(videodata->ime_himm32, "ImmLockIMCC");
    videodata->ImmUnlockIMCC = (BOOL (WINAPI *)(HIMCC))SDL_LoadFunction(videodata->ime_himm32, "ImmUnlockIMCC");

    IME_SetWindow(videodata, hwnd);
    videodata->ime_himc = ImmGetContext(hwnd);
    ImmReleaseContext(hwnd, videodata->ime_himc);
    if (!videodata->ime_himc) {
        videodata->ime_available = SDL_FALSE;
        IME_Disable(videodata, hwnd);
        return;
    }
    videodata->ime_available = SDL_TRUE;
    IME_UpdateInputLocale(videodata);
    IME_SetupAPI(videodata);
    videodata->ime_uiless = UILess_SetupSinks(videodata);
    IME_UpdateInputLocale(videodata);
    IME_Disable(videodata, hwnd);
}

static void
IME_Enable(SDL_VideoData *videodata, HWND hwnd)
{
    if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
        return;

    if (!videodata->ime_available) {
        IME_Disable(videodata, hwnd);
        return;
    }
    if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
        ImmAssociateContext(videodata->ime_hwnd_current, videodata->ime_himc);

    videodata->ime_enabled = SDL_TRUE;
    IME_UpdateInputLocale(videodata);
    UILess_EnableUIUpdates(videodata);
}

static void
IME_Disable(SDL_VideoData *videodata, HWND hwnd)
{
    if (!videodata->ime_initialized || !videodata->ime_hwnd_current)
        return;

    IME_ClearComposition(videodata);
    if (videodata->ime_hwnd_current == videodata->ime_hwnd_main)
        ImmAssociateContext(videodata->ime_hwnd_current, (HIMC)0);

    videodata->ime_enabled = SDL_FALSE;
    UILess_DisableUIUpdates(videodata);
}

static void
IME_Quit(SDL_VideoData *videodata)
{
    if (!videodata->ime_initialized)
        return;

    UILess_ReleaseSinks(videodata);
    if (videodata->ime_hwnd_main)
        ImmAssociateContext(videodata->ime_hwnd_main, videodata->ime_himc);

    videodata->ime_hwnd_main = 0;
    videodata->ime_himc = 0;
    if (videodata->ime_himm32) {
        SDL_UnloadObject(videodata->ime_himm32);
        videodata->ime_himm32 = 0;
    }
    if (videodata->ime_threadmgr) {
        videodata->ime_threadmgr->lpVtbl->Release(videodata->ime_threadmgr);
        videodata->ime_threadmgr = 0;
    }
    if (videodata->ime_com_initialized) {
        WIN_CoUninitialize();
        videodata->ime_com_initialized = SDL_FALSE;
    }
    IME_DestroyTextures(videodata);
    videodata->ime_initialized = SDL_FALSE;
}

static void
IME_GetReadingString(SDL_VideoData *videodata, HWND hwnd)
{
    DWORD id = 0;
    HIMC himc = 0;
    WCHAR buffer[16];
    WCHAR *s = buffer;
    DWORD len = 0;
    INT err = 0;
    BOOL vertical = FALSE;
    UINT maxuilen = 0;
    static OSVERSIONINFOA osversion;

    if (videodata->ime_uiless)
        return;

    videodata->ime_readingstring[0] = 0;
    if (!osversion.dwOSVersionInfoSize) {
        osversion.dwOSVersionInfoSize = sizeof(osversion);
        GetVersionExA(&osversion);
    }
    id = IME_GetId(videodata, 0);
    if (!id)
        return;

    himc = ImmGetContext(hwnd);
    if (!himc)
        return;

    if (videodata->GetReadingString) {
        len = videodata->GetReadingString(himc, 0, 0, &err, &vertical, &maxuilen);
        if (len) {
            if (len > SDL_arraysize(buffer))
                len = SDL_arraysize(buffer);

            len = videodata->GetReadingString(himc, len, s, &err, &vertical, &maxuilen);
        }
        SDL_wcslcpy(videodata->ime_readingstring, s, len);
    }
    else {
        LPINPUTCONTEXT2 lpimc = videodata->ImmLockIMC(himc);
        LPBYTE p = 0;
        s = 0;
        switch (id)
        {
        case IMEID_CHT_VER42:
        case IMEID_CHT_VER43:
        case IMEID_CHT_VER44:
            p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 24);
            if (!p)
                break;

            len = *(DWORD *)(p + 7*4 + 32*4);
            s = (WCHAR *)(p + 56);
            break;
        case IMEID_CHT_VER51:
        case IMEID_CHT_VER52:
        case IMEID_CHS_VER53:
            p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 4);
            if (!p)
                break;

            p = *(LPBYTE *)((LPBYTE)p + 1*4 + 5*4);
            if (!p)
                break;

            len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
            s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
            break;
        case IMEID_CHS_VER41:
            {
                int offset = (IME_GetId(videodata, 1) >= 0x00000002) ? 8 : 7;
                p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + offset * 4);
                if (!p)
                    break;

                len = *(DWORD *)(p + 7*4 + 16*2*4);
                s = (WCHAR *)(p + 6*4 + 16*2*1);
            }
            break;
        case IMEID_CHS_VER42:
            if (osversion.dwPlatformId != VER_PLATFORM_WIN32_NT)
                break;

            p = *(LPBYTE *)((LPBYTE)videodata->ImmLockIMCC(lpimc->hPrivate) + 1*4 + 1*4 + 6*4);
            if (!p)
                break;

            len = *(DWORD *)(p + 1*4 + (16*2+2*4) + 5*4 + 16*2);
            s = (WCHAR *)(p + 1*4 + (16*2+2*4) + 5*4);
            break;
        }
        if (s) {
            size_t size = SDL_min((size_t)(len + 1), SDL_arraysize(videodata->ime_readingstring));
            SDL_wcslcpy(videodata->ime_readingstring, s, size);
        }

        videodata->ImmUnlockIMCC(lpimc->hPrivate);
        videodata->ImmUnlockIMC(himc);
    }
    ImmReleaseContext(hwnd, himc);
    IME_SendEditingEvent(videodata);
}

static void
IME_InputLangChanged(SDL_VideoData *videodata)
{
    UINT lang = PRIMLANG();
    IME_UpdateInputLocale(videodata);
    if (!videodata->ime_uiless)
        videodata->ime_candlistindexbase = (videodata->ime_hkl == CHT_HKL_DAYI) ? 0 : 1;

    IME_SetupAPI(videodata);
    if (lang != PRIMLANG()) {
        IME_ClearComposition(videodata);
    }
}

static DWORD
IME_GetId(SDL_VideoData *videodata, UINT uIndex)
{
    static HKL hklprev = 0;
    static DWORD dwRet[2] = {0};
    DWORD dwVerSize = 0;
    DWORD dwVerHandle = 0;
    LPVOID lpVerBuffer = 0;
    LPVOID lpVerData = 0;
    UINT cbVerData = 0;
    char szTemp[256];
    HKL hkl = 0;
    DWORD dwLang = 0;
    if (uIndex >= sizeof(dwRet) / sizeof(dwRet[0]))
        return 0;

    hkl = videodata->ime_hkl;
    if (hklprev == hkl)
        return dwRet[uIndex];

    hklprev = hkl;
    dwLang = ((DWORD_PTR)hkl & 0xffff);
    if (videodata->ime_uiless && LANG() == LANG_CHT) {
        dwRet[0] = IMEID_CHT_VER_VISTA;
        dwRet[1] = 0;
        return dwRet[0];
    }
    if (hkl != CHT_HKL_NEW_PHONETIC
        && hkl != CHT_HKL_NEW_CHANG_JIE
        && hkl != CHT_HKL_NEW_QUICK
        && hkl != CHT_HKL_HK_CANTONESE
        && hkl != CHS_HKL) {
        dwRet[0] = dwRet[1] = 0;
        return dwRet[uIndex];
    }
    if (ImmGetIMEFileNameA(hkl, szTemp, sizeof(szTemp) - 1) <= 0) {
        dwRet[0] = dwRet[1] = 0;
        return dwRet[uIndex];
    }
    if (!videodata->GetReadingString) {
        #define LCID_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
        if (CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME1, -1) != 2
            && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME2, -1) != 2
            && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHT_IMEFILENAME3, -1) != 2
            && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME1, -1) != 2
            && CompareStringA(LCID_INVARIANT, NORM_IGNORECASE, szTemp, -1, CHS_IMEFILENAME2, -1) != 2) {
            dwRet[0] = dwRet[1] = 0;
            return dwRet[uIndex];
        }
        #undef LCID_INVARIANT
        dwVerSize = GetFileVersionInfoSizeA(szTemp, &dwVerHandle);
        if (dwVerSize) {
            lpVerBuffer = SDL_malloc(dwVerSize);
            if (lpVerBuffer) {
                if (GetFileVersionInfoA(szTemp, dwVerHandle, dwVerSize, lpVerBuffer)) {
                    if (VerQueryValueA(lpVerBuffer, "\\", &lpVerData, &cbVerData)) {
                        #define pVerFixedInfo   ((VS_FIXEDFILEINFO FAR*)lpVerData)
                        DWORD dwVer = pVerFixedInfo->dwFileVersionMS;
                        dwVer = (dwVer & 0x00ff0000) << 8 | (dwVer & 0x000000ff) << 16;
                        if ((videodata->GetReadingString) ||
                            ((dwLang == LANG_CHT) && (
                            dwVer == MAKEIMEVERSION(4, 2) ||
                            dwVer == MAKEIMEVERSION(4, 3) ||
                            dwVer == MAKEIMEVERSION(4, 4) ||
                            dwVer == MAKEIMEVERSION(5, 0) ||
                            dwVer == MAKEIMEVERSION(5, 1) ||
                            dwVer == MAKEIMEVERSION(5, 2) ||
                            dwVer == MAKEIMEVERSION(6, 0)))
                            ||
                            ((dwLang == LANG_CHS) && (
                            dwVer == MAKEIMEVERSION(4, 1) ||
                            dwVer == MAKEIMEVERSION(4, 2) ||
                            dwVer == MAKEIMEVERSION(5, 3)))) {
                            dwRet[0] = dwVer | dwLang;
                            dwRet[1] = pVerFixedInfo->dwFileVersionLS;
                            SDL_free(lpVerBuffer);
                            return dwRet[0];
                        }
                        #undef pVerFixedInfo
                    }
                }
            }
            SDL_free(lpVerBuffer);
        }
    }
    dwRet[0] = dwRet[1] = 0;
    return dwRet[uIndex];
}

static void
IME_SetupAPI(SDL_VideoData *videodata)
{
    char ime_file[MAX_PATH + 1];
    void* hime = 0;
    HKL hkl = 0;
    videodata->GetReadingString = 0;
    videodata->ShowReadingWindow = 0;
    if (videodata->ime_uiless)
        return;

    hkl = videodata->ime_hkl;
    if (ImmGetIMEFileNameA(hkl, ime_file, sizeof(ime_file) - 1) <= 0)
        return;

    hime = SDL_LoadObject(ime_file);
    if (!hime)
        return;

    videodata->GetReadingString = (UINT (WINAPI *)(HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT))
        SDL_LoadFunction(hime, "GetReadingString");
    videodata->ShowReadingWindow = (BOOL (WINAPI *)(HIMC, BOOL))
        SDL_LoadFunction(hime, "ShowReadingWindow");

    if (videodata->ShowReadingWindow) {
        HIMC himc = ImmGetContext(videodata->ime_hwnd_current);
        if (himc) {
            videodata->ShowReadingWindow(himc, FALSE);
            ImmReleaseContext(videodata->ime_hwnd_current, himc);
        }
    }
}

static void
IME_SetWindow(SDL_VideoData* videodata, HWND hwnd)
{
    videodata->ime_hwnd_current = hwnd;
    if (videodata->ime_threadmgr) {
        struct ITfDocumentMgr *document_mgr = 0;
        if (SUCCEEDED(videodata->ime_threadmgr->lpVtbl->AssociateFocus(videodata->ime_threadmgr, hwnd, NULL, &document_mgr))) {
            if (document_mgr)
                document_mgr->lpVtbl->Release(document_mgr);
        }
    }
}

static void
IME_UpdateInputLocale(SDL_VideoData *videodata)
{
    static HKL hklprev = 0;
    videodata->ime_hkl = GetKeyboardLayout(0);
    if (hklprev == videodata->ime_hkl)
        return;

    hklprev = videodata->ime_hkl;
    switch (PRIMLANG()) {
    case LANG_CHINESE:
        videodata->ime_candvertical = SDL_TRUE;
        if (SUBLANG() == SUBLANG_CHINESE_SIMPLIFIED)
            videodata->ime_candvertical = SDL_FALSE;

        break;
    case LANG_JAPANESE:
        videodata->ime_candvertical = SDL_TRUE;
        break;
    case LANG_KOREAN:
        videodata->ime_candvertical = SDL_FALSE;
        break;
    }
}

static void
IME_ClearComposition(SDL_VideoData *videodata)
{
    HIMC himc = 0;
    if (!videodata->ime_initialized)
        return;

    himc = ImmGetContext(videodata->ime_hwnd_current);
    if (!himc)
        return;

    ImmNotifyIME(himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
    if (videodata->ime_uiless)
        ImmSetCompositionString(himc, SCS_SETSTR, TEXT(""), sizeof(TCHAR), TEXT(""), sizeof(TCHAR));

    ImmNotifyIME(himc, NI_CLOSECANDIDATE, 0, 0);
    ImmReleaseContext(videodata->ime_hwnd_current, himc);
    SDL_SendEditingText("", 0, 0);
}

static void
IME_GetCompositionString(SDL_VideoData *videodata, HIMC himc, DWORD string)
{
    LONG length = ImmGetCompositionStringW(himc, string, videodata->ime_composition, sizeof(videodata->ime_composition) - sizeof(videodata->ime_composition[0]));
    if (length < 0)
        length = 0;

    length /= sizeof(videodata->ime_composition[0]);
    videodata->ime_cursor = LOWORD(ImmGetCompositionStringW(himc, GCS_CURSORPOS, 0, 0));
    if (videodata->ime_cursor < SDL_arraysize(videodata->ime_composition) && videodata->ime_composition[videodata->ime_cursor] == 0x3000) {
        int i;
        for (i = videodata->ime_cursor + 1; i < length; ++i)
            videodata->ime_composition[i - 1] = videodata->ime_composition[i];

        --length;
    }
    videodata->ime_composition[length] = 0;
}

static void
IME_SendInputEvent(SDL_VideoData *videodata)
{
    char *s = 0;
    s = WIN_StringToUTF8(videodata->ime_composition);
    SDL_SendKeyboardText(s);
    SDL_free(s);

    videodata->ime_composition[0] = 0;
    videodata->ime_readingstring[0] = 0;
    videodata->ime_cursor = 0;
}

static void
IME_SendEditingEvent(SDL_VideoData *videodata)
{
    char *s = 0;
    WCHAR buffer[SDL_TEXTEDITINGEVENT_TEXT_SIZE];
    const size_t size = SDL_arraysize(buffer);
    buffer[0] = 0;
    if (videodata->ime_readingstring[0]) {
        size_t len = SDL_min(SDL_wcslen(videodata->ime_composition), (size_t)videodata->ime_cursor);
        SDL_wcslcpy(buffer, videodata->ime_composition, len + 1);
        SDL_wcslcat(buffer, videodata->ime_readingstring, size);
        SDL_wcslcat(buffer, &videodata->ime_composition[len], size);
    }
    else {
        SDL_wcslcpy(buffer, videodata->ime_composition, size);
    }
    s = WIN_StringToUTF8(buffer);
    SDL_SendEditingText(s, videodata->ime_cursor + (int)SDL_wcslen(videodata->ime_readingstring), 0);
    SDL_free(s);
}

static void
IME_AddCandidate(SDL_VideoData *videodata, UINT i, LPCWSTR candidate)
{
    LPWSTR dst = videodata->ime_candidates[i];
    *dst++ = (WCHAR)(TEXT('0') + ((i + videodata->ime_candlistindexbase) % 10));
    if (videodata->ime_candvertical)
        *dst++ = TEXT(' ');

    while (*candidate && (SDL_arraysize(videodata->ime_candidates[i]) > (dst - videodata->ime_candidates[i])))
        *dst++ = *candidate++;

    *dst = (WCHAR)'\0';
}

static void
IME_GetCandidateList(HIMC himc, SDL_VideoData *videodata)
{
    LPCANDIDATELIST cand_list = 0;
    DWORD size = ImmGetCandidateListW(himc, 0, 0, 0);
    if (size) {
        cand_list = (LPCANDIDATELIST)SDL_malloc(size);
        if (cand_list) {
            size = ImmGetCandidateListW(himc, 0, cand_list, size);
            if (size) {
                UINT i, j;
                UINT page_start = 0;
                videodata->ime_candsel = cand_list->dwSelection;
                videodata->ime_candcount = cand_list->dwCount;

                if (LANG() == LANG_CHS && IME_GetId(videodata, 0)) {
                    const UINT maxcandchar = 18;
                    size_t cchars = 0;

                    for (i = 0; i < videodata->ime_candcount; ++i) {
                        size_t len = SDL_wcslen((LPWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[i])) + 1;
                        if (len + cchars > maxcandchar) {
                            if (i > cand_list->dwSelection)
                                break;

                            page_start = i;
                            cchars = len;
                        }
                        else {
                            cchars += len;
                        }
                    }
                    videodata->ime_candpgsize = i - page_start;
                } else {
                    videodata->ime_candpgsize = SDL_min(cand_list->dwPageSize, MAX_CANDLIST);
                    page_start = (cand_list->dwSelection / videodata->ime_candpgsize) * videodata->ime_candpgsize;
                }
                SDL_memset(&videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
                for (i = page_start, j = 0; (DWORD)i < cand_list->dwCount && j < (int)videodata->ime_candpgsize; i++, j++) {
                    LPCWSTR candidate = (LPCWSTR)((DWORD_PTR)cand_list + cand_list->dwOffset[i]);
                    IME_AddCandidate(videodata, j, candidate);
                }
                if (PRIMLANG() == LANG_KOREAN || (PRIMLANG() == LANG_CHT && !IME_GetId(videodata, 0)))
                    videodata->ime_candsel = -1;

            }
            SDL_free(cand_list);
        }
    }
}

static void
IME_ShowCandidateList(SDL_VideoData *videodata)
{
    videodata->ime_dirty = SDL_TRUE;
    videodata->ime_candlist = SDL_TRUE;
    IME_DestroyTextures(videodata);
    IME_SendEditingEvent(videodata);
}

static void
IME_HideCandidateList(SDL_VideoData *videodata)
{
    videodata->ime_dirty = SDL_FALSE;
    videodata->ime_candlist = SDL_FALSE;
    IME_DestroyTextures(videodata);
    IME_SendEditingEvent(videodata);
}

SDL_bool
IME_HandleMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM *lParam, SDL_VideoData *videodata)
{
    SDL_bool trap = SDL_FALSE;
    HIMC himc = 0;
    if (!videodata->ime_initialized || !videodata->ime_available || !videodata->ime_enabled)
        return SDL_FALSE;

    switch (msg) {
    case WM_INPUTLANGCHANGE:
        IME_InputLangChanged(videodata);
        break;
    case WM_IME_SETCONTEXT:
        *lParam = 0;
        break;
    case WM_IME_STARTCOMPOSITION:
        trap = SDL_TRUE;
        break;
    case WM_IME_COMPOSITION:
        trap = SDL_TRUE;
        himc = ImmGetContext(hwnd);
        if (*lParam & GCS_RESULTSTR) {
            IME_GetCompositionString(videodata, himc, GCS_RESULTSTR);
            IME_SendInputEvent(videodata);
        }
        if (*lParam & GCS_COMPSTR) {
            if (!videodata->ime_uiless)
                videodata->ime_readingstring[0] = 0;

            IME_GetCompositionString(videodata, himc, GCS_COMPSTR);
            IME_SendEditingEvent(videodata);
        }
        ImmReleaseContext(hwnd, himc);
        break;
    case WM_IME_ENDCOMPOSITION:
        videodata->ime_composition[0] = 0;
        videodata->ime_readingstring[0] = 0;
        videodata->ime_cursor = 0;
        SDL_SendEditingText("", 0, 0);
        break;
    case WM_IME_NOTIFY:
        switch (wParam) {
        case IMN_SETCONVERSIONMODE:
        case IMN_SETOPENSTATUS:
            IME_UpdateInputLocale(videodata);
            break;
        case IMN_OPENCANDIDATE:
        case IMN_CHANGECANDIDATE:
            if (videodata->ime_uiless)
                break;

            trap = SDL_TRUE;
            IME_ShowCandidateList(videodata);
            himc = ImmGetContext(hwnd);
            if (!himc)
                break;

            IME_GetCandidateList(himc, videodata);
            ImmReleaseContext(hwnd, himc);
            break;
        case IMN_CLOSECANDIDATE:
            trap = SDL_TRUE;
            IME_HideCandidateList(videodata);
            break;
        case IMN_PRIVATE:
            {
                DWORD dwId = IME_GetId(videodata, 0);
                IME_GetReadingString(videodata, hwnd);
                switch (dwId)
                {
                case IMEID_CHT_VER42:
                case IMEID_CHT_VER43:
                case IMEID_CHT_VER44:
                case IMEID_CHS_VER41:
                case IMEID_CHS_VER42:
                    if (*lParam == 1 || *lParam == 2)
                        trap = SDL_TRUE;

                    break;
                case IMEID_CHT_VER50:
                case IMEID_CHT_VER51:
                case IMEID_CHT_VER52:
                case IMEID_CHT_VER60:
                case IMEID_CHS_VER53:
                    if (*lParam == 16
                        || *lParam == 17
                        || *lParam == 26
                        || *lParam == 27
                        || *lParam == 28)
                        trap = SDL_TRUE;
                    break;
                }
            }
            break;
        default:
            trap = SDL_TRUE;
            break;
        }
        break;
    }
    return trap;
}

static void
IME_CloseCandidateList(SDL_VideoData *videodata)
{
    IME_HideCandidateList(videodata);
    videodata->ime_candcount = 0;
    SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
}

static void
UILess_GetCandidateList(SDL_VideoData *videodata, ITfCandidateListUIElement *pcandlist)
{
    UINT selection = 0;
    UINT count = 0;
    UINT page = 0;
    UINT pgcount = 0;
    DWORD pgstart = 0;
    DWORD pgsize = 0;
    UINT i, j;
    pcandlist->lpVtbl->GetSelection(pcandlist, &selection);
    pcandlist->lpVtbl->GetCount(pcandlist, &count);
    pcandlist->lpVtbl->GetCurrentPage(pcandlist, &page);

    videodata->ime_candsel = selection;
    videodata->ime_candcount = count;
    IME_ShowCandidateList(videodata);

    pcandlist->lpVtbl->GetPageIndex(pcandlist, 0, 0, &pgcount);
    if (pgcount > 0) {
        UINT *idxlist = SDL_malloc(sizeof(UINT) * pgcount);
        if (idxlist) {
            pcandlist->lpVtbl->GetPageIndex(pcandlist, idxlist, pgcount, &pgcount);
            pgstart = idxlist[page];
            if (page < pgcount - 1)
                pgsize = SDL_min(count, idxlist[page + 1]) - pgstart;
            else
                pgsize = count - pgstart;

            SDL_free(idxlist);
        }
    }
    videodata->ime_candpgsize = SDL_min(pgsize, MAX_CANDLIST);
    videodata->ime_candsel = videodata->ime_candsel - pgstart;

    SDL_memset(videodata->ime_candidates, 0, sizeof(videodata->ime_candidates));
    for (i = pgstart, j = 0; (DWORD)i < count && j < videodata->ime_candpgsize; i++, j++) {
        BSTR bstr;
        if (SUCCEEDED(pcandlist->lpVtbl->GetString(pcandlist, i, &bstr))) {
            if (bstr) {
                IME_AddCandidate(videodata, j, bstr);
                SysFreeString(bstr);
            }
        }
    }
    if (PRIMLANG() == LANG_KOREAN)
        videodata->ime_candsel = -1;
}

STDMETHODIMP_(ULONG) TSFSink_AddRef(TSFSink *sink)
{
    return ++sink->refcount;
}

STDMETHODIMP_(ULONG)TSFSink_Release(TSFSink *sink)
{
    --sink->refcount;
    if (sink->refcount == 0) {
        SDL_free(sink);
        return 0;
    }
    return sink->refcount;
}

STDMETHODIMP UIElementSink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
{
    if (!ppv)
        return E_INVALIDARG;

    *ppv = 0;
    if (SDL_IsEqualIID(riid, &IID_IUnknown))
        *ppv = (IUnknown *)sink;
    else if (SDL_IsEqualIID(riid, &IID_ITfUIElementSink))
        *ppv = (ITfUIElementSink *)sink;

    if (*ppv) {
        TSFSink_AddRef(sink);
        return S_OK;
    }
    return E_NOINTERFACE;
}

ITfUIElement *UILess_GetUIElement(SDL_VideoData *videodata, DWORD dwUIElementId)
{
    ITfUIElementMgr *puiem = 0;
    ITfUIElement *pelem = 0;
    ITfThreadMgrEx *threadmgrex = videodata->ime_threadmgrex;

    if (SUCCEEDED(threadmgrex->lpVtbl->QueryInterface(threadmgrex, &IID_ITfUIElementMgr, (LPVOID *)&puiem))) {
        puiem->lpVtbl->GetUIElement(puiem, dwUIElementId, &pelem);
        puiem->lpVtbl->Release(puiem);
    }
    return pelem;
}

STDMETHODIMP UIElementSink_BeginUIElement(TSFSink *sink, DWORD dwUIElementId, BOOL *pbShow)
{
    ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
    ITfReadingInformationUIElement *preading = 0;
    ITfCandidateListUIElement *pcandlist = 0;
    SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
    if (!element)
        return E_INVALIDARG;

    *pbShow = FALSE;
    if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
        BSTR bstr;
        if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
            SysFreeString(bstr);
        }
        preading->lpVtbl->Release(preading);
    }
    else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
        videodata->ime_candref++;
        UILess_GetCandidateList(videodata, pcandlist);
        pcandlist->lpVtbl->Release(pcandlist);
    }
    return S_OK;
}

STDMETHODIMP UIElementSink_UpdateUIElement(TSFSink *sink, DWORD dwUIElementId)
{
    ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
    ITfReadingInformationUIElement *preading = 0;
    ITfCandidateListUIElement *pcandlist = 0;
    SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
    if (!element)
        return E_INVALIDARG;

    if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
        BSTR bstr;
        if (SUCCEEDED(preading->lpVtbl->GetString(preading, &bstr)) && bstr) {
            WCHAR *s = (WCHAR *)bstr;
            SDL_wcslcpy(videodata->ime_readingstring, s, SDL_arraysize(videodata->ime_readingstring));
            IME_SendEditingEvent(videodata);
            SysFreeString(bstr);
        }
        preading->lpVtbl->Release(preading);
    }
    else if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
        UILess_GetCandidateList(videodata, pcandlist);
        pcandlist->lpVtbl->Release(pcandlist);
    }
    return S_OK;
}

STDMETHODIMP UIElementSink_EndUIElement(TSFSink *sink, DWORD dwUIElementId)
{
    ITfUIElement *element = UILess_GetUIElement((SDL_VideoData *)sink->data, dwUIElementId);
    ITfReadingInformationUIElement *preading = 0;
    ITfCandidateListUIElement *pcandlist = 0;
    SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
    if (!element)
        return E_INVALIDARG;

    if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfReadingInformationUIElement, (LPVOID *)&preading))) {
        videodata->ime_readingstring[0] = 0;
        IME_SendEditingEvent(videodata);
        preading->lpVtbl->Release(preading);
    }
    if (SUCCEEDED(element->lpVtbl->QueryInterface(element, &IID_ITfCandidateListUIElement, (LPVOID *)&pcandlist))) {
        videodata->ime_candref--;
        if (videodata->ime_candref == 0)
            IME_CloseCandidateList(videodata);

        pcandlist->lpVtbl->Release(pcandlist);
    }
    return S_OK;
}

STDMETHODIMP IPPASink_QueryInterface(TSFSink *sink, REFIID riid, PVOID *ppv)
{
    if (!ppv)
        return E_INVALIDARG;

    *ppv = 0;
    if (SDL_IsEqualIID(riid, &IID_IUnknown))
        *ppv = (IUnknown *)sink;
    else if (SDL_IsEqualIID(riid, &IID_ITfInputProcessorProfileActivationSink))
        *ppv = (ITfInputProcessorProfileActivationSink *)sink;

    if (*ppv) {
        TSFSink_AddRef(sink);
        return S_OK;
    }
    return E_NOINTERFACE;
}

STDMETHODIMP IPPASink_OnActivated(TSFSink *sink, DWORD dwProfileType, LANGID langid, REFCLSID clsid, REFGUID catid, REFGUID guidProfile, HKL hkl, DWORD dwFlags)
{
    static const GUID TF_PROFILE_DAYI = { 0x037B2C25, 0x480C, 0x4D7F, { 0xB0, 0x27, 0xD6, 0xCA, 0x6B, 0x69, 0x78, 0x8A } };
    SDL_VideoData *videodata = (SDL_VideoData *)sink->data;
    videodata->ime_candlistindexbase = SDL_IsEqualGUID(&TF_PROFILE_DAYI, guidProfile) ? 0 : 1;
    if (SDL_IsEqualIID(catid, &GUID_TFCAT_TIP_KEYBOARD) && (dwFlags & TF_IPSINK_FLAG_ACTIVE))
        IME_InputLangChanged((SDL_VideoData *)sink->data);

    IME_HideCandidateList(videodata);
    return S_OK;
}

static void *vtUIElementSink[] = {
    (void *)(UIElementSink_QueryInterface),
    (void *)(TSFSink_AddRef),
    (void *)(TSFSink_Release),
    (void *)(UIElementSink_BeginUIElement),
    (void *)(UIElementSink_UpdateUIElement),
    (void *)(UIElementSink_EndUIElement)
};

static void *vtIPPASink[] = {
    (void *)(IPPASink_QueryInterface),
    (void *)(TSFSink_AddRef),
    (void *)(TSFSink_Release),
    (void *)(IPPASink_OnActivated)
};

static void
UILess_EnableUIUpdates(SDL_VideoData *videodata)
{
    ITfSource *source = 0;
    if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie != TF_INVALID_COOKIE)
        return;

    if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
        source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie);
        source->lpVtbl->Release(source);
    }
}

static void
UILess_DisableUIUpdates(SDL_VideoData *videodata)
{
    ITfSource *source = 0;
    if (!videodata->ime_threadmgrex || videodata->ime_uielemsinkcookie == TF_INVALID_COOKIE)
        return;

    if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
        source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie);
        videodata->ime_uielemsinkcookie = TF_INVALID_COOKIE;
        source->lpVtbl->Release(source);
    }
}

static SDL_bool
UILess_SetupSinks(SDL_VideoData *videodata)
{
    TfClientId clientid = 0;
    SDL_bool result = SDL_FALSE;
    ITfSource *source = 0;
    if (FAILED(CoCreateInstance(&CLSID_TF_ThreadMgr, NULL, CLSCTX_INPROC_SERVER, &IID_ITfThreadMgrEx, (LPVOID *)&videodata->ime_threadmgrex)))
        return SDL_FALSE;

    if (FAILED(videodata->ime_threadmgrex->lpVtbl->ActivateEx(videodata->ime_threadmgrex, &clientid, TF_TMAE_UIELEMENTENABLEDONLY)))
        return SDL_FALSE;

    videodata->ime_uielemsink = SDL_malloc(sizeof(TSFSink));
    videodata->ime_ippasink = SDL_malloc(sizeof(TSFSink));

    videodata->ime_uielemsink->lpVtbl = vtUIElementSink;
    videodata->ime_uielemsink->refcount = 1;
    videodata->ime_uielemsink->data = videodata;

    videodata->ime_ippasink->lpVtbl = vtIPPASink;
    videodata->ime_ippasink->refcount = 1;
    videodata->ime_ippasink->data = videodata;

    if (SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
        if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfUIElementSink, (IUnknown *)videodata->ime_uielemsink, &videodata->ime_uielemsinkcookie))) {
            if (SUCCEEDED(source->lpVtbl->AdviseSink(source, &IID_ITfInputProcessorProfileActivationSink, (IUnknown *)videodata->ime_ippasink, &videodata->ime_alpnsinkcookie))) {
                result = SDL_TRUE;
            }
        }
        source->lpVtbl->Release(source);
    }
    return result;
}

#define SAFE_RELEASE(p)                             \
{                                                   \
    if (p) {                                        \
        (p)->lpVtbl->Release((p));                  \
        (p) = 0;                                    \
    }                                               \
}

static void
UILess_ReleaseSinks(SDL_VideoData *videodata)
{
    ITfSource *source = 0;
    if (videodata->ime_threadmgrex && SUCCEEDED(videodata->ime_threadmgrex->lpVtbl->QueryInterface(videodata->ime_threadmgrex, &IID_ITfSource, (LPVOID *)&source))) {
        source->lpVtbl->UnadviseSink(source, videodata->ime_uielemsinkcookie);
        source->lpVtbl->UnadviseSink(source, videodata->ime_alpnsinkcookie);
        SAFE_RELEASE(source);
        videodata->ime_threadmgrex->lpVtbl->Deactivate(videodata->ime_threadmgrex);
        SAFE_RELEASE(videodata->ime_threadmgrex);
        TSFSink_Release(videodata->ime_uielemsink);
        videodata->ime_uielemsink = 0;
        TSFSink_Release(videodata->ime_ippasink);
        videodata->ime_ippasink = 0;
    }
}

static void *
StartDrawToBitmap(HDC hdc, HBITMAP *hhbm, int width, int height)
{
    BITMAPINFO info;
    BITMAPINFOHEADER *infoHeader = &info.bmiHeader;
    BYTE *bits = NULL;
    if (hhbm) {
        SDL_zero(info);
        infoHeader->biSize = sizeof(BITMAPINFOHEADER);
        infoHeader->biWidth = width;
        infoHeader->biHeight = -1 * SDL_abs(height);
        infoHeader->biPlanes = 1;
        infoHeader->biBitCount = 32;
        infoHeader->biCompression = BI_RGB;
        *hhbm = CreateDIBSection(hdc, &info, DIB_RGB_COLORS, (void **)&bits, 0, 0);
        if (*hhbm)
            SelectObject(hdc, *hhbm);
    }
    return bits;
}

static void
StopDrawToBitmap(HDC hdc, HBITMAP *hhbm)
{
    if (hhbm && *hhbm) {
        DeleteObject(*hhbm);
        *hhbm = NULL;
    }
}

/* This draws only within the specified area and fills the entire region. */
static void
DrawRect(HDC hdc, int left, int top, int right, int bottom, int pensize)
{
    /* The case of no pen (PenSize = 0) is automatically taken care of. */
    const int penadjust = (int)SDL_floor(pensize / 2.0f - 0.5f);
    left += pensize / 2;
    top += pensize / 2;
    right -= penadjust;
    bottom -= penadjust;
    Rectangle(hdc, left, top, right, bottom);
}

static void
IME_DestroyTextures(SDL_VideoData *videodata)
{
}

#define SDL_swap(a,b) { \
    int c = (a);        \
    (a) = (b);          \
    (b) = c;            \
    }

static void
IME_PositionCandidateList(SDL_VideoData *videodata, SIZE size)
{
    int left, top, right, bottom;
    SDL_bool ok = SDL_FALSE;
    int winw = videodata->ime_winwidth;
    int winh = videodata->ime_winheight;

    /* Bottom */
    left = videodata->ime_rect.x;
    top = videodata->ime_rect.y + videodata->ime_rect.h;
    right = left + size.cx;
    bottom = top + size.cy;
    if (right >= winw) {
        left -= right - winw;
        right = winw;
    }
    if (bottom < winh)
        ok = SDL_TRUE;

    /* Top */
    if (!ok) {
        left = videodata->ime_rect.x;
        top = videodata->ime_rect.y - size.cy;
        right = left + size.cx;
        bottom = videodata->ime_rect.y;
        if (right >= winw) {
            left -= right - winw;
            right = winw;
        }
        if (top >= 0)
            ok = SDL_TRUE;
    }

    /* Right */
    if (!ok) {
        left = videodata->ime_rect.x + size.cx;
        top = 0;
        right = left + size.cx;
        bottom = size.cy;
        if (right < winw)
            ok = SDL_TRUE;
    }

    /* Left */
    if (!ok) {
        left = videodata->ime_rect.x - size.cx;
        top = 0;
        right = videodata->ime_rect.x;
        bottom = size.cy;
        if (right >= 0)
            ok = SDL_TRUE;
    }

    /* Window too small, show at (0,0) */
    if (!ok) {
        left = 0;
        top = 0;
        right = size.cx;
        bottom = size.cy;
    }

    videodata->ime_candlistrect.x = left;
    videodata->ime_candlistrect.y = top;
    videodata->ime_candlistrect.w = right - left;
    videodata->ime_candlistrect.h = bottom - top;
}

static void
IME_RenderCandidateList(SDL_VideoData *videodata, HDC hdc)
{
    int i, j;
    SIZE size = {0};
    SIZE candsizes[MAX_CANDLIST];
    SIZE maxcandsize = {0};
    HBITMAP hbm = NULL;
    const int candcount = SDL_min(SDL_min(MAX_CANDLIST, videodata->ime_candcount), videodata->ime_candpgsize);
    SDL_bool vertical = videodata->ime_candvertical;

    const int listborder = 1;
    const int listpadding = 0;
    const int listbordercolor = RGB(0xB4, 0xC7, 0xAA);
    const int listfillcolor = RGB(255, 255, 255);

    const int candborder = 1;
    const int candpadding = 0;
    const int candmargin = 1;
    const COLORREF candbordercolor = RGB(255, 255, 255);
    const COLORREF candfillcolor = RGB(255, 255, 255);
    const COLORREF candtextcolor = RGB(0, 0, 0);
    const COLORREF selbordercolor = RGB(0x84, 0xAC, 0xDD);
    const COLORREF selfillcolor = RGB(0xD2, 0xE6, 0xFF);
    const COLORREF seltextcolor = RGB(0, 0, 0);
    const int horzcandspacing = 5;

    HPEN listpen = listborder != 0 ? CreatePen(PS_SOLID, listborder, listbordercolor) : (HPEN)GetStockObject(NULL_PEN);
    HBRUSH listbrush = CreateSolidBrush(listfillcolor);
    HPEN candpen = candborder != 0 ? CreatePen(PS_SOLID, candborder, candbordercolor) : (HPEN)GetStockObject(NULL_PEN);
    HBRUSH candbrush = CreateSolidBrush(candfillcolor);
    HPEN selpen = candborder != 0 ? CreatePen(PS_DOT, candborder, selbordercolor) : (HPEN)GetStockObject(NULL_PEN);
    HBRUSH selbrush = CreateSolidBrush(selfillcolor);
    HFONT font = CreateFont((int)(1 + videodata->ime_rect.h * 0.75f), 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, VARIABLE_PITCH | FF_SWISS, TEXT("Microsoft Sans Serif"));

    SetBkMode(hdc, TRANSPARENT);
    SelectObject(hdc, font);

    for (i = 0; i < candcount; ++i) {
        const WCHAR *s = videodata->ime_candidates[i];
        if (!*s)
            break;

        GetTextExtentPoint32W(hdc, s, (int)SDL_wcslen(s), &candsizes[i]);
        maxcandsize.cx = SDL_max(maxcandsize.cx, candsizes[i].cx);
        maxcandsize.cy = SDL_max(maxcandsize.cy, candsizes[i].cy);

    }
    if (vertical) {
        size.cx =
            (listborder * 2) +
            (listpadding * 2) +
            (candmargin * 2) +
            (candborder * 2) +
            (candpadding * 2) +
            (maxcandsize.cx)
            ;
        size.cy =
            (listborder * 2) +
            (listpadding * 2) +
            ((candcount + 1) * candmargin) +
            (candcount * candborder * 2) +
            (candcount * candpadding * 2) +
            (candcount * maxcandsize.cy)
            ;
    }
    else {
        size.cx =
            (listborder * 2) +
            (listpadding * 2) +
            ((candcount + 1) * candmargin) +
            (candcount * candborder * 2) +
            (candcount * candpadding * 2) +
            ((candcount - 1) * horzcandspacing);
        ;

        for (i = 0; i < candcount; ++i)
            size.cx += candsizes[i].cx;

        size.cy =
            (listborder * 2) +
            (listpadding * 2) +
            (candmargin * 2) +
            (candborder * 2) +
            (candpadding * 2) +
            (maxcandsize.cy)
            ;
    }

    StartDrawToBitmap(hdc, &hbm, size.cx, size.cy);

    SelectObject(hdc, listpen);
    SelectObject(hdc, listbrush);
    DrawRect(hdc, 0, 0, size.cx, size.cy, listborder);

    SelectObject(hdc, candpen);
    SelectObject(hdc, candbrush);
    SetTextColor(hdc, candtextcolor);
    SetBkMode(hdc, TRANSPARENT);

    for (i = 0; i < candcount; ++i) {
        const WCHAR *s = videodata->ime_candidates[i];
        int left, top, right, bottom;
        if (!*s)
            break;

        if (vertical) {
            left = listborder + listpadding + candmargin;
            top = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * maxcandsize.cy);
            right = size.cx - listborder - listpadding - candmargin;
            bottom = top + maxcandsize.cy + (candpadding * 2) + (candborder * 2);
        }
        else {
            left = listborder + listpadding + (i * candborder * 2) + (i * candpadding * 2) + ((i + 1) * candmargin) + (i * horzcandspacing);

            for (j = 0; j < i; ++j)
                left += candsizes[j].cx;

            top = listborder + listpadding + candmargin;
            right = left + candsizes[i].cx + (candpadding * 2) + (candborder * 2);
            bottom = size.cy - listborder - listpadding - candmargin;
        }

        if (i == videodata->ime_candsel) {
            SelectObject(hdc, selpen);
            SelectObject(hdc, selbrush);
            SetTextColor(hdc, seltextcolor);
        }
        else {
            SelectObject(hdc, candpen);
            SelectObject(hdc, candbrush);
            SetTextColor(hdc, candtextcolor);
        }

        DrawRect(hdc, left, top, right, bottom, candborder);
        ExtTextOutW(hdc, left + candborder + candpadding, top + candborder + candpadding, 0, NULL, s, (int)SDL_wcslen(s), NULL);
    }
    StopDrawToBitmap(hdc, &hbm);

    DeleteObject(listpen);
    DeleteObject(listbrush);
    DeleteObject(candpen);
    DeleteObject(candbrush);
    DeleteObject(selpen);
    DeleteObject(selbrush);
    DeleteObject(font);

    IME_PositionCandidateList(videodata, size);
}

static void
IME_Render(SDL_VideoData *videodata)
{
    HDC hdc = CreateCompatibleDC(NULL);

    if (videodata->ime_candlist)
        IME_RenderCandidateList(videodata, hdc);

    DeleteDC(hdc);

    videodata->ime_dirty = SDL_FALSE;
}

void IME_Present(SDL_VideoData *videodata)
{
    if (videodata->ime_dirty)
        IME_Render(videodata);

    /* FIXME: Need to show the IME bitmap */
}

#endif /* SDL_DISABLE_WINDOWS_IME */

#endif /* SDL_VIDEO_DRIVER_WINDOWS */

/* vi: set ts=4 sw=4 expandtab: */
