/* hanzi.h: Defines, includes, data structures, and global variables for
  Hanzi Master character mental organization improver.
  Adrian Robert; Version 1.0 1/99 */

/* 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 of the License, or
   (at your option) any later version.  Please see the file "COPYING"
   for details.  If you have not received it along with this program,
   please write to the Free Software Foundation, Inc., 59 Temple Place,
   Suite 330, Boston, MA 02111-1307, USA. */

#define HANZIM_VERSION 1.3

/* default for datafiles? (should be in makefile) */
#ifndef LIBDIR
#ifndef _WINDOWS
#define LIBDIR "/home/arobert/Hanzim/Data"
#else
#define LIBDIR "/progra~1/Hanzim/Data"
#endif
#endif

/* maximum lengths for definitions and historical info */
#define DEFNL 80
#define HISTL 80
/* max number of characters with same pronunciation */
#define MAXPCHAR 56
/* max number of pronunciations for one character */
#define MAXCPRON 19
/* max number of characters one character will be remainder of */
#define MAXREMOF 25
/* number of radicals (depends on file "bushou.gb") */
#define NRAD 214

/* pinyin stuff; shouldn't change this */
#define N_INITS 24
#define N_FINALS 37
#define N_TONES 5
#define NPINYIN 4440

/* radical position codes: also shouldn't change */
#define POS_L 0
#define POS_R 1
#define POS_T 2
#define POS_B 3
#define POS_O 4
#define POS_M 5
#define POS_A 6

#define RAD_S 0
#define RAD_N 1
#define RAD_F 2
#define RAD_A 3


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <tk.h>
/* #ifdef _WINDOWS */
/* #include "StdAfx.h" */
/* #endif */

typedef unsigned char uchar;

/* macros to convert between charchar and int formats for char font indices */
#define f_char2int(x,y) ((int) (x) * 256 + (int) (y))
#define f_int2charh(x) ((char)((int) (x) / 256) & 0xff)
#define f_int2charl(x) ((char)((int) (x) % 256) & 0xff)


/***********************************************************/
/* structure definitions */

/* A basic structure to contain lists of indices.*/
typedef struct {
  int		n_entries,	/* number of characters in the list */
  		*ent;		/* an array allocated at runtime */
} idxlist;

/* Structure for a pinyin table entry. */
typedef struct {
  char		init,		/* these first two are indices into */
    		finl,		/* arrays containing strings */
		tone;		/* this is simply a number from 1-4 */
  idxlist	chars;		/* list of characters with this sound */
} pinyinst;

/* Structure for a radical table entry. */
typedef struct {
  int		charidx,	/* reference to character w/form of radical */
  		pinyinidx;	/* pronunciation */
  char		meaning[DEFNL];	/* a definition */
  char		hassimp,	/* marks whether has simp form (and no full) */
    		hasalt,		/* whether has alternate form */
    		hasfull,	/* whether has full form */
		strokes;	/* number of strokes */
  idxlist	chars[4];	/* characters employing in any position */
} radicalst;

/* A large structure containing information on a character.  Note for
  positions here we use the convention 0,...,9 = left,right,top,bottom,
  outside,inside/middle.  Currently it is 167 + 4*(ref'ed elements) in
  size, or roughly 250 bytes, so for database of 7000 characters, is
  about 1.8Mb total. */
typedef struct {
  int		fontidx,	/* reference to the font character (in gb) */
		big5idx;	/* reference to font character in big5 */
  int		radidx,		/* principal radical, indexed into radicals */
    		remainder;	/* leftover, indexed into character array */
  char		radtype,	/* whether norm, simp, full, or alt (0-3) */
  		radpos;		/* position of principal radical */
  int		compidx[10];	/* index for component in each position */
  /*  char	constype;	 how character was constructed (not yet) */
  char		meaning[DEFNL];	/* short definition */
  /*		history[HISTL];	 historical notes (if any; not used yet) */
  char		freq;		/* degree of commonness of use */
  idxlist	pinyins,	/* pronunciations (indices into pinyintbl) */
  		Rpart,		/* words of which is left character */
		Lpart,		/* words of which is the right character */
		remOf;		/* characters of which is remainder */
  char		utf_jh[4],	/* font string in utf8, simplified */
		utf_ft[4],	/* font string in utf8, traditional */
		utf_bpmf[15];	/* hack: store one BoPoMoFo font string */
} characterst;

/* Structure for (2-character) compound information.  Currently it is
   89 bytes large, so for database of 20,000 compounds, is 1.8Mb total. */
typedef struct {
  int		Lcharidx,	/* references to the first and second halves */
		Rcharidx;
  char		meaning[DEFNL];	/* short definition of compound */
  char		freq;		/* degree of commonness of use */
} compoundst;

/* Structure for 3-character triplet information.  Currently it is 93 bytes
   large, so for database of 1,000 compounds, is 93K.  Note, unlike compounds,
   triplets are not indexed and referenced by the characters. */
typedef struct {
  int		char1idx,	/* references to the three components */
		char2idx,
		char3idx;
  char		meaning[DEFNL];	/* short definition of compound */
  char		freq;		/* degree of commonness of use */
} tripletst;


/* function prototypes, C-internal */
void	badfile(char *fname, char *reason),i_error(char *msg),
  	kanzi(char *datadir), kanhe(char *datadir), kanbu(char *datadir),
	kansanzi(char *datadir), fanyi(Tcl_Interp *interp),
	db_init(char *datdir, Tcl_Interp *interp),
  	db_read(FILE *fp), db_write(FILE *fp), memfail(char *item);
char	getnextline(FILE *fp,char *line, int maxlen), *skip(int n, char *s),
	init_vars(char *datadir), radtype(char *s), *itoa(int n);
int	pin_init(char *s), pin_fin(char *s), pin_index(char *s),
	radnum(char *s), icmp(const int *a, const int *b),
  	g2u(char *gb, char*utf), main(int argc, char **argv);
float	dr();
FILE	*Dopen(char *datadir, char *datafile);
Tcl_Obj	*construct_char_entry(int cidx, Tcl_Interp *interp),
  	*construct_comp_entry(compoundst *comp, Tcl_Interp *interp),
  	*construct_triplet_entry(tripletst *triplet, Tcl_Interp *interp);

/* function prototypes, Tcl-liaison */
int	sameRadList(ClientData clientData, Tcl_Interp *interp,
		    int argc, char **argv),
	sameRemList(ClientData clientData, Tcl_Interp *interp,
		    int argc, char **argv),
	samePronList(ClientData clientData, Tcl_Interp *interp,
		    int argc, char **argv),
	LcompList(ClientData clientData, Tcl_Interp *interp,
		    int argc, char **argv),
	RcompList(ClientData clientData, Tcl_Interp *interp,
		    int argc, char **argv),
	radList(ClientData clientData, Tcl_Interp *interp,
		    int argc, char **argv),
	pyChar(ClientData clientData, Tcl_Interp *interp,
		    int argc, char **argv),
  	charinfo(ClientData clientData, Tcl_Interp *interp,
		 int argc, char **argv),
  	randChar(ClientData clientdata, Tcl_Interp *interp,
		 int argc, char **argv),
  	yingHanCh(ClientData clientdata, Tcl_Interp *interp,
		 int argc, char **argv),
  	searchDefn(ClientData clientdata, Tcl_Interp *interp,
                   int argc, char **argv),
  	convertSelection(ClientData clientdata, Tcl_Interp *interp,
		 int objc, Tcl_Obj **objv);

/* function prototypes, Tcl-liason util */
void	catdef(char *dest, char *src, int llen, int nl, int ntabs,
               char uscoreflag),
        copyPron(char *dest, characterst *ch);
int	spacepad(char *dest, int n), issep(char c);


/* global variables (nonstatic declared in hanzi.C) */

/* arrays of character info structures, to be dynamically allocated */
extern pinyinst		*pinyintbl;
extern characterst	*chartbl;
extern radicalst	*radtbl;
extern compoundst	*comptbl;
extern tripletst	*triplettbl;
extern int		*fnt2chr, 	/* convert given font to char index */
  			nchars,  	/* actual numbers we index */
  			ncomps,
  			ntriplets,
			Nchar,		/* these 3 are max possible numbers*/
			Ncomp,		/* determined in 1st pass through dbs*/
			Ntriplet;

/* An array for converting an ascii letter into an initial index number,
   used simply by looking by up the letter-a in the array. */
static char	asc2iidx[26] = {0,1,2,3,0,4,5,6,0,7,8,9,10,11,0,12,13,14, \
				15,16,0,0,17,18,19,20};

/* An array for converting an ascii letter into a final index number into
   an array. */
static char	asc2fidx[26] = {1,0,0,0,6,0,0,0,11,0,0,0,0,0,21,0,0,0,0,0, \
				24,33,0,0,0,0};

/* An array for converting an ascii vowel into a vowel order index. */
static char	asc2vidx[26] = {1,0,0,0,2,0,0,0,3,0,0,0,0,0,4,0,0,0,0,0, \
				5,6,0,0,0,0};

/* A 2-d array of initial strings, including null */
static char	init_str[N_INITS][3] = {"","b","c","d","f","g","h","j","k",
					"l","m","n","p","q","r","s","t",
					"w","x","y","z","ch","sh","zh"};
extern char 	init_str_t[N_INITS][7];

/* A 2-d array of final strings */
static char	fin_str[N_FINALS][5] = {"a","ai","an","ao","ang",
					"e","ei","en","er","eng",
					"i","ia","ie","in","iu","ian","iao",
					    "ing","iang","iong",
					"o","ou","ong",
					"u","ua","ue","ui","un","uo",
					    "uai","uan","uang","ueng",
					"v","ve","vn","van"};
extern char fin_str_t[N_FINALS][5][13];

/* an array to convert radical position letter to code */
static char	rad2pos[26] = {POS_A,POS_B,-1,-1,-1,-1,-1,-1,-1,-1,-1,
			       POS_L,POS_M,-1,POS_O,-1,-1,POS_R,-1,POS_T,
			       -1,-1,-1,-1,-1,-1};

/* these flags are set based on command-line options */
extern int debug;
extern int verbose;
extern int quiet;
