/* vi: set sw=4 ts=4: */
/*
 * CCE - Console Chinese Environment -
 * Copyright (C) 1998-2003 Rui He (rhe@3eti.com)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE TERRENCE R. LAMBERT BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */

#ifndef __CCE_ZHUYIN_H__
#define __CCE_ZHUYIN_H__

#define ZHUYIN_AREA_WIDTH		20

#define MAX_ZYINPUT_BUF			32

#define KEYBOARD_MAP_AUTO       0
#define KEYBOARD_MAP_PINYIN     1 /* no tone py */
#define KEYBOARD_MAP_SHUANGPIN	2 /* no tone shuangpin */

#define KEYBOARD_MAP_LASTPY		2

#define KEYBOARD_MAP_ZOZY       (KEYBOARD_MAP_LASTPY+1)
#define KEYBOARD_MAP_ETZY       (KEYBOARD_MAP_LASTPY+2)
#define KEYBOARD_MAP_CYZY		(KEYBOARD_MAP_LASTPY+3)
#define KEYBOARD_MAP_IBMZY		(KEYBOARD_MAP_LASTPY+4)
#define KEYBOARD_MAP_STZY		(KEYBOARD_MAP_LASTPY+5)
#define KEYBOARD_MAP_ET26ZY		(KEYBOARD_MAP_LASTPY+6)
#define KEYBOARD_MAP_HSU25ZY	(KEYBOARD_MAP_LASTPY+7)
#define KEYBOARD_MAP_LASTZY		(KEYBOARD_MAP_LASTPY+7)

#define IS_KB_PINYIN(map) ( (map) >= 1 && (map) <= KEYBOARD_MAP_LASTPY )
#define IS_KB_SHUANGPIN(map)  ( (map) == KEYBOARD_MAP_SHUANGPIN) /*  || (map) == KEYBOARD_MAP_TONESP ) */
#define IS_KB_ZHUYIN(map) ( (map) > KEYBOARD_MAP_LASTPY && (map) <= KEYBOARD_MAP_LASTZY )
#define IS_KB_CONFLICT(map) ( (map) > KEYBOARD_MAP_LASTPY && (map) <= KEYBOARD_MAP_STZY )

#define MAX_ZYPHRASE_LEN	8

#define MAX_TONE_NUM 5  /* 12345 */
#define MAX_YIN_NUM  4  /* only 3 chars have 4 yins */

#define MAX_ZI_PER_PHONE_SYMBOL  1150 /* max 1070 symbol j */

#define NUM_ZHUYIN_CAND	10  /* 1-90, display 10 candidates */
#define MAX_CAND_NUM	512

#define TONE_MASK 	0xF800
#define TONE_OFFSET 11
#define BPMF_MASK 	0x07C0
#define BPMF_OFFSET	6
#define IUV_MASK  	0x0030
#define IUV_OFFSET  4
#define AOE_MASK  0x000F
#define AOE_OFFSET	0

#define ZHUYIN_NUM1	21  /* bpmfdtnl... */
#define ZHUYIN_NUM2 16 
#define ZHUYIN_TOTAL_NUM (ZHUYIN_NUM1 + ZHUYIN_NUM2) /* 37 */
#define ZHUYIN_FIRST_TONE (ZHUYIN_TOTAL_NUM+1) /* 38, SPACE */

#define TOTAL_ZHUYIN_NUM (0x057F+1)  /* 0000-0101-0111-1111  10101->21  1408 is enough */

#define TOTAL_ET26HSU25_NUM  (0xF00) /* 1 << 12 */
extern u_short ET26HSU25Map[2][ TOTAL_ET26HSU25_NUM /* 1<<12 */];

typedef unsigned short ZYFREQTYPE;
#define MAX_FREQ_ALLOWED	65500

#define PYMAP_TO_INDEX(m, n)    (((m) << 8) | ((n)+1))
#define INDEX_TO_PYMAP(n)       (PYMap[ (n) >> 8][ ((n) & 0xFF)-1])
#define GET_PYMAP_PY(n)  		(INDEX_TO_PYMAP(n).py)

typedef struct _Yin
{
	unsigned short offset;  /* UINT16 offset to the char table */
	unsigned short ZiNum[MAX_TONE_NUM]; /* number of Zi with tone 1-5 */
}Yin;

typedef struct _Zi
{
	ZYFREQTYPE freq;
	unsigned short yin[MAX_YIN_NUM];
	unsigned int   offset;  /* byte offset in CiLib */
	union
	{
		unsigned char  PhraseNum[MAX_ZYPHRASE_LEN];  /* len=1~7(without 1st char)   (less than 255) */
		unsigned short PhraseNum1; /* two many len=2 phrases, using 0~1(16 bits) for it */
	}phnum;  /* not everybody supports anonymous union */
}Zi;

typedef struct
{
	char py[MAX_PY_LEN+1];   /* 8 + 2 = 10 bytes each PYToZY item */
	unsigned short zykey;  /* 11 bits zhuyin key without tones	 */
} PYToZY;

typedef struct 
{
	unsigned short zi;  /* first zi */
	unsigned char  len; /* len=0 for zi, len=1~MAX_ZYPHRASE_LEN for phrase */
	u_char	*ptr;  /* pointer to the phrase */
} SelItem;  /* 4 bytes per item */

typedef struct _ZhuyinModule
{
	
	Yin *YinTable; 
	int	ZiLibSize;        /* 28KB */
	unsigned short *ZiLib;
	
	int ZiNum;    /* how many zis */
	Zi	*ZiTable;  /* 206KB */

	int CiLibSize;
	unsigned char *CiLib;
	
  	void *MmapPtr;
  	int sys_size;

	int KeyboardMode;
	int OldCoding;

	u_char Keybuf[MAX_ZYINPUT_BUF+1];	/* input buffer for keystrokes */
	int  KeybufLen; /* total length(in bytes) */

  	int  EnglishPos; /* Capital Letter entered? 0 for no */
 
	u_char   HZbuf[2*MAX_ZYPHRASE_LEN + 1]; /* pinyin string converted to hanzi(in sys coding) */
	u_char   HZbufOldCoding[2*MAX_ZYPHRASE_LEN + 1]; /* in CODE_GBK */
	u_char HZPYKey[MAX_ZYPHRASE_LEN + 1];  /* hanzi pinyin keys */
	int    HZbufLen;   /* length of current converted phrase(in Chinese chars, 2 bytes) */

	u_char ZYbuf[MAX_ZYINPUT_BUF+1]; /* un-selected pinyin string */
	int  ZYbufLen;             /* length of ZYbuf, in bytes */

	unsigned short CurZYKey[ MAX_ZYPHRASE_LEN+1]; /* we use 2* just in case some ` stuff */
	unsigned short CurZYMask[ MAX_ZYPHRASE_LEN+1];
	ZYString CurZYStr[ MAX_ZYPHRASE_LEN+1];

	int CurZYNum; /* current total pinyin number (eg: Chars) */
	int CurZYPos; /* current pinyin position */
  
	u_char SavedPYStr[ MAX_ZYPHRASE_LEN+1][MAX_PY_LEN+3]; /* for pinyin 7+3 = 10 */

	SPString CurSPStr[MAX_ZYPHRASE_LEN+1];

	u_short FirstZiAry[MAX_ZI_PER_PHONE_SYMBOL];  /* 1150 */

  	SelItem CurSel[MAX_CAND_NUM+1];  /* final selection */

  	int TotalSelNum;   /* total selectable char/phrases */
  	int FirstZiNum;  /* number of matching first char */
  	int SelStartPos;
  	int SelEndPos;   /* startpos and endpos of showed selection */

  	int CandidateIndex[NUM_ZHUYIN_CAND];  /* hard-coded here 1-90 map Candidate 1-10 back to CurSel index */
 
  	char iapybuf[MAX_ZYINPUT_BUF + 2*MAX_ZYPHRASE_LEN + 1];
  	char iahzbuf[MAX_CANDIDATE_BUF];

} ZhuyinModule;   /* about 42KB */

extern unsigned char *InputKeyMap[];

extern unsigned char Big5PhoneChars[];
extern unsigned char GBPhoneChars[];
extern unsigned char *ZYSymbolToPYString[];

extern u_short ZYToPYMap[TOTAL_ZHUYIN_NUM];

 void ZhuyinInputCleanup(hz_input_table *table);
 void ResetZhuyinInput(ZhuyinModule *inmd);

 int ParseOneZhuyin(u_char key[], ZYString zhuyin,
		         u_short yin[], u_short mask[]);

 int ParseZhuyinKeys(int KBIndex, u_char key[], ZYString zhuyin[],
		 u_short yin[], u_short mask[], int nMax);

 int ConvertOnePinyinToZhuyin( u_char pybuf[], int count, ZYString zhuyin,
		u_short yin[], u_short mask[], u_char pystr[MAX_PY_LEN+3]);
 
 int ConvertPinyinKeysToZhuyin( int KBIndex, u_char pybuf[], ZYString zhuyin[],
        u_short yin[], u_short mask[], u_char pystr[][MAX_PY_LEN+3], SPString spstr[], int nMax);
	
 int ConvertZhuyinStrToKeys(u_char *buf, u_char key[]);
	
#endif  /* __CCE_ZHUYIN_H__ */

