/* # skkinput (Simple Kana-Kanji Input)
 *
 * This file is part of skkinput.
 * Copyright (C) 2002
 * Takashi SAKAMOTO (PXG01715@nifty.ne.jp)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with skkinput; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <X11/Xlib.h>
#include "commondef.h"
#include "XIMInputMethodP.h"
#include "protocol.h"
#include "kanji.h"
#include "attrs.h"

static	XIMInputStyle	srSupportedStyles []	= {
	{	XIMPreeditPosition  | XIMStatusNothing,		CONVERSION_NYUURYOKU_HOUSHIKI_OVERTHESPOT, },
	{	XIMPreeditPosition  | XIMStatusArea,		CONVERSION_NYUURYOKU_HOUSHIKI_OVERTHESPOT, },
	{	XIMPreeditArea      | XIMStatusArea,		CONVERSION_NYUURYOKU_HOUSHIKI_OFFTHESPOT, },
	{	XIMPreeditNothing   | XIMStatusNothing,		CONVERSION_NYUURYOKU_HOUSHIKI_SEPARATEMADO, },
	/*	sorry, currently not supported. */
	{	XIMPreeditCallbacks | XIMStatusCallbacks,	CONVERSION_NYUURYOKU_HOUSHIKI_ONTHESPOT, },
	{	XIMPreeditCallbacks | XIMStatusNothing,		CONVERSION_NYUURYOKU_HOUSHIKI_ONTHESPOT, },
} ;

XIMInputMethod*
XIMInputMethod_Create (
	register Widget		gw,
	register int		nID)
{
	register XIMInputMethod*	pInputMethod ;

	pInputMethod	= malloc (sizeof (XIMInputMethod)) ;

	pInputMethod->m_wgClient		= gw ;
	pInputMethod->m_woID			= nID ;
	pInputMethod->m_woICID			= 1 ;
	pInputMethod->m_woExtensionMask	= 0 ;
	pInputMethod->m_lstInputContext	= NULL ;
	return	pInputMethod ;
}

void
XIMInputMethod_Destroy (
	register XIMInputMethod*	pInputMethod)
{
	register XIMInputContext*	pNode ;
	register XIMInputContext*	pNextNode ;

	/*	InputContext を全部破棄する。*/
	assert (pInputMethod != NULL) ;
	pNode	= pInputMethod->m_lstInputContext ;
	while (pNode != NULL) {
		pNextNode	= XIMInputContext_GetNext (pNode) ;
		XIMInputContext_Destroy (pNode) ;
		pNode		= pNextNode ;
	}
	free (pInputMethod) ;
	return ;
}

int
XIMInputMethod_GetID (
	register XIMInputMethod*	pInputMethod)
{
	assert (pInputMethod != NULL) ;
	return	pInputMethod->m_woID ;
}

Widget
XIMInputMethod_GetClient (
	register XIMInputMethod*	pInputMethod)
{
	assert (pInputMethod != NULL) ;
	return	pInputMethod->m_wgClient ;
}

XIMInputContext*
XIMInputMethod_CreateInputContext (
	register XIMInputMethod*	pInputMethod)
{
	XIMInputContext*	pInputContext ;

	assert (pInputMethod != NULL) ;
	pInputContext	= XIMInputContext_Create (pInputMethod, pInputMethod->m_woICID) ;
	if (pInputContext == NULL)
		return	NULL ;
	pInputMethod->m_woICID	++ ;

	XIMInputContext_SetNext (pInputContext, pInputMethod->m_lstInputContext) ;
	pInputMethod->m_lstInputContext	= pInputContext ;
	return	pInputContext ;
}

void
XIMInputMethod_DestroyInputContext (
	register XIMInputMethod*	pInputMethod,
	register XIMInputContext*	pInputContext)
{
	register XIMInputContext*	pNode ;
	register XIMInputContext*	pPrevNode ;
	
	assert (pInputMethod != NULL) ;
	pNode		= pInputMethod->m_lstInputContext ;
	pPrevNode	= NULL ;
	while (pNode != NULL) {
		if (pNode == pInputContext) {
			register XIMInputContext*	pNextNode ;

			if (pPrevNode == NULL) {
				pNextNode	= XIMInputContext_GetNext (pNode) ;
				pInputMethod->m_lstInputContext	= pNextNode ;
			} else {
				pNextNode	= XIMInputContext_GetNext (pNode) ;
				XIMInputContext_SetNext (pPrevNode, pNextNode) ;
			}
			XIMInputContext_Destroy (pInputContext) ;
			return ;
		}
		pPrevNode	= pNode ;
		pNode		= XIMInputContext_GetNext (pPrevNode) ;
	}
	return ;
}

XIMInputContext*
XIMInputMethod_FindInputContext (
	register XIMInputMethod*	pInputMethod,
	register int				nID)
{
	register XIMInputContext*	pNode ;

	assert (pInputMethod != NULL) ;
	pNode	= pInputMethod->m_lstInputContext ;
	while (pNode != NULL) {
		if (XIMInputContext_GetID (pNode) == nID)
			return	pNode ;
		pNode	= XIMInputContext_GetNext (pNode) ;
	}
	return	NULL ;
}

int
XIMInputMethod_GetQueryInputStyle (
	register XIMInputMethod*		pInputMethod,
	register const XIMInputStyle**	ppSupportedStyle)
{
	assert (pInputMethod != NULL) ;
	if (ppSupportedStyle != NULL)
		*ppSupportedStyle	= srSupportedStyles ;
	return	sizeof (srSupportedStyles) / sizeof (srSupportedStyles [0]) ;
}

CARD16
XIMInputMethod_GetExtMask (
	register XIMInputMethod*			pInputMethod)
{
	assert (pInputMethod != NULL) ;
	return	pInputMethod->m_woExtensionMask ;
}

Boolean
XIMInputMethod_SetExtMask (
	register XIMInputMethod*			pInputMethod,
	register CARD16						woMask)
{
	assert (pInputMethod != NULL) ;
	pInputMethod->m_woExtensionMask	= woMask ;
	return	True ;
}

void
XIMInputMethod_SetNext (
	register XIMInputMethod*			pInputMethod,
	register XIMInputMethod*			pNextInputMethod)
{
	assert (pInputMethod != NULL) ;
	pInputMethod->m_pNext	= pNextInputMethod ;
	return ;
}

XIMInputMethod*
XIMInputMethod_GetNext (
	register XIMInputMethod*			pInputMethod)
{
	assert (pInputMethod != NULL) ;
	return	pInputMethod->m_pNext ;
}





