/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	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.

**********************************************************************/



#ifndef ___LONG_CHAR_H___
#define ___LONG_CHAR_H___

#define LCZM_4BYTE	0x80000000
#define LCZ_4BYTE	0x00000000
#define LCZM_4B_TYPE	0x80000000

#define LCZM_3BYTE	0xc0000000
#define LCZ_3BYTE	0x80000000
#define LCZM_3B_TYPE	0xff000000
#define LCZM_3B_CODE	0x00ffffff

#define	LCZM_2BYTE	0xe0000000
#define LCZ_2BYTE	0xc0000000
#define LCZM_2B_TYPE	0xffff0000
#define LCZM_2B_CODE	0x0000ffff

#define LCZM_1BYTE	0xf0000000
#define LCZ_1BYTE	0xe0000000
#define LCZM_1B_TYPE	0xffffff00
#define LCZM_1B_CODE	0x000000ff

#define LCZM_7BIT	0xf0000000
#define LCZ_7BIT	0xf0000000
#define LCZM_7b_TYPE	0xffffff80
#define LCZM_7b_CODE	0x0000007f

#define LCZ_1BC_ASCII		0x00000000
#define LCZ_1BC_ISO8859_1	0x00000000

#define LCZ_1BC_ISO8859_2	0xe0000200
#define LCZ_1BC_ISO8859_3	0xe0000300
#define LCZ_1BC_ISO8859_4	0xe0000400
#define LCZ_1BC_ISO8859_5	0xe0000500
#define LCZ_1BC_ISO8859_6	0xe0000600
#define LCZ_1BC_ISO8859_7	0xe0000700
#define LCZ_1BC_ISO8859_8	0xe0000800
#define LCZ_1BC_ISO8859_9	0xe0000900
#define LCZ_1BC_ISO8859_10	0xe0000a00
#define LCZ_1BC_ISO8859_13	0xe0000d00
#define LCZ_1BC_ISO8859_14	0xe0000e00
#define LCZ_1BC_ISO8859_15	0xe0000f00


#define LCZ_1BC_JISX0201	0xe0000100
#define LCZ_2BC_JISX0208_1990	0xc0010000
#define LCZ_2BC_JISX0208_1983	0xc0030000
#define LCZ_2BC_JISX0208_1978	0xc0040000
#define LCZ_2BC_JISX0212_1990	0xc0050000

#define LCZ_2BC_UNICODE_v1_1_JP	0xc0060000
#define LCZ_2BC_UNICODE_v1_1_TW	0xc0070000
#define LCZ_2BC_UNICODE_v1_1_CN	0xc0080000
#define LCZ_2BC_UNICODE_v1_1_KR	0xc0090000

#define LCZ_2BC_UNICODE_v2_0_JP	0xc00a0000
#define LCZ_2BC_UNICODE_v2_0_TW	0xc00b0000
#define LCZ_2BC_UNICODE_v2_0_CN	0xc00c0000
#define LCZ_2BC_UNICODE_v2_0_KR	0xc00d0000

#define LCZ_2BC_UNICODE_v3_0_JP	0xc00e0000
#define LCZ_2BC_UNICODE_v3_0_TW	0xc00f0000
#define LCZ_2BC_UNICODE_v3_0_CN	0xc0100000
#define LCZ_2BC_UNICODE_v3_0_KR	0xc0110000

#define LCZ_2BC_UNICODE_v1_1_UN	0xc0120000
#define LCZ_2BC_UNICODE_v2_0_UN	0xc0130000
#define LCZ_2BC_UNICODE_v3_0_UN	0xc0140000

#define LCZ_3BC_NICHIBUN	0xc0020000
#define LCZ_3BC_KONJAKU		0x81000000

#define LCZ_2BC_LCCODE		0xdfff0000

#define LCC_INTERNAL		(LCZ_2BC_LCCODE|0x0000)
#define LCC_ASCII		(LCZ_2BC_LCCODE|0x0001)
#define LCC_ISO646		(LCZ_2BC_LCCODE|0x0002)
#define LCC_ISO8859_1		(LCZ_2BC_LCCODE|0x0003)
#define LCC_ISO8859_2		(LCZ_2BC_LCCODE|0x0004)
#define LCC_ISO8859_3		(LCZ_2BC_LCCODE|0x0005)
#define LCC_ISO8859_4		(LCZ_2BC_LCCODE|0x0006)
#define LCC_ISO8859_5		(LCZ_2BC_LCCODE|0x0007)
#define LCC_ISO8859_6		(LCZ_2BC_LCCODE|0x0008)
#define LCC_ISO8859_7		(LCZ_2BC_LCCODE|0x0009)
#define LCC_ISO8859_8		(LCZ_2BC_LCCODE|0x000a)
#define LCC_ISO8859_9		(LCZ_2BC_LCCODE|0x000b)
#define LCC_ISO8859_10		(LCZ_2BC_LCCODE|0x000c)
#define LCC_UNICODE_v1_1	(LCZ_2BC_LCCODE|0x000d)
#define LCC_UNICODE_v2_0	(LCZ_2BC_LCCODE|0x000e)
#define LCC_UNICODE_v3_0	(LCZ_2BC_LCCODE|0x000f)
#define LCC_ISO10646_v1_1	(LCZ_2BC_LCCODE|0x0010)
#define LCC_ISO10646_v2_0	(LCZ_2BC_LCCODE|0x0011)
#define LCC_ISO10646_v3_0	(LCZ_2BC_LCCODE|0x0012)
#define LCC_UCS2		(LCZ_2BC_LCCODE|0x0013)
#define LCC_UCS4		(LCZ_2BC_LCCODE|0x0014)
#define LCC_UTF7		(LCZ_2BC_LCCODE|0x0015)
#define LCC_UTF8		(LCZ_2BC_LCCODE|0x0016)
#define LCC_UTF16		(LCZ_2BC_LCCODE|0x0017)

#define LCC_ISO8859_11		(LCZ_2BC_LCCODE|0x0018)
#define LCC_ISO8859_12		(LCZ_2BC_LCCODE|0x0019)
#define LCC_ISO8859_13		(LCZ_2BC_LCCODE|0x001a)
#define LCC_ISO8859_14		(LCZ_2BC_LCCODE|0x001b)
#define LCC_ISO8859_15		(LCZ_2BC_LCCODE|0x001c)

#define LCC_VISCII		(LCZ_2BC_LCCODE|0x0100)
#define LCC_TCVN5712		(LCZ_2BC_LCCODE|0x0101)

#define LCC_TIS620		(LCZ_2BC_LCCODE|0x0200)

#define LCC_JISX0201_ROMAN	(LCZ_2BC_LCCODE|0x0300)
#define LCC_JISX0201_KATAKANA	(LCZ_2BC_LCCODE|0x0301)
#define LCC_JISX0208_1978	(LCZ_2BC_LCCODE|0x0302)
#define LCC_JISX0208_1983	(LCZ_2BC_LCCODE|0x0303)
#define LCC_JISX0208_1990	(LCZ_2BC_LCCODE|0x0304)
#define LCC_JISX0208_1997	(LCZ_2BC_LCCODE|0x0305)
#define LCC_JISX0218		(LCZ_2BC_LCCODE|0x0306)
#define LCC_JP_EUC		(LCZ_2BC_LCCODE|0x0307)
#define LCC_EUC_JP		(LCZ_2BC_LCCODE|0x0308)
#define LCC_Shift_JIS		(LCZ_2BC_LCCODE|0x0309)
#define LCC_ISO2022_JP		(LCZ_2BC_LCCODE|0x030a)
#define LCC_ISO2022_JP_1	(LCZ_2BC_LCCODE|0x030b)
#define LCC_ISO2022_JP_2	(LCZ_2BC_LCCODE|0x030c)
#define LCC_KONJAKU		(LCZ_2BC_LCCODE|0x0380)
#define LCC_NICHIBUN		(LCZ_2BC_LCCODE|0x0381)

#define LCC_GB2312		(LCZ_2BC_LCCODE|0x0400)
#define LCC_CN_GB		(LCZ_2BC_LCCODE|0x0401)
#define LCC_GBK			(LCZ_2BC_LCCODE|0x0402)
#define LCC_HZ_GB2312		(LCZ_2BC_LCCODE|0x0403)
#define LCC_GB7589		(LCZ_2BC_LCCODE|0x0404)
#define LCC_GB7590		(LCZ_2BC_LCCODE|0x0405)
#define LCC_ITU_T_T101_ChinesePrimarySet	\
				(LCZ_2BC_LCCODE|0x0406)
#define LCC_GBT12345		(GBZ_2BC_LCCODE|0x0407)
#define LCC_ISO2022_CN		(LCZ_2BC_LCCODE|0x0408)
#define LCC_ISO2022_CN_EXT	(LCZ_2BC_LCCODE|0x0409)

#define LCC_BIG5		(LCZ_2BC_LCCODE|0x0500)
#define LCC_CNS11643		(LCZ_2BC_LCCODE|0x0501)
#define LCC_CNS11643_1988	(LCZ_2BC_LCCODE|0x0502)
#define LCC_CNS11643_1992	(LCZ_2BC_LCCODE|0x0503)
#define LCC_CCCII		(LCZ_2BC_LCCODE|0x0504)
#define LCC_EUC_TW		(LCZ_2BC_LCCODE|0x0505)

#define LCC_KSX1001		(LCZ_2BC_LCCODE|0x0600)
#define LCC_KSX1002		(LCZ_2BC_LCCODE|0x0601)
#define LCC_EUC_KR		(LCZ_2BC_LCCODE|0x0602)
#define LCC_ISO2022_KR		(LCZ_2BC_LCCODE|0x0603)
#define LCC_JOHAB		(LCZ_2BC_LCCODE|0x0604)
#define LCC_UHC			(LCZ_2BC_LCCODE|0x0605)

#define LCC_ERROR		(LCZ_2BC_LCCODE|0x0ffff)

#define LCZ_4BC_ISO10646_v2_0	0x00000000


#define _L_CHAR	unsigned long
typedef _L_CHAR L_CHAR;

#define LC_MIN	0x00000000
#define LC_MAX	0xffffffff


#define LC_NAME_SIZE	32

typedef struct code_abb {
	struct code_abb *	next;
	char		name[LC_NAME_SIZE];
	struct code_method *	cm;
	L_CHAR			lccode;
} CODE_ABB;

typedef struct cm_dummy {
	short		d0;
	short		d1;
} CM_DUMMY;

typedef struct code_method {
	char		name[LC_NAME_SIZE];
	L_CHAR		lccode;
	L_CHAR *	main_code;
	int		max_ret;
	int		close_max;
	CM_DUMMY	dummy;
	void *		(*open)();
	int		(*close)(unsigned char *,void *);
	int		(*to_internal)(
				L_CHAR * ret,
				void * work,
				unsigned char ch
					);
	int		(*to_external)(
				unsigned char * ret,
				void * work,
				L_CHAR ch
					);
	struct code_method *	next;
} CODE_METHOD;

typedef struct writable_code_table {
	struct writable_code_table *	next;
	L_CHAR				lcz;
	L_CHAR				mask;
	L_CHAR *			tbl;
	struct writable_code_table *	alias;
	void *				work;
} WRITABLE_CODE_TABLE;

typedef struct wct {
	WRITABLE_CODE_TABLE *		list;
} WCT;

typedef struct unicode_x {
	L_CHAR	unicode;
	L_CHAR	local;
} UNICODE_X;

typedef struct code_entry {
	L_CHAR			code;
	struct code_entry *	co;
} CODE_ENTRY;

typedef struct code_table_header {
	struct code_table_header *	next;
	L_CHAR				lcz;
	L_CHAR				mask;
	int				len;
	struct code_entry *		tbl;
} CODE_TABLE_HEADER;

extern CODE_METHOD * std_cm;

L_CHAR * l_string(CODE_METHOD *,char*);
char * n_string(CODE_METHOD *,L_CHAR *);
int l_strcmp(L_CHAR*,L_CHAR*);
int l_strlen(L_CHAR *);
CODE_METHOD * get_default_cm();
CODE_METHOD * search_cm(char *);
CODE_METHOD * search_cm_by_lccode(L_CHAR);
CODE_METHOD * search_cm_by_main_code(L_CHAR);
L_CHAR search_lccode(char * name);
L_CHAR get_lc_mask(L_CHAR code);
void insert_code_list(CODE_METHOD *);
void insert_code_abb(char * name,L_CHAR,CODE_METHOD *);

L_CHAR * wct_conv(WCT*,L_CHAR *);
WCT * new_wct();
WRITABLE_CODE_TABLE * set_wct(WCT* wct,L_CHAR lcz,L_CHAR mask,
			WRITABLE_CODE_TABLE * alias,
			void * work);
WRITABLE_CODE_TABLE * get_wct(WCT* wct,L_CHAR ch);
void
set_convert(WCT * w,
	L_CHAR from,L_CHAR mask,
	L_CHAR to,
	int flag);
#define SC_ALL		0
#define SC_IF_NOTEXIST	1
int wct_check(WCT *,L_CHAR);
void
copy_wct(
	WRITABLE_CODE_TABLE * dest,
	WRITABLE_CODE_TABLE * src,
	int mode);

extern CODE_METHOD sjis_cm,jis_cm,euc_cm,int_cm;
extern CODE_METHOD utf8_cm,ucs4_cm,utf16_cm;
extern CODE_METHOD ascii_cm;

/* latin domain font bitmap */
#define LCB_ISO8859_1		1
#define LCB_ISO8859_2		2
#define LCB_ISO8859_3		4
#define LCB_ISO8859_4		8
#define LCB_ISO8859_5		0x10
#define LCB_ISO8859_6		0x20
#define LCB_ISO8859_7		0x40
#define LCB_ISO8859_8		0x80
#define LCB_ISO8859_9		0x100
#define LCB_ISO8859_10		0x200
#define LCB_ISO8859_11		0x400
#define LCB_ISO8859_12		0x800
#define LCB_ISO8859_13		0x1000
#define LCB_ISO8859_14		0x2000
#define LCB_ISO8859_15		0x4000

#define LCB_UNICODE_v1_1	0x80000000
#define LCB_UNICODE_v2_0	0x40000000
#define LCB_UNICODE_v3_0	0x20000000

/* jp domain font bitmap */

#define LCB_JISX0201		1
#define LCB_JISX0208_1978	2
#define LCB_JISX0208_1983	4
#define LCB_JISX0208_1990	8
#define LCB_JISX0212_1990	0x10
#define LCB_NICHIBUN		0x20
#define LCB_KONJAKU		0x40
#define LCB_UNICODE_v1_1_JP	0x80000000
#define LCB_UNICODE_v2_0_JP	0x40000000
#define LCB_UNICODE_v3_0_JP	0x20000000

void wct_unicode(WCT * w);
void wct_jp(WCT * w,int bitmap);
void wct_latin(WCT * w,int bitmap);

CODE_TABLE_HEADER *
get_code_table_by_lcz(L_CHAR lcz);
CODE_TABLE_HEADER *
get_code_table_by_char(L_CHAR a);
void
set_correspond(L_CHAR a,L_CHAR b);
L_CHAR
code_convert(L_CHAR from,L_CHAR lcz);

#endif
