/*
 *	Input Method Context
 *
 *	Copyright 2000 Hidenori Takeshima
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

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

#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(imm);

#include "imm_private.h"

static HIMC IMM32_CreateIMC( HKL hkl );
static BOOL IMM32_DestroyIMC( HIMC hIMC );

IMM32_IMC* IMM32_LockIMC( HIMC hIMC )
{
	IMM32_IMC*	pIMC;

	if ( hIMC == NULLIMC )
	{
		SetLastError( ERROR_INVALID_HANDLE );
		return NULL;
	}

	pIMC = (IMM32_IMC*)IMM32_MoveableLock( (IMM32_MOVEABLEMEM*)hIMC );
	if ( !pIMC->fSelected )
	{
		(void)IMM32_MoveableUnlock( (IMM32_MOVEABLEMEM*)hIMC );
		SetLastError( ERROR_ACCESS_DENIED );
		return NULL;
	}

	return pIMC;
}

BOOL IMM32_UnlockIMC( HIMC hIMC )
{
	if ( hIMC == NULLIMC )
	{
		SetLastError( ERROR_INVALID_HANDLE );
		return FALSE;
	}

	return IMM32_MoveableUnlock( (IMM32_MOVEABLEMEM*)hIMC );
}

static HIMC IMM32_CreateIMC( HKL hkl )
{
	IMM32_MOVEABLEMEM*	hIMC;
	IMM32_IMC*		pIMC;
	LPCOMPOSITIONSTRING	lpCompStr;
	LPCANDIDATEINFO		lpCandInfo;
	LPGUIDELINE		lpGuideLine;

	hIMC = IMM32_MoveableAlloc( 0, sizeof( IMM32_IMC ) );
	if ( hIMC == NULL )
	{
		SetLastError( ERROR_OUTOFMEMORY );
		return NULLIMC;
	}

	pIMC = (IMM32_IMC*)IMM32_MoveableLock( hIMC );

	/* Initialize some members of IMC. */
	pIMC->context.hWnd = (HWND)NULL;
	pIMC->context.fOpen = FALSE;
	pIMC->context.hCompStr = (HIMCC)NULL;
	pIMC->context.hCandInfo = (HIMCC)NULL;
	pIMC->context.hGuideLine = (HIMCC)NULL;
	pIMC->context.hPrivate = (HIMCC)NULL;
	pIMC->context.dwNumMsgBuf = 0;
	pIMC->context.hMsgBuf = (HIMCC)NULL;
	pIMC->context.fdwInit = 0;
	pIMC->pkl = NULL;
	pIMC->fSelected = FALSE;

	/* hCompStr, hCandInfo, hGuideLine, hMsgBuf must be allocated. */
	pIMC->context.hCompStr = ImmCreateIMCC( sizeof(COMPOSITIONSTRING) );
	if ( pIMC->context.hCompStr == (HIMCC)NULL )
		goto out_of_memory;
	lpCompStr = (LPCOMPOSITIONSTRING)ImmLockIMCC( pIMC->context.hCompStr );
	if ( lpCompStr == NULL )
		goto out_of_memory;
	lpCompStr->dwSize = sizeof(COMPOSITIONSTRING);
	(void)ImmUnlockIMCC( pIMC->context.hCompStr );

	pIMC->context.hCandInfo = ImmCreateIMCC( sizeof(CANDIDATEINFO) );
	if ( pIMC->context.hCandInfo == (HIMCC)NULL )
		goto out_of_memory;
	lpCandInfo = (LPCANDIDATEINFO)ImmLockIMCC( pIMC->context.hCandInfo );
	if ( lpCandInfo == NULL )
		goto out_of_memory;
	lpCandInfo->dwSize = sizeof(CANDIDATEINFO);
	(void)ImmUnlockIMCC( pIMC->context.hCandInfo );

	pIMC->context.hGuideLine = ImmCreateIMCC( sizeof(GUIDELINE) );
	if ( pIMC->context.hGuideLine == (HIMCC)NULL )
		goto out_of_memory;
	lpGuideLine = (LPGUIDELINE)ImmLockIMCC( pIMC->context.hGuideLine );
	if ( lpGuideLine == NULL )
		goto out_of_memory;
	lpGuideLine->dwSize = sizeof(GUIDELINE);
	(void)ImmUnlockIMCC( pIMC->context.hGuideLine );

	pIMC->context.hMsgBuf = ImmCreateIMCC( 0 );
	if ( pIMC->context.hMsgBuf == (HIMCC)NULL )
		goto out_of_memory;

	pIMC->pkl = IMM32_GetIME( hkl );
	if ( pIMC->pkl != NULL )
	{
		/* The current HKL is IME.
		 * Initialize IME's private context.
		 */
		if ( pIMC->pkl->imeinfo.dwPrivateDataSize > 0 )
		{
			pIMC->context.hPrivate = ImmCreateIMCC(
				pIMC->pkl->imeinfo.dwPrivateDataSize );
			if ( pIMC->context.hPrivate == (HIMCC)NULL )
				goto out_of_memory;
		}

		pIMC->fSelected = TRUE;
		if ( !pIMC->pkl->handlers.pImeSelect( (HIMC)hIMC, TRUE ) )
		{
			pIMC->fSelected = FALSE;
			goto out_of_memory;
		}
	}

	(void)IMM32_MoveableUnlock( hIMC );

	return (HIMC)hIMC;

out_of_memory:
	(void)IMM32_DestroyIMC( (HIMC)hIMC );
	SetLastError( ERROR_OUTOFMEMORY );
	return NULLIMC;
}

static BOOL IMM32_DestroyIMC( HIMC hIMC )
{
	IMM32_IMC*		pIMC;

	if ( hIMC == NULLIMC )
	{
		SetLastError( ERROR_INVALID_HANDLE );
		return FALSE;
	}

	pIMC = (IMM32_IMC*)IMM32_MoveableLock( (IMM32_MOVEABLEMEM*)hIMC );

	if ( pIMC->context.hWnd != (HWND)NULL )
	{
		FIXME( "please release lock of the context.hWnd!\n" );
	}

	if ( pIMC->fSelected )
	{
		(void)pIMC->pkl->handlers.pImeSelect( hIMC, FALSE );
		pIMC->fSelected = FALSE;
	}

	if ( pIMC->context.hCompStr != (HIMCC)NULL )
		(void)ImmDestroyIMCC(pIMC->context.hCompStr);
	if ( pIMC->context.hCandInfo != (HIMCC)NULL )
		(void)ImmDestroyIMCC(pIMC->context.hCandInfo);
	if ( pIMC->context.hGuideLine != (HIMCC)NULL )
		(void)ImmDestroyIMCC(pIMC->context.hGuideLine);
	if ( pIMC->context.hPrivate != (HIMCC)NULL )
		(void)ImmDestroyIMCC(pIMC->context.hPrivate);
	if ( pIMC->context.hMsgBuf != (HIMCC)NULL )
		(void)ImmDestroyIMCC(pIMC->context.hMsgBuf);

	IMM32_MoveableFree( (IMM32_MOVEABLEMEM*)hIMC );

	return TRUE;
}





/***********************************************************************
 *		ImmCreateContext (IMM32.@)
 */
HIMC WINAPI ImmCreateContext( void )
{
	TRACE("()\n");

	return IMM32_CreateIMC( GetKeyboardLayout(0) );
}

/***********************************************************************
 *		ImmDestroyContext (IMM32.@)
 */
BOOL WINAPI ImmDestroyContext( HIMC hIMC )
{
	TRACE("(0x%08x)\n",hIMC);

	return IMM32_DestroyIMC( hIMC );
}

/***********************************************************************
 *		ImmLockIMC (IMM32.@)
 */
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
{
	IMM32_IMC*	pIMC;

	TRACE("(0x%08x)\n", (unsigned)hIMC);

	pIMC = IMM32_LockIMC( hIMC );
	if ( pIMC == NULL )
		return NULL;
	return &(pIMC->context);
}

/***********************************************************************
 *		ImmUnlockIMC (IMM32.@)
 */
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
{
	TRACE("(0x%08x)\n", (unsigned)hIMC);

	return IMM32_UnlockIMC( hIMC );
}

/***********************************************************************
 *		ImmGetIMCLockCount (IMM32.@)
 */
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
{
	TRACE("(0x%08x)\n", (unsigned)hIMC);

	if ( hIMC == NULLIMC )
	{
		SetLastError( ERROR_INVALID_HANDLE );
		return 0;
	}

	return IMM32_MoveableGetLockCount( (IMM32_MOVEABLEMEM*)hIMC );
}


