/* 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.
 *
 */

/* hzinput.h -- definitions used in input methods */
#ifndef __CCE_HZINPUT_H__
#define __CCE_HZINPUT_H__

#define MAX_INPUT_LENGTH        15 

#define INPUT_MAGIC_NUMBER     "CIN" /* CCE input method file magic number */
#define ASSOCIATE_MAGIC_NUMBER "ASC" /* CCE Association file magic number  sizeof("ASC") = 4, including the 0 */

#define EMPTY_SLOT_STRING		"EMPTY"  /* used to indicate that the current slot is empty(no input method) */

#define MAX_CHANGEPAGE_KEYS		7
#define DEFAULT_PAGEPREV_KEYS   ",<-["
#define DEFAULT_PAGENEXT_KEYS   ".>=]"

#define ASSOCIATE_PAGEPREV_KEYS "<-["
#define ASSOCIATE_PAGENEXT_KEYS ">=]"

#define MAX_SELFIRST_KEYS		3
#define DEFAULT_SELFIRST_KEYS	" "

#define CIN_ENAME_LENGTH        24
#define CIN_CNAME_LENGTH        16
#define MAX_PHRASE_LENGTH       30  

#define MAX_KEY_LENGTH			12

#define MAX_END_KEYS			7

#define MAX_INPUT_KEYS			64
#define DEFAULT_WILDCARD_CHAR	'?'

#define MAX_SELECT_KEYS       	16  
#define DEFAULT_SELECT_KEYS  "1234567890"

#define DEFAULT_INPUT_KEYS   "abcdefghijklmnopqrstuvwxyz"

#define DEFAULT_SWITCH_KEYS  "ABCDEFGHIJKLMNOPQRSTUVWXYZ:"
#define VALID_SWITCHENG_CHARS(c)      	((c) >= 'A' && (c) <= 'Z')
#define VALID_ENG_CHARS(c)    			((c) >= ' ' && (c) <= 0x7E)

#define WINDOW_TERMINAL_STR_WIDTH  18

#define cal_input_xpos(table) ( (dispInfo.show_terminal ? 5 : 0) + strlen((table)->cname)+4)
 
typedef struct {
	unsigned char ch;      
	unsigned char *punct[CODE_NUM];  /* two possible choice, NULL for only one */
}Punct1;

typedef struct {
	unsigned char ch;      
	unsigned char index;      /* 0 or 1 for the current choice */
	unsigned char *punct[2][CODE_NUM];  /* two possible choice, NULL for only one */
}Punct2;

typedef struct {
	unsigned char ch[2];
	int count;
    unsigned char *punct[2][2][CODE_NUM];
}Punct3;

#define NR_INPUTMETHOD 10

#define TYPE_CHAR   0x01
#define TYPE_PHRASE 0x80

#define INPUT_TYPE_INTCODE 0x01
#define INPUT_TYPE_PINYIN  0x02
#define INPUT_TYPE_TABLE   0x03
#define INPUT_TYPE_ZHUYIN  0x04

typedef struct {
	union 
	{
  		unsigned int  PhraseOffset;  /* Offset to phrase file */
  		unsigned char Phrase[4];     /* 2 or 4 bytes Chinese char/phrase */
 	}phr;
  	unsigned int key[1];

} ITEM;

 typedef struct
 {
	unsigned int KVal1, KVal2;			/* key values */
	unsigned int LMask1, LMask2;		/* key's len mask(for prefix-match) */
    unsigned int WMask1, WMask2;  		/* wildcard mask   a*cd => f0ff */
	unsigned int WPreMask1, WPreMask2;	/* wildcard prefix-mask a*cd => f000 ab*d => ff00 */
 }KEYCODE;

typedef struct {
	char MagicNum[sizeof(ASSOCIATE_MAGIC_NUMBER)];
	int Encoding; /* GB/GBK/Big5  GB and GBK can use interchangeably */
	int	PhraseOffset; /* offset to begin of phrase entry */
	unsigned short MinIndex, MaxIndex;  /* last one, MaxIndex is a dummy  MinIndex <= ValidIndex < MaxIndex */
}AssociateHeader;

typedef struct {
        u_char magic_number[sizeof(INPUT_MAGIC_NUMBER)];    /* magic number */
        u_char ename[CIN_ENAME_LENGTH];               /* ascii name */
        u_char cname[CIN_CNAME_LENGTH];               /* chinese input method name */
        u_char selkey[MAX_SELECT_KEYS+1];             /* select keys, add one 0 */
		
		u_char pageprevkey[MAX_CHANGEPAGE_KEYS+1];
		u_char pagenextkey[MAX_CHANGEPAGE_KEYS+1];

		u_char selfirstkey[MAX_SELFIRST_KEYS+1];

		u_char wildcard;	      /* can define one wildcard char(default is ?) 0x00 for none */
		
		u_char InputType;			/* 0x1-0x3 intcode, pinyin, table */

		u_char encoding;      /*GB/GBK/Big5/KSC/JIS etc */
		u_char key_prompt;     /* mainly for CangJie, WuBi, display uninput key for candidates */
        u_char auto_select;   /*char last_full;        */

		u_char prefix_match_enable; /* 1 to enable keys' prefix-match otherwise exact-match */
		u_char left_shift_enable;  /* 1 to enable left-shift */

		u_char key_len;			/* Key Length: 5->32 keys(max 12 keys)  6->64 keys(max 10 keys), default is 6 */
		u_char keyname_bytes;     /* 1 or 2, ASCII or Chinese, default is 1 */

        int TotalKey;           /* number of keys needed */
        int MaxPress;           /* Max len of keystroke */
        int MaxDupSel;          /* how many keys used to select */
        int TotalEntries;       /* Defined characters and phrases */
		int ItemBytes;          /* ItemBytes: how many bytes in an item, 8/12 bytes */

        u_char KeyMap[128];     /* Map 128 chars to 64(6 bit) key index */
        u_char KeyName[MAX_INPUT_KEYS][3];  

        unsigned short KeyIndex[MAX_INPUT_KEYS];   /* 64 key first index of TotalChar */

        int  PhraseFileSize;     /* Total Phrase File Size (==0 means no phrase file) */
		int	 PhraseBegin;        /* the location where phrase strings begin, 0 for no phrase */

        ITEM *item;             /* item != NULL  dynamic mapping
		                          0 unmapped, -1 (no table) other: mapped
								ITEM table has been mapped(will map when it's used) */
        FILE *TableFile;       /* *.tab File */

        FILE *AssocFile;        /* *.lx LianXiang File */

		int AscEncoding; /* GB/GBK/Big5  GB and GBK can use interchangeably */
    	int AscPhraseOffset; /* offset to begin of phrase entry */
    	unsigned short AscMinIndex, AscMaxIndex;  /* last on */

		int  InputSelectKeyConflict, FirstInputSelectKeyConflict;
		u_char Shift_SelKey[MAX_SELECT_KEYS+1];  /* add one zero   */

		int  InputAreaX, InputAreaWidth;
		int  SelAreaX, SelAreaWidth;

		int  FontMapped;  /* font has been mmapped */

		void *PrivateData; /* pointer to private data structure of the input method, like Pinyin's Input_Module */
	
		int (*HZFilter)(int tty, unsigned char key);
		void (*RefreshInput)(void);
		void (*ChangeKeyboardMap)(int offset);
		
} hz_input_table;

void InputAreaOutput(int encoding, int x, u_char *string, int fg, int bg);
int  FindMatchKeyAndFill(void);
int  FillMatchCharsForward(int FirstFill, int nCount, int *CurIndex, int CurEndIndex, KEYCODE *kc);
int FillAssociateChars(int index);
int FindAssociateKeyAndFill(unsigned char LastChar[]);
void DisplayAssociateInput(void);

hz_input_table* Init_PinyinInput(hz_input_table *table, char *filename, int sysCoding);
hz_input_table* Init_ZhuyinInput(hz_input_table *table, char *filename, int sysCoding);
hz_input_table* Init_IntCodeInput(hz_input_table *table, int sysCoding);

void IntCode_FindMatchKey(int sysCoding);
void IntCode_FillMatchChars(int sysCoding, int index);
int Intcode_HZFilter(int tty_fd, unsigned char key);
int Associate_HZFilter(int tty_fd, unsigned char key);
int Pinyin_HZFilter(int tty_fd, u_char key);
int Zhuyin_HZFilter(int tty_fd, u_char key);

int LoadAssociateFile(hz_input_table *table, const char *filename);
int MmapInputTable(hz_input_table *table);
hz_input_table* LoadInputMethod(const char *filename);
void UnloadInputMethod(int i);
int Table_HZFilter(int tty_fd, unsigned char key); 
void ClearSelectionArea(void);
void ClearInputArea(void);
void DisplayInput(void);
void DisplaySelection(void);
void ResetInput(int ClearInput, int ClearSelect);

void InputInit(void);
void InputCleanup(void);
void InputSwitchEncoding(int encoding);
void HZFilter(int tty_fd, unsigned char c);
void ToggleAssociateMode();
void ToggleChinesePunct();
void ToggleInputMethod(void);
void ToggleHalfFull(void);
void ChangePinyinZhuyinKeyboardMap(void);
void SwitchInputMethod(void);  /* jmce added */
int  SetCurrentInputMethod(int);
void RefreshInputArea(int ClearInput);
void DispSelection(void);
void OutputSelection(int inEncoding, int tty_fd, unsigned char *p );
void OutputEngChar(int tty_fd, unsigned char c);
void OutputCJKStr(int tty_fd, unsigned char *buf, int count);

int ConfigInputMethod(const char *str);     /* universal (IntCode as 0) */
int ConfigInputMethodGB(const char *str);   /* GB (IntCode as 0 and ZhiPin as 9) */
int ConfigInputMethodBig5(const char *str); /* Big5 (0/1/3/8/9 loaded) */

 extern int IsHanziInput;   /* 0 for ascii, 1 for hanzi input */
 extern int IsFullChar;     /* 0 for half char, 1 for full char */
 extern int IsChinesePunct; /* 0 for english punctuation, 1 for Chinese punct */

 extern int current_method;
 extern hz_input_table *input_table[NR_INPUTMETHOD],*cur_table; /* NULL */

 extern int IsAssocEnable;  /* -1 default */

 extern int IsAssociateMode;  /* currently it's in AssociateMode */

 extern unsigned char SelTab[MAX_SELECT_KEYS][MAX_PHRASE_LENGTH+1];
 extern int CurSelNum;   /* Current Total Selection Number */
 extern int InpKey[MAX_INPUT_LENGTH];

#define MAX_PAGE_INDEX 32 /* save the first 32 pages' starting index */
 extern int SavedPageIndex[MAX_PAGE_INDEX];
 extern int CurrentPage;
 
 extern int InputCount,InputMatch, StartIndex,EndIndex;
 extern int NextPageIndex,CurrentPageIndex,MultiPageMode;
 extern int IsDirectSelect;

 extern int EnableFuzzyPinyin; /* global option z-c-s zh-ch-sh */
 extern int ZhiyinKeyboardMode;
 extern int ZhuyinKeyboardMode;
   
 extern char *InpNameStr[];
 extern u_char HalfFullIcons[2][32];
 extern u_char ChEngPunctIcons[2][32];
 extern char *EngNumStr[];
 extern char *WindowStr[];
 extern char *LianXiangStr[];
 extern u_char *CurCoding[];
 extern u_char *FullCharMap[];
 extern char *IntCode_CNameStr[];
 extern char *Pinyin_CNameStr[];
 extern char *Zhuyin_CNameStr[];
 extern char *ZhiyinKeyboardMapStr[];
 extern char *CiyinKeyboardMapStr[];
 
 extern Punct1 Punct1Str[];
 extern Punct2 Punct2Str[];
 extern Punct3 Punct3Str[];

#endif  /* __CCE_HZINPUT_H__ */

