/*
  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_ResetDeadKeys()
{
    /*
    if a deadkey has been typed, but not the next character (which the deadkey might modify), 
    this tries to undo the effect pressing the deadkey.
    see: http://archives.miloush.net/michkap/archive/2006/09/10/748775.html
    */
    BYTE keyboardState[256];
    WCHAR buffer[16];
    int keycode, scancode, result, i;

    GetKeyboardState(keyboardState);

    keycode = VK_SPACE;
    scancode = MapVirtualKey(keycode, MAPVK_VK_TO_VSC);
    if (scancode == 0) {
        /* the keyboard doesn't have this key */
        return;
    }

    for (i = 0; i < 5; i++) {
        result = ToUnicode(keycode, scancode, keyboardState, (LPWSTR)buffer, 16, 0);
        if (result > 0) {
            /* success */
            return;
        }
    }
}

void
WIN_StartTextInput(_THIS)
{
#ifndef SDL_DISABLE_WINDOWS_IME
    SDL_Window *window;
#endif

    WIN_ResetDeadKeys();

#ifndef SDL_DISABLE_WINDOWS_IME
    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;
#endif

    WIN_ResetDeadKeys();

#ifndef SDL_DISABLE_WINDOWS_IME
    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: */
