/*
 *	Implementation of the 'IME window' class
 *
 *	Copyright 2000 Hidenori Takeshima
 *
 *
 * FIXME:
 *	- handle all messages.
 *	- handle all notifications.
 */

#include "config.h"

#include "winbase.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "immddk.h"

#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(imm);

#include "imm_private.h"

#define	IMM32_CONVERSION_BUFSIZE		200

static CHAR IMM32_szIMEClass[] = "IME";
static CHAR IMM32_szIMEWindowName[] = "Default IME";

typedef struct
{
	HWND	hwndSelf;
	HWND	hwndActive;
	DWORD	dwBufUsed;
	union
	{
		CHAR	A[IMM32_CONVERSION_BUFSIZE];
		WCHAR	W[IMM32_CONVERSION_BUFSIZE];
	}		buf;
} IMM32_IMEWNDPARAM;


static BOOL IMM32_IsUIMessage( UINT nMsg );

static
LRESULT IMM32_IMEWnd_WM_KEYDOWN( IMM32_IMEWNDPARAM* pParam,
				 WPARAM wParam, LPARAM lParam )
{
	BYTE			bKeyState[ 256 ];
	DWORD			dwTransBufSize;
	UINT			nNumOfMsg;
	LRESULT			lr;
	HIMC			hIMC;
	IMM32_IMC*		pIMC;
	const IMM32_IMEKL*	pkl;

	if ( pParam->hwndActive == (HWND)NULL )
		return 0;

	/* get context -> get pkl. */
	hIMC = ImmGetContext( pParam->hwndActive );
	if ( hIMC == NULLIMC )
		return 0;
	pIMC = IMM32_LockIMC( hIMC );
	if ( pIMC == NULL )
	{
		ImmReleaseContext( pParam->hwndActive, hIMC );
		return 0;
	}
	pkl = pIMC->pkl;

	GetKeyboardState( bKeyState );
	if ( !pkl->handlers.pImeProcessKey
		( hIMC, wParam, lParam, bKeyState ) )
	{
		lr = SendMessageA( pParam->hwndActive, WM_IME_KEYDOWN,
				   wParam, lParam );
		goto end;
	}

	dwTransBufSize = 0;
	nNumOfMsg = pkl->handlers.pImeToAsciiEx
		( wParam, (lParam>>16)&0xff, 
		  bKeyState, &dwTransBufSize,
		  0, /* FIXME!!! - 1 if a menu is active */
		  hIMC );

	/* FIXME - process generated messages */
	/* I cannot use ImmGenerateMessage() since
	 * the IME window must handle generated messages. */

	/* NOTE - I must check pkl->fUnicode. */
	FIXME( "%d messages generated.\n", nNumOfMsg );

	lr = 0;
end:
	IMM32_UnlockIMC( hIMC );
	ImmReleaseContext( pParam->hwndActive, hIMC );

	return lr;
}

static
LRESULT IMM32_IMEWnd_WM_KEYUP( IMM32_IMEWNDPARAM* pParam,
			       WPARAM wParam, LPARAM lParam )
{
	BYTE			bKeyState[ 256 ];
	LRESULT			lr;
	HIMC			hIMC;
	IMM32_IMC*		pIMC;
	const IMM32_IMEKL*	pkl;

	if ( pParam->hwndActive == (HWND)NULL )
		return 0;

	/* get context -> get pkl. */
	hIMC = ImmGetContext( pParam->hwndActive );
	if ( hIMC == NULLIMC )
		return 0;
	pIMC = IMM32_LockIMC( hIMC );
	if ( pIMC == NULL )
	{
		ImmReleaseContext( pParam->hwndActive, hIMC );
		return 0;
	}
	pkl = pIMC->pkl;

	GetKeyboardState( bKeyState );
	if ( !pkl->handlers.pImeProcessKey
		( hIMC, wParam, lParam, bKeyState ) )
	{
		lr = SendMessageA( pParam->hwndActive, WM_IME_KEYUP,
				   wParam, lParam );
		goto end;
	}

	lr = 0;
end:
	IMM32_UnlockIMC( hIMC );
	ImmReleaseContext( pParam->hwndActive, hIMC );

	return lr;
}


static
LRESULT CALLBACK IMM32_IMEWndProc( HWND hwnd, UINT nMsg,
				   WPARAM wParam, LPARAM lParam )
{
	IMM32_IMEWNDPARAM* pParam =
		(IMM32_IMEWNDPARAM*)GetWindowLongA( hwnd, 0L );

	if ( nMsg == WM_CREATE )
	{
		pParam = (IMM32_IMEWNDPARAM*)IMM32_HeapAlloc(
				HEAP_ZERO_MEMORY, sizeof(IMM32_IMEWNDPARAM) );
		if ( pParam == NULL )
			return -1L;
		SetWindowLongA( hwnd, 0L, (LONG)pParam );

		/* Initialize pParam. */
		pParam->hwndSelf = hwnd;
		pParam->hwndActive = (HWND)NULL;
		pParam->dwBufUsed = 0;

		return 0;
	}
	else if ( nMsg == WM_DESTROY )
	{
		/* Uninitialize pParam. */

		IMM32_HeapFree( pParam );
		SetWindowLongA( hwnd, 0L, (LONG)NULL );
		return 0;
	}

	if ( pParam == NULL )
	{
		if ( IMM32_IsUIMessage( nMsg ) )
			return 0;
		return DefWindowProcA( hwnd, nMsg, wParam, lParam );
	}

	/* FIXME - handle all messages. */
	/* FIXME - handle all notifications. */
	switch ( nMsg )
	{
	case WM_KEYDOWN:
		return IMM32_IMEWnd_WM_KEYDOWN( pParam, wParam, lParam );
	case WM_KEYUP:
		return IMM32_IMEWnd_WM_KEYUP( pParam, wParam, lParam );
	case WM_IME_KEYDOWN:
		ERR( "Why WM_IME_KEYDOWN is generated?" );
		return 0;
	case WM_IME_KEYUP:
		ERR( "Why WM_IME_KEYUP is generated?" );
		return 0;
	case WM_IME_CHAR:
		FIXME( "ignore WM_IME_CHAR - wParam %08x, lParam %08lx.\n",
		       wParam, lParam );
		return 0;
	case WM_CHAR:
		/* TranslateMessage don't support IME HKL. - FIXME? */
		FIXME( "ignore WM_CHAR - wParam %08x, lParam %08lx.\n",
		       wParam, lParam );
		return 0;
	case WM_IME_CONTROL:
	case WM_IME_REQUEST:
	case WM_IME_STARTCOMPOSITION:
	case WM_IME_ENDCOMPOSITION:
	case WM_IME_COMPOSITION:
	case WM_IME_SETCONTEXT:
	case WM_IME_NOTIFY:
	case WM_IME_COMPOSITIONFULL:
	case WM_IME_SELECT:
	case 0x287: /* What is this message? IMM32.DLL returns TRUE. */
		FIXME( "handle message %08x\n", nMsg );
		return 0;
	}

	return DefWindowProcA( hwnd, nMsg, wParam, lParam );
}


/***********************************************************************
 *		IMM32_RegisterClass (internal)
 */
BOOL IMM32_RegisterIMEWndClass( HINSTANCE hInstDLL )
{
	WNDCLASSA	wc;

	/* SDK says the "IME" window class is a system global class. */
	wc.style		= CS_GLOBALCLASS;
	wc.lpfnWndProc		= IMM32_IMEWndProc;
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= sizeof(LONG);
	wc.hInstance		= hInstDLL;
	wc.hIcon		= (HICON)NULL;
	wc.hCursor		= LoadCursorA((HINSTANCE)NULL,IDC_ARROWA);
	wc.hbrBackground	= (HBRUSH)NULL;
	wc.lpszMenuName		= NULL;
	wc.lpszClassName	= IMM32_szIMEClass;
	if ( !RegisterClassA( &wc ) )
		return FALSE;

	return TRUE;
}

/***********************************************************************
 *		IMM32_UnregisterClass (internal)
 */
void IMM32_UnregisterIMEWndClass( HINSTANCE hInstDLL )
{
	(void)UnregisterClassA( IMM32_szIMEClass, hInstDLL );
}

/***********************************************************************
 *		IMM32_CreateDefaultIMEWnd (internal)
 */

HWND IMM32_CreateDefaultIMEWnd( void )
{
	return CreateWindowExA( 0L,
				IMM32_szIMEClass,
				IMM32_szIMEWindowName,
				WS_POPUP | WS_CLIPSIBLINGS | WS_OVERLAPPED,
				0, 0, 0, 0,
				(HWND)NULL,
				(HMENU)NULL,
				(HINSTANCE)GetModuleHandleA(NULL),
				NULL );
}

static BOOL IMM32_IsUIMessage( UINT nMsg )
{
	switch ( nMsg )
	{
	case WM_IME_STARTCOMPOSITION:
	case WM_IME_ENDCOMPOSITION:
	case WM_IME_COMPOSITION:
	case WM_IME_SETCONTEXT:
	case WM_IME_NOTIFY:
	case WM_IME_COMPOSITIONFULL:
	case WM_IME_SELECT:
	case 0x287: /* What is this message? IMM32.DLL returns TRUE. */
		return TRUE;
	}

	return FALSE;
}


/***********************************************************************
 *		ImmIsUIMessageA (IMM32.@)
 */
BOOL WINAPI ImmIsUIMessageA(
	HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
{
	TRACE("(0x%08x, %d, %d, %ld)\n",
	      hwndIME, msg, wParam, lParam);

	if ( !IMM32_IsUIMessage( msg ) )
		return FALSE;
	if ( hwndIME == (HWND)NULL )
		return TRUE;

	switch ( msg )
	{
	case WM_IME_STARTCOMPOSITION:
	case WM_IME_ENDCOMPOSITION:
	case WM_IME_COMPOSITION:
	case WM_IME_SETCONTEXT:
	case WM_IME_NOTIFY:
	case WM_IME_COMPOSITIONFULL:
	case WM_IME_SELECT:
		SendMessageA( hwndIME, msg, wParam, lParam );
		break;
	case 0x287: /* What is this message? */
		FIXME("(0x%08x, %d, %d, %ld) - unknown message 0x287.\n",
		      hwndIME, msg, wParam, lParam);
		SendMessageA( hwndIME, msg, wParam, lParam );
		break;
	}

	return TRUE;
}

/***********************************************************************
 *		ImmIsUIMessageW (IMM32.@)
 */
BOOL WINAPI ImmIsUIMessageW(
	HWND hwndIME, UINT msg, WPARAM wParam, LPARAM lParam)
{
	TRACE("(0x%08x, %d, %d, %ld)\n",
	      hwndIME, msg, wParam, lParam);

	if ( !IMM32_IsUIMessage( msg ) )
		return FALSE;
	if ( hwndIME == (HWND)NULL )
		return TRUE;

	switch ( msg )
	{
	case WM_IME_STARTCOMPOSITION:
	case WM_IME_ENDCOMPOSITION:
	case WM_IME_COMPOSITION:
	case WM_IME_SETCONTEXT:
	case WM_IME_NOTIFY:
	case WM_IME_COMPOSITIONFULL:
	case WM_IME_SELECT:
		SendMessageW( hwndIME, msg, wParam, lParam );
		break;
	case 0x287: /* What is this message? */
		FIXME("(0x%08x, %d, %d, %ld) - unknown message 0x287.\n",
		      hwndIME, msg, wParam, lParam);
		SendMessageW( hwndIME, msg, wParam, lParam );
		break;
	}

	return TRUE;
}
