/* vi:set ts=8 sts=4 sw=4:
 *
 * VIM - Vi IMproved		by Bram Moolenaar
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 */

/*
 * DESCRIPTION:
 * This module produces Global IME for Vim, on Windows with Internet
 * Explorer 5.01 or higher.  You need three files "dimm.idl", "dimm.h", and
 * "dimm_i.c" when compile this module at your self.  "dimm.h", and
 * "dimm_i.c" are generated from "dimm.idl" by using MIDL.EXE as like
 * "if_ole.h".  You can get "dimm.idl" in MSDN web site.  I got it below
 * URL.
 *
 * WHAT IS THE GLOBAL IME?:
 * Global IME makes capability input Chinese, Japanese, and Korean text into
 * Vim buffer on any language version of Windows 98, Windows 95, and Windows
 * NT 4.0.  See below URL for detail of Global IME.  You can also find
 * various language version of Global IME at same place.
 *
 * RUNTIME REQUIREMENTS:
 * - Internet Explorer 5.01 or higher.
 * - Global IME (with language pack?).
 * - Of course Vim for Windows.
 *
 * URLS:
 * - Where you can probably get "dimm.idl".
 * http://msdn.microsoft.com/downloads/samples/internet/libraries/ie5_lib/sample.asp
 * - Global IME detailed information.
 * http://www.microsoft.com/windows/ie/features/ime.asp
 */

#ifdef GLOBAL_IME

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <objbase.h>
extern "C" {
#include "vim.h"
}
#include "dimm.h"
#include "glbl_ime.h"

static IActiveIMMApp *pIApp = NULL;
static IActiveIMMMessagePumpOwner *pIMsg = NULL;
static HWND s_hWnd = NULL;
static BOOL s_bStatus = FALSE; /* for evacuate */

/*
 * Initialize Global IME.
 * "atom" must be return value of RegisterClass(Ex).
 */
    void
global_ime_init(ATOM atom, HWND hWnd)
{
    IUnknown *pI;
    HRESULT hr;

    if (pIApp != NULL || pIMsg != NULL)
	return;
    OleInitialize(NULL);

    /*
     * Get interface IUnknown
     */
    hr = CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_SERVER,
	    IID_IUnknown, (void**)&pI);
    if (FAILED(hr) || !pI)
	return;

    /*
     * Get interface IActiveIMMApp
     */
    hr = pI->QueryInterface(IID_IActiveIMMApp, (void**)&pIApp);
    if (FAILED(hr))
	pIApp = NULL;

    /*
     * Get interface IActiveIMMMessagePumpOwner
     */
    hr = pI->QueryInterface(IID_IActiveIMMMessagePumpOwner, (void**)&pIMsg);
    if (FAILED(hr))
	pIMsg = NULL;

    if (pIApp != NULL)
    {
	pIApp->Activate(TRUE);
	pIApp->FilterClientWindows(&atom, 1);
    }
    if (pIMsg != NULL)
	pIMsg->Start();

    pI->Release();
    s_hWnd = hWnd;
}

/*
 * Reset and clear Global IME.
 */
    void
global_ime_end()
{
    if (pIApp != NULL)
    {
	IActiveIMMApp *p = pIApp;

	pIApp = NULL;
	p->FilterClientWindows(NULL, 0);
	p->Deactivate();
	p->Release();
    }
    if (pIMsg != NULL)
    {
	IActiveIMMMessagePumpOwner *p = pIMsg;

	pIMsg = NULL;
	p->End();
	p->Release();
    }
    OleUninitialize();
}

/*
 * Replacement for DefWindowProc().
 */
    LRESULT WINAPI
global_ime_DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
    LRESULT lResult;

    if (pIApp == NULL || pIApp->OnDefWindowProc(hWnd, Msg,
					    wParam, lParam, &lResult) != S_OK)
    {
#if defined(WIN3264) && defined(FEAT_MBYTE)
	if (wide_WindowProc)
	    lResult = DefWindowProcW(hWnd, Msg, wParam, lParam);
	else
#endif
	    lResult = DefWindowProc(hWnd, Msg, wParam, lParam);
    }
    return lResult;
}

/*
 * Replace with TranslateMessage()
 */
    BOOL WINAPI
global_ime_TranslateMessage(CONST MSG *lpMsg)
{
    if (pIMsg == NULL || pIMsg->OnTranslateMessage(lpMsg) == S_FALSE)
	return TranslateMessage(lpMsg);
    return TRUE;
}

/*
 * Set position of IME composition window.
 *
 * You have to call this before starting composition.  If once composition
 * started, this can take no effect until that composition have finished.  So
 * you should handle WM_IME_STARTCOMPOSITION and call this function.
 */
    void WINAPI
global_ime_set_position(POINT *pPoint)
{
    HIMC hImc = NULL;

    if (pIApp == NULL || pPoint == NULL)
	return;

    if (SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
    {
	COMPOSITIONFORM CompForm;

	CompForm.dwStyle = CFS_POINT;
	CompForm.ptCurrentPos = *pPoint;
	pIApp->SetCompositionWindow(hImc, &CompForm);
	pIApp->ReleaseContext(s_hWnd, hImc);
    }
}

/*
 * Set font to Global IME
 */
/* GIME_TEST */
    void WINAPI
global_ime_set_font(LOGFONT *pFont)
{
    HIMC hImc = NULL;

    if (pIApp == NULL || pFont == NULL)
	return;

    if (SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
    {
	pIApp->SetCompositionFontA(hImc, pFont);
	pIApp->ReleaseContext(s_hWnd, hImc);
    }
}

#if 0
/*
 * for IME control.  Save current status of IME, and set force new-status to
 * English (turn off).
 */
    void WINAPI
global_ime_status_evacuate()
{
    HIMC    hImc;

    if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
    {
	s_bStatus = (pIApp->GetOpenStatus(hImc) == 0) ? TRUE : FALSE;
	pIApp->SetOpenStatus(hImc, FALSE);
	pIApp->ReleaseContext(s_hWnd, hImc);
    }
}

/*
 * for IME control.  Change IME status to last saved one.
 */
    void WINAPI
global_ime_status_restore()
{
    HIMC    hImc;

    if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
    {
	pIApp->SetOpenStatus(hImc, s_bStatus);
	pIApp->ReleaseContext(s_hWnd, hImc);
    }
}
#endif

    void WINAPI
global_ime_set_status(int status)
{
    HIMC    hImc;

    if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
    {
	pIApp->SetOpenStatus(hImc, status ? TRUE : FALSE);
	pIApp->ReleaseContext(s_hWnd, hImc);
    }
}

    int WINAPI
global_ime_get_status()
{
    int status = 0;
    HIMC    hImc;

    if (pIApp != NULL && SUCCEEDED(pIApp->GetContext(s_hWnd, &hImc)))
    {
	status = pIApp->GetOpenStatus(hImc) ? 1 : 0;
	pIApp->ReleaseContext(s_hWnd, hImc);
    }
    return status;
}

#endif /* GLOBAL_IME */
