
/* 	
			UNICON PROJECT

   		    Copyright (C) 1999 TLDN
	
   Authors:	Li Qi Chen <chrisl@turbolinux.com.cn>
		Arthur Ma  <arthur.ma@turbolinux.com.cn>
		Justin Yu  <justiny@turbolinux.com.cn>

   Homepage:    http://turbolinux.com.cn/TLDN/chinese/project/unicon/index.html
   Mailinglist: unicon@turbolinux.com.cn 	
   Download:    http://turbolinux.com.cn/TLDN/chinese/project/unicon/download.html

   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 this program; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

/* Imm Standard Interfaces */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <iconv.h>
#include <langinfo.h>
#include <locale.h>
#include <errno.h>
#include <ImmModule.h>
#include "xl_hzinput.h"
//#include "HL_Debug.h"

#define CODING_SINGLE_BYTE	0x01
#define CODING_DOUBLE_BYTES	0x02
#define CODING_FOUR_BYTES	0x04


hz_input_table *IntCode_Init(void)
{
	hz_input_table *table;
	int i,index,cnt;

	table = malloc(sizeof(hz_input_table));
	if (table == NULL)
		return NULL;

	strcpy(table->magic_number,MAGIC_NUMBER);
	strcpy(table->ename, "IntCode");
	strcpy(table->cname, "¡¾ÄÚÂë¡¿");
	strcpy(table->selkey, "0123456789");

	table->last_full = 1;
	for(i = 0; i < 128; i++)
	{
		table->KeyMap[i] = 0;
		if ((i >= '0' && i <= '9') || (i >= 'a' && i <= 'f'))
		{
			// Convert '0' -> 0, 'f' -> 16
			if (i >= '0' && i <= '9')
				index = i - '0';
			else
				index = i -'a' + 10;
			
			table->KeyMap[i] = index;
			table->KeyName[index] = toupper(i);
		}
	}    
	return table;
}

int ConfigureInputArea (HzInputTable_T * pHzInputTable, int nSelectionLen)
{
	pHzInputTable->MaxSelectLen = nSelectionLen;
	return 1;
}

int gb18030_valid (const char *strToVerify, int len)
{
	if ((unsigned char)strToVerify[0] < 0x81 || (unsigned char)strToVerify[0] > 0xFE)
		return 0;

	if ( (len == 2)
			&& ((unsigned char)strToVerify[1] >= 0x40 && (unsigned char)strToVerify[1] <= 0xFE)
			&& ((unsigned char)strToVerify[1] != 0x7F) )
		return 1;
	else
		return 0;

	if ( (len == 4)
			&& ((unsigned char)strToVerify[1] >= 0x30 && (unsigned char)strToVerify[1] <= 0x39)
			&& ((unsigned char)strToVerify[2] >= 0x81 && (unsigned char)strToVerify[2] <= 0xFE)
			&& ((unsigned char)strToVerify[3] >= 0x30 && (unsigned char)strToVerify[3] <= 0x39) )
		return 1;
	else
		return 0;
}

void ResetInput(HzInputTable_T * pHzInputTable)
{
	// Stroke input from user, and table for selection, 2D array of char
	bzero (pHzInputTable->InpKey, sizeof(pHzInputTable->InpKey));
	bzero (pHzInputTable->seltab, sizeof(pHzInputTable->seltab));

	pHzInputTable->MultiPageMode = 0;
	pHzInputTable->NextPageIndex = 0;
	pHzInputTable->CurrentPageIndex = 0;
	pHzInputTable->CurSelNum = 0;
	pHzInputTable->InputCount = 0;
	pHzInputTable->InputMatch = 0;
	pHzInputTable->val1 = 0;
}

void ClearSelection(HzInputTable_T * pHzInputTable)
{
	pHzInputTable->MultiPageMode = 0;
	pHzInputTable->NextPageIndex = 0;
	pHzInputTable->CurrentPageIndex = 0;
	pHzInputTable->CurSelNum = 0;
}

void IntCode_FindMatchKey(HzInputTable_T *pHzInputTable)
{
	unsigned long Key;

	// check the user have a valid input. The previous input must be invalid. Don't generate select menu.
	if ( (pHzInputTable->InpKey[0] < 8)
			|| (pHzInputTable->InpKey[2] < 3) )
	{
		pHzInputTable->StartKey = pHzInputTable->EndKey = 0;
		return;
	}
	if ( (pHzInputTable->val1 == CODING_FOUR_BYTES)
			&& ( (pHzInputTable->InpKey[4] < 8)
				|| (pHzInputTable->InpKey[6] != 3)
				|| (pHzInputTable->InpKey[2] != 3) ) )
	{
		pHzInputTable->StartKey = pHzInputTable->EndKey = 0;
		return;
	}

	if (pHzInputTable->val1 == CODING_FOUR_BYTES)
		Key = (pHzInputTable->InpKey[0] << 28)
			| (pHzInputTable->InpKey[1] << 24)
			| (pHzInputTable->InpKey[2] << 20)
			| (pHzInputTable->InpKey[3] << 16)
			| (pHzInputTable->InpKey[4] << 12)
			| (pHzInputTable->InpKey[5] << 8)
			| (pHzInputTable->InpKey[6] << 4);
#if 0
			| (pHzInputTable->InpKey[5] << 8);
#endif
	else 
		Key = (pHzInputTable->InpKey[0] << 12)
			| (pHzInputTable->InpKey[1] << 8)
			| (pHzInputTable->InpKey[2] << 4);
#if 0
			| (pHzInputTable->InpKey[1] << 8);
#endif
	
	switch(pHzInputTable->InputCount)
	{
#if 0
		case 3:
			if (pHzInputTable->val1 == CODING_DOUBLE_BYTES)
			{
				pHzInputTable->StartKey = Key + (pHzInputTable->InpKey[2] << 4);
				pHzInputTable->EndKey = pHzInputTable->StartKey + 0x0F; 
			}
			else
				/* not display selection */
				pHzInputTable->StartKey = pHzInputTable->EndKey = 0;   
				break;
			
		case 6:
			pHzInputTable->StartKey = Key + 0x30;
			pHzInputTable->EndKey = Key + 0x39;
			break;
#endif
		case 3:
			if (pHzInputTable->val1 == CODING_DOUBLE_BYTES)
			{
				pHzInputTable->StartKey = Key;
				if (pHzInputTable->InpKey[2] == 7 || pHzInputTable->InpKey[2] == 15)
					pHzInputTable->EndKey = Key + 0x0E; 
				else
					pHzInputTable->EndKey = Key + 0x0F; 
			}
		case 7:
			pHzInputTable->StartKey = Key;
			pHzInputTable->EndKey = Key + 0x09;
			break;
		default:
			pHzInputTable->StartKey = pHzInputTable->EndKey = 0;
	}
}

void IntCode_FillMatchChars(HzInputTable_T *pHzInputTable, int index)
{
	int MaxSel = 10, i;

	int CurSelNum = 0;
	if (pHzInputTable->InputCount != 3 && pHzInputTable->InputCount !=7)
		return;
	if (pHzInputTable->InputCount == 7)
	{
		while( CurSelNum < MaxSel && index <= pHzInputTable->EndKey)
		{
			pHzInputTable->seltab[CurSelNum][0] = (char)((index & 0xFF000000) >> 24); 
			pHzInputTable->seltab[CurSelNum][1] = (char)((index & 0x00FF0000) >> 16);
			pHzInputTable->seltab[CurSelNum][2] = (char)((index & 0x0000FF00) >> 8);
			pHzInputTable->seltab[CurSelNum][3] = (char)((index & 0x000000FF));
			pHzInputTable->seltab[CurSelNum][4] = '\0';
			CurSelNum++;
			index++;
		}

	}
	else
	{
		while( CurSelNum < MaxSel && index <= pHzInputTable->EndKey)
		{
			pHzInputTable->seltab[CurSelNum][0] = (char)((index & 0x0000FF00) >> 8); 
			pHzInputTable->seltab[CurSelNum][1] = (char)((index & 0x000000FF));
//			pHzInputTable->seltab[CurSelNum][0] = index / 256; 
//			pHzInputTable->seltab[CurSelNum][1] = index % 256;
			pHzInputTable->seltab[CurSelNum][2] = '\0';
			CurSelNum++;
			index++;
		}
	}
    
	pHzInputTable->CurSelNum = CurSelNum;
	for(i = CurSelNum; i < 16; i++)
		/* zero out the unused area */
		pHzInputTable->seltab[i][0] = '\0';

	pHzInputTable->InputMatch = pHzInputTable->InputCount;

	if ( index <= pHzInputTable->EndKey && CurSelNum == MaxSel && MaxSel == 10)
	{
		/* has another matched key, so enter MultiPageMode, has more pages */
		pHzInputTable->NextPageIndex = index;
		pHzInputTable->MultiPageMode = 1;
	}  
	else if (pHzInputTable->MultiPageMode)
	{
		/* rotate selection */
		pHzInputTable->NextPageIndex = pHzInputTable->StartKey;
	}
	else pHzInputTable->MultiPageMode = 0;
}

int Intcode_HZFilter (HzInputTable_T *pHzInputTable,
		unsigned char key, char *buff, int *len)
{
	int inkey = 0;
	int nSelIndex = 0;
	char *pSelChar = NULL;
 
	// printf ("In Intcode_HZFilter................\n");
	switch ( key )
	{
		case '\010':  /* BackSpace Ctrl+H */
		case '\177':  /* BackSpace */
#if 0
			if (pHzInputTable->InputCount > 0) 
			{
				pHzInputTable->InpKey[--pHzInputTable->InputCount]=0;

				if (pHzInputTable->InputCount == 2)
				{
					pHzInputTable->val1 = 0;
					ClearSelection(pHzInputTable);
				}	

				if (pHzInputTable->InputCount == 0)
					ResetInput(pHzInputTable);
				else if (pHzInputTable->InputCount > 2)
				{
					IntCode_FindMatchKey(pHzInputTable);
					pHzInputTable->MultiPageMode = 0;
					pHzInputTable->CurrentPageIndex = pHzInputTable->StartKey;
					IntCode_FillMatchChars(pHzInputTable, pHzInputTable->StartKey); 
				}
			}
			else return 0;
#endif
			if (pHzInputTable->InputCount > 0) 
			{
				if (pHzInputTable->InputCount == 3
						|| pHzInputTable->InputCount == 7)
					ClearSelection(pHzInputTable);
				pHzInputTable->InputCount--;
				return 1;
			}
			else return 0;
			break;

		case '\033':  /* ESCAPE */
			if (pHzInputTable->InputCount > 0) 
				ResetInput(pHzInputTable);
			else return 0;
			break;

		case '-':
		case ',':
			if ( pHzInputTable->MultiPageMode )
			{
			   if ( pHzInputTable->CurrentPageIndex > pHzInputTable->StartKey) 
					pHzInputTable->CurrentPageIndex = pHzInputTable->CurrentPageIndex - 10;
			   else pHzInputTable->CurrentPageIndex = pHzInputTable->StartKey;
			   
			   IntCode_FillMatchChars(pHzInputTable, pHzInputTable->CurrentPageIndex);
			}
			else return 0;
			break;

		case '.':
		case '=':
			if ( pHzInputTable->MultiPageMode )
			{
			   pHzInputTable->CurrentPageIndex = pHzInputTable->NextPageIndex;
			   IntCode_FillMatchChars(pHzInputTable, pHzInputTable->CurrentPageIndex);
			}
			else return 0;
			break;

		case ' ':
			if (pHzInputTable->CurSelNum == 0 )
			   return 0;
			if ( pHzInputTable->seltab[0][0] )
			{
				strcpy(buff, pHzInputTable->seltab[0]);
				*len = strlen(buff);
				ResetInput(pHzInputTable);
				return 2;
			}   
			break;

		default:
			inkey = pHzInputTable->cur_table->KeyMap[key];
			pSelChar = strchr(pHzInputTable->cur_table->selkey, key);
			nSelIndex = pSelChar - pHzInputTable->cur_table->selkey;
			
			if (pSelChar && pHzInputTable->CurSelNum > 0
					&& pHzInputTable->seltab[nSelIndex][0])
			{
				strcpy(buff, pHzInputTable->seltab[nSelIndex]);
				*len = strlen(buff);
				ResetInput(pHzInputTable);
				return 2;
			}
//			printf("nSelIndex = %d inkey = %d, InputCount = %d, key = %c, Coding = %ld\n",
//			nSelIndex, inkey,pHzInputTable->InputCount, key, pHzInputTable->val1);
			switch(pHzInputTable->InputCount % 4)
			{
				case 0:  /* 8-F */
					if (inkey < 8)
					{
						//pHzInputTable->val1 = CODING_SINGLE_BYTE;
						return 0;	
					}	
					else 
					{
#if 0
						if ((pHzInputTable->val1 & CODING_FOUR_BYTES)
							&& (pHzInputTable->InputCount == 4)
							&& (pHzInputTable->InpKey[pHzInputTable->InputCount - 4] == 8)
							&& (pHzInputTable->InpKey[pHzInputTable->InputCount - 3] == 4)
							&& (pHzInputTable->InpKey[pHzInputTable->InputCount - 2] == 3)
							&& (pHzInputTable->InpKey[pHzInputTable->InputCount - 1] == 1)
							&& (inkey > 9))
						{
							return 0;
						}
						else
						{
						    pHzInputTable->InpKey[pHzInputTable->InputCount++] = inkey;
						}
#endif
						pHzInputTable->InpKey[pHzInputTable->InputCount++] = inkey;
					}	
					break;
				
				case 1:
					// 0-F
					// 0x80 or 0xFF is invalid, so only 0x81 ~ 0xFE
#if 0
					if (((pHzInputTable->InpKey[pHzInputTable->InputCount - 1] == 8) && (inkey == 0)) || 
					    ((pHzInputTable->InpKey[pHzInputTable->InputCount - 1] == 15) && (inkey == 15))) 
					{
						return 0;
					}
					else
					{
						pHzInputTable->InpKey[pHzInputTable->InputCount++] = inkey;
						
						if (pHzInputTable->InputCount == 6)
						{
							IntCode_FindMatchKey(pHzInputTable);
							pHzInputTable->MultiPageMode = 0;
							pHzInputTable->CurrentPageIndex = pHzInputTable->StartKey;
							IntCode_FillMatchChars(pHzInputTable, pHzInputTable->StartKey);
							pHzInputTable->InpKey[pHzInputTable->InputCount++] = 3;
						}
					}
#endif
					pHzInputTable->InpKey[pHzInputTable->InputCount++] = inkey;
					break;

				case 2:  /* A-F */
#if 0
					if (inkey < 3)
					{
						return 0;
					}
#endif

					printf ("This is third char.\n");
					if (inkey == 3)
					{
						// Right, the send byte starting with 3 must be Four byte.
						// In order words, the current case is First Byte: (0x81 ~ 0xFE) Second Byte: (0x3?)
						pHzInputTable->val1 = CODING_FOUR_BYTES;
						pHzInputTable->InpKey[pHzInputTable->InputCount++] = inkey;
						ClearSelection(pHzInputTable);
						if (pHzInputTable->InputCount == 7)
						{
							IntCode_FindMatchKey(pHzInputTable);
							pHzInputTable->MultiPageMode = 0;
							pHzInputTable->CurrentPageIndex = pHzInputTable->StartKey;
							IntCode_FillMatchChars(pHzInputTable, pHzInputTable->StartKey);
						}
#if 0
						if (pHzInputTable->InputCount < 4)
						{
							if ((pHzInputTable->InpKey[pHzInputTable->InputCount - 2] == 8)
									&& (pHzInputTable->InpKey[pHzInputTable->InputCount - 1] <= 4)
									&& (pHzInputTable->InpKey[pHzInputTable->InputCount - 1] >= 1))
							{
								pHzInputTable->val1 = CODING_FOUR_BYTES;
								ClearSelection(pHzInputTable);
								pHzInputTable->InpKey[pHzInputTable->InputCount++] = inkey;
							}
							else
							{
								return 0;
							}
						pHzInputTable->val1 = CODING_FOUR_BYTES;
						ClearSelection(pHzInputTable);
						pHzInputTable->InpKey[pHzInputTable->InputCount++] = inkey;
						}
						else
						{
							pHzInputTable->val1 = CODING_FOUR_BYTES;
							ClearSelection(pHzInputTable);
							pHzInputTable->InpKey[pHzInputTable->InputCount++] = inkey;
						}
#endif
					}
					else
					{
						pHzInputTable->val1 = CODING_DOUBLE_BYTES;
						pHzInputTable->InpKey[pHzInputTable->InputCount++] = inkey;
						IntCode_FindMatchKey(pHzInputTable);
						pHzInputTable->MultiPageMode = 0;
						pHzInputTable->CurrentPageIndex = pHzInputTable->StartKey;
						IntCode_FillMatchChars(pHzInputTable, pHzInputTable->StartKey);
					}
					break;
				case 3:   /* output char */
						  /* A1A1-FEFE */
#if 0
					if (((pHzInputTable->InpKey[pHzInputTable->InputCount - 1] == 7) && (inkey == 15))
							|| ((pHzInputTable->InpKey[pHzInputTable->InputCount - 1] == 15) && (inkey == 15))
							|| ((pHzInputTable->InpKey[pHzInputTable->InputCount - 1] == 3) && (inkey > 9)))
					//0x7F or 0xFF or 3A-3F is invalid
					{
						return 0;
					}
					else
#endif
					{
						if (pHzInputTable->val1 & CODING_DOUBLE_BYTES)
						{
							pHzInputTable->seltab[0][0] = (pHzInputTable->InpKey[0] << 4) | pHzInputTable->InpKey[1];
							pHzInputTable->seltab[0][1] = (pHzInputTable->InpKey[2] << 4) | inkey ;
							pHzInputTable->seltab[0][2] = '\0';
							//DebugLog("double bytes %s\n", seltab[0]);
							if (gb18030_valid (pHzInputTable->seltab[0], 2))
							{
								strcpy(buff, pHzInputTable->seltab[0]);
								*len = strlen(buff);
								ResetInput(pHzInputTable);
								return 2;
							}
							else
							{
								ResetInput (pHzInputTable);
								return 0;
							}
						}
#if 0
						if ((pHzInputTable->val1 & CODING_FOUR_BYTES)
								&& (pHzInputTable->InputCount == 3)
								&& (pHzInputTable->InpKey[pHzInputTable->InputCount - 2] == 4)
								&& (inkey > 1))
						{
							return 0;                                 
						}
#endif
						if ((pHzInputTable->val1 & CODING_FOUR_BYTES)
								&& (pHzInputTable->InputCount == 7))
						{
							pHzInputTable->seltab[0][0] = (pHzInputTable->InpKey[0] << 4) | pHzInputTable->InpKey[1];
							pHzInputTable->seltab[0][1] = (pHzInputTable->InpKey[2] << 4) | pHzInputTable->InpKey[3];
							pHzInputTable->seltab[0][2] = (pHzInputTable->InpKey[4] << 4) | pHzInputTable->InpKey[5];
							pHzInputTable->seltab[0][3] = (pHzInputTable->InpKey[6] << 4) | inkey;
							pHzInputTable->seltab[0][4] = '\0';
							//write(tty_fd, seltab[0], 4);
							if (gb18030_valid (pHzInputTable->seltab[0], 4))
							{
								strcpy(buff, pHzInputTable->seltab[0]);
								*len = strlen(buff);
								ResetInput(pHzInputTable);
								return 2;
							}
							else
							{
								ResetInput (pHzInputTable);
								return 0;
							}
						}
       					pHzInputTable->InpKey[pHzInputTable->InputCount++] = inkey;
					}
					break;
			}
	} /* switch */
	return 1;
}

int GetSelectDisplay (HzInputTable_T * pHzInputTable, char *strBuf, int nBufLen)
{
	int i, pos = 0,len;
	int buflen;
	char *in,*out;
	iconv_t cd;
	wchar_t result[1];

	/* not first page */
	if (pHzInputTable->MultiPageMode
			&& pHzInputTable->CurrentPageIndex != pHzInputTable->StartKey)
	{
		strcpy(strBuf + pos, "< ");    
		pos += 2;
	}

	//printf ("GetSelectDisplay: nl_langinfo = %s\n", nl_langinfo (CODESET));
	cd = iconv_open ("ucs-2", nl_langinfo(CODESET));
	for (i = 0; i < pHzInputTable->CurSelNum; i++)
	{
		if (!pHzInputTable->seltab[i][0])
			break;

		len = strlen (pHzInputTable->seltab[i]);
		in = (char *)pHzInputTable->seltab[i];
		out = (char *)result;
		buflen = len;

		if (iconv(cd,&in,&buflen,&out,&buflen) == -1)
		{
			pHzInputTable->seltab[i][0] = 0xa1;
			pHzInputTable->seltab[i][1] = 0xa1;
			pHzInputTable->seltab[i][2] = 0x0;
			pHzInputTable->seltab[i][3] = 0x0;
			len = 2;
		}

		if (pos + len + 3 > nBufLen)
			break;
		sprintf(strBuf + pos, "%d%s ", i, pHzInputTable->seltab[i]);
		pos += len + 2; 
//		printf("<%d> %#lx\n",i, *(long*)pHzInputTable->seltab[i]);
	}

	/* not last page */
	if (pHzInputTable->MultiPageMode
			&& pHzInputTable->NextPageIndex != pHzInputTable->StartKey)
	{
		strcpy(strBuf + pos, "> ");
		pos += 2;
	}
	strBuf[pos] = '\0';
	bzero (strBuf, nBufLen);
	return pHzInputTable->CurSelNum ? 1 : 0;
}

int GetInputDisplay (HzInputTable_T * pHzInputTable, char *buf)
{
	int i;

	for (i = 0; i < pHzInputTable->InputCount ; i++)
		sprintf (buf + i, "%c",
				pHzInputTable->cur_table->KeyName[pHzInputTable->InpKey[i]]);

	buf[pHzInputTable->InputCount] = '\0';	
	return pHzInputTable->InputCount ? 1: 0; 
}

/* ********************** Now the interface functions *********************** */
static IMM_CLIENT *IMM_open (char *szFileName, long type)
{
	HzInputTable_T *pHzInputTable_T;
	IMM_CLIENT *pIMM_CLIENT;
	hz_input_table *phz_input_table;

	phz_input_table = IntCode_Init();
	if (phz_input_table == NULL)
		return NULL;

	pHzInputTable_T = (HzInputTable_T *) malloc (sizeof (HzInputTable_T));
	if (pHzInputTable_T == NULL)
	{
		free (phz_input_table);
		return NULL;
	}

	pIMM_CLIENT = (IMM_CLIENT *) malloc (sizeof (IMM_CLIENT));
	if (pIMM_CLIENT == NULL)
	{
		free (pHzInputTable_T);
		free (phz_input_table);
		return NULL;
	}

	ResetInput(pHzInputTable_T);
	ConfigureInputArea(pHzInputTable_T, 48);	
//	SetPhraseBuffer (&pIMM_CLIENT->m, pIMM_CLIENT->buf, sizeof (pIMM_CLIENT->buf));
	pIMM_CLIENT->pImmClientData = (void *) pHzInputTable_T;
	pHzInputTable_T->cur_table = phz_input_table;
	return pIMM_CLIENT;
}

static int IMM_save (IMM_CLIENT *p, char *szFileName)
{
	return 1;
}

static int IMM_close (IMM_CLIENT *p)
{
	HzInputTable_T *pClient = (HzInputTable_T *) p->pImmClientData; 
	free (pClient->cur_table);
	free (p->pImmClientData);
	free (p);
	return 1;
}

/* Indepent Modules support */
static int IMM_KeyFilter (IMM_CLIENT *p, u_char key, char *buf, int *len)
{
	buf[0] = '\0';
	*len = 0;
	return Intcode_HZFilter ((HzInputTable_T *) p->pImmClientData, key, buf, len);
}

/* Input Area Configuration & Operation */
static int IMM_ConfigInputArea (IMM_CLIENT *p, int SelectionLen)
{
	return ConfigureInputArea ((HzInputTable_T *) p->pImmClientData, SelectionLen);
}

// Check about overflow 'buf'
static int IMM_GetInputDisplay (IMM_CLIENT *p, char *buf, long buflen)
{
	return GetInputDisplay((HzInputTable_T *) p->pImmClientData, buf);
}

static int IMM_GetSelectDisplay (IMM_CLIENT *p, char *buf, long buflen)
{
	return GetSelectDisplay((HzInputTable_T *) p->pImmClientData, buf, buflen);
}

int IMM_ResetInput (IMM_CLIENT *p)
{
	//char buf[32];
	//int len;
	/* Send Esc */
	ResetInput ((HzInputTable_T *) p->pImmClientData);
	return 1;
}

PhraseItem * IMM_pGetItem (IMM_CLIENT *p, u_long n)
{
	return NULL;
}

/* Phrase Operation */
static int IMM_AddPhrase (IMM_CLIENT *pClient, PhraseItem *p)
{
	return 1;
}

static int IMM_ModifyPhraseItem (IMM_CLIENT *p, long n, PhraseItem *pItem)
{
	return 1;
}

static int IMM_Flush ()
{
	return 1;
}

#ifdef  __cplusplus
extern "C" 
#endif
struct ImmOperation ImmOp_Ptr = {
	"ÄÚÂë", 
	"HCON Chinese Input Version 3.0",
	"Author:Dianzhi Wang",
	IMM_CCE | IMM_LC_GB2312 << 24,
	IMM_open,
	IMM_save,
	IMM_close,

	/* Indepent Modules support */
	IMM_KeyFilter,
	IMM_ResetInput,

	/* Input Area Configuration & Operation */
	IMM_ConfigInputArea,
	IMM_GetInputDisplay,
	IMM_GetSelectDisplay,
	IMM_pGetItem,
	IMM_AddPhrase,
	IMM_ModifyPhraseItem,
	IMM_Flush,
};

#ifdef __CCE_HZINPUT_DEBUG__
int test (long a, PhraseItem *p)
{
	printf ("%s\n", p->szPhrase);
	return 1;
}

/* gcc -g -I../include -I. -D__CCE_HZINPUT_DEBUG__ xl_hzinput.c CCE_hzinput.c */
int main ()
{
    IMM_CLIENT *pImm;
    char *szTest = "wa"; //ng";
    int i, j;
    long n;
    PhraseItem *p; 
    PhraseItem a; 

    pImm = ImmOp_Ptr.open ("../../datas"); ///pinyin.tab");
                           //"../../datas/ziranma.tab");
    pImm->m.szPhrase = pImm->buf;

    printf ("\n");
    for (i = 0; i < strlen (szTest); i++)
    {
		char buf[256];
		n = ImmOp_Ptr.KeyFilter (pImm, szTest[i]);
		ImmOp_Ptr.GetInputDisplay (pImm, buf, sizeof (buf)),
		printf ("Input::%s\n", buf);
		ImmOp_Ptr.GetSelectDisplay (pImm, buf, sizeof (buf));
		printf ("Selection::%s\n", buf);

		printf ("each select test...\n");
		for (j = 0; j < n; j++)
		{
			 p = IMM_pGetItem (pImm, j);
			 if (p != NULL)
				 printf ("%s,", p->szPhrase);
		}
		printf ("\n");
	}

	p = ImmOp_Ptr.DoSelectItem (pImm, 0);
	if (p != NULL)
		printf ("you select : 0 ==> %s\n", p->szPhrase);
	printf ("resuming....\n");
	n = ImmOp_Ptr.RestoreToLastStep (pImm);
	for (j = 0; j < n; j++)
	{
		p = IMM_pGetItem (pImm, j);
		if (p != NULL)
			printf ("%s,", p->szPhrase);
	}
	printf ("\n");
	ImmOp_Ptr.PageUp (pImm);
	ImmOp_Ptr.PageDown (pImm);
	ImmOp_Ptr.close (pImm);
	return 1;
}
#endif

