/* vi: set sw=4 ts=4: */
/*
 * Copyright 1999.1 by Li ZhenChun  zhchli@163.net  All Rights Reserved
 *
 * 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_PINYIN_H__
#define	__CCE_PINYIN_H__

#define ENABLE_IUV_PINYIN

#define MAX_PY_NUM 510 /* 410 */

#define MAX_PY_LEN  7 /* miniChinput changed it to 10   */

#define MAX_ZY_LEN  4 /* 3 symbol + 1 tone + '0' */

#define MAX_PYPHRASE_LEN 8 /* 6  */

#define PINYIN_AREA_WIDTH 	20   
 
#define MAX_PYINPUT_BUF 	256 /*	(MAX_PYPHRASE_LEN * MAX_PY_LEN) */

#define MAX_CANDIDATE_BUF 	250  /* selection area (even 1600x1200 at 16x16 font, only 200 width) */

#define NUM_PINYIN_CAND		10 /* 1-9 & 0 */

#define MAX_PY_PER_LETTER 63 /* 38 */

#define MAX_SELECT_PH  512 /* 1024  // we are going to check this one, if too many, will stop! */
#define MAX_TEMP_SELECT_PH 256 /* each len's max temporary select phrase */

#define MAX_PHRASE_COUNT 1024 /* 250 */

typedef struct 
{
  u_short key;  /* This is an index to the 400~500 pinyins  */
  u_short zykey;
  char py[MAX_PY_LEN+1];   /* 8 + 4 = 12 bytes */
} PinYin;

typedef struct _UsrPhrase
{
    struct _UsrPhrase *next;       /* 4 bytes */
    u_short len;    /* phrase len  // 2 bytes */
    u_short count;  /* phrase number // 2 bytes */
    u_char key[0]; /* pinyin key [len+1] */
}UsrPhrase;

typedef struct _Phrase
{
  u_short len;   /* phrase len */
  u_short count; /* phrase number */
  u_char key[0];  /* pinyin key [len+1] */
}Phrase;

#if 0 /* miniChinput's 10 bit pinyin keying */

#define MAX_PYKEY_LEN 18 /* MAX_PYPHRASE_LEN*10/8+1 */
#define PYKEYLEN(len) (len*10/8 +1)

#else /* 9 bit pinyin keying */

#define MAX_PYKEY_LEN (MAX_PYPHRASE_LEN+1)
#define PYKEYLEN(len) (len+1)

#endif

typedef unsigned char PYFREQTYPE;

#define LenOfPhrase(len) ( 2*(len) + sizeof(PYFREQTYPE) )
#define OffsetOfPhrase(len,index) ( PYKEYLEN(len) + (index)*LenOfPhrase(len) )
#define FreqOffsetOfPhrase(len, index) ( OffsetOfPhrase(len,index) + 2*(len) )
#define SizeOfPhrase(len,count)  ( sizeof(Phrase) + OffsetOfPhrase(len, count) ) 

typedef struct _SysPhrase
{
  u_short count;
  Phrase phrase[0];
}SysPhrase;

typedef struct _CandidateItem
{
   Phrase *head;    /* pointer to the len field */
   u_short index;    /* index of the phrase in that  */
}CandidateItem;

typedef u_char PYString[MAX_PY_LEN+3]; /* +2 for the last '\0' and tone? ' ? */
typedef u_char ZYString[MAX_ZY_LEN+1];
typedef u_char SPString[5];  /* AB0'  */

typedef struct _PinyinModule
{

  SysPhrase *sysph[MAX_PY_NUM];   /* system phrases */

  void *MmapPtr;
  int sys_size;

  int KeyboardMode; /* 0 auto, 1 Pinyin 2 KC/ZOZY 3 ETZY */
  int OldCoding; /* pinyin always output as system coding, but this is its old coding  */
  
  UsrPhrase *usrph[MAX_PY_NUM];  /*user defined phrase */

  u_char Keybuf[MAX_PYINPUT_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_PYPHRASE_LEN + 1]; /* pinyin string converted to hanzi(in sys coding) */
  u_char   HZbufOldCoding[2*MAX_PYPHRASE_LEN + 1]; /* in CODE_GBK */
  u_char HZPYKey[MAX_PYPHRASE_LEN + 1];  /* hanzi pinyin keys */
  int    HZbufLen;   /* length of current converted phrase(in Chinese chars, 2 bytes) */

  u_char PYbuf[MAX_PYINPUT_BUF+1]; /* un-selected pinyin string */
  int  PYbufLen;             /* length of PYbuf, in bytes */

  PYString CurPYStr[2 * MAX_PYPHRASE_LEN+1]; /* we use 2* just in case some ` stuff ?? FIXME! */
  int CurPYNum; /* current total pinyin number (eg: Chars) */
  int CurPYPos; /* current pinyin position */
  
  SPString CurSPStr[MAX_PYPHRASE_LEN+1]; /* for ShuangPin */

  ZYString CurZYStr[MAX_PYPHRASE_LEN+1]; /* for Zhuyin */

  Phrase *TmpSel[MAX_PYPHRASE_LEN][MAX_TEMP_SELECT_PH+1];  
  int TmpSelNum[MAX_PYPHRASE_LEN], TmpSelExactCnt[MAX_PYPHRASE_LEN];  
  
  CandidateItem CurSel[MAX_SELECT_PH+1];  /* final selection */
  int TotalSelNum;   /* total selectable char/phrases */
  int SelStartPos;
  int SelEndPos;   /* startpos and endpos of showed selection */
  int CandidateIndex[NUM_PINYIN_CAND];  /* map Candidate 1-10 back to CurSel index */
  
  char iapybuf[MAX_PYINPUT_BUF + 2*MAX_PYPHRASE_LEN + 1];
  char iahzbuf[MAX_CANDIDATE_BUF];

} PinyinModule;   /* about 42KB */

 extern PinYin PYMap[26][MAX_PY_PER_LETTER];  /* 16380 bytes */
  
 extern u_short SPToPYKeyMap[26][28]; /* [3]; only one allow */
 int LoadShuangPinData(u_char *filename); /* load shuangpin.map */

 void PinyinInputCleanup(hz_input_table *table);
 void ResetPinyinInput(PinyinModule *inmd);

 int FindMatchPinyins(int KBIndex, u_char *py, u_short PYAry[]);
 int ParsePinyinKeys( int KBIndex, char *pybuf, PYString pinyin[], SPString sp[]);
 int ConvertZhuyinKeysToPinyin( int KBIndex, char *key, PYString pinyin[], ZYString zhuyin[]);

 int IsValidPinyinZhuyinKey( int KBIndex, int EngPos, int BufLen, u_char ch );

#endif   /* __CCE_PINYIN_H__ */

