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

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

#include	<stdio.h>
#include	<stdlib.h>
#include	"long_char.h"

#define BSIZE 1000
#define MAX	10

char output_type;
void (*conv_func)();
char buffer[BSIZE];
char col[MAX][100];

CODE_TABLE_HEADER * ct_unicode;
CODE_TABLE_HEADER * ct_rk;
CODE_TABLE_HEADER * ct_jisx0;
CODE_TABLE_HEADER * ct_jisx1;
CODE_TABLE_HEADER * ct_jisx2;
CODE_TABLE_HEADER * ct_jisx_s;

CODE_TABLE_HEADER * ct_root;

L_CHAR
output_jisx(char * str,L_CHAR mask)
{
int a;
int ku,ten,code;
char buf[100];
	a = atoi(&str[2]);
	ku = a/100;
	ten = a%100;
	code = ((ku+0x20)<<8) + (ten+0x20);
	return mask|code;
}


int
get_col_row(char * str)
{
char * s1, * s2;
	s1 = &str[2];
	for ( s2 = s1 ; *s2 && *s2 != '/' ; s2 ++ );
	if ( *s2 == 0 ) {
		fprintf(stderr,"get_col_row error %s\n",str);
		exit(1);
	}
	*s2 = 0;
	s2 ++;
	return (atoi(s1)<<4) +  atoi(s2);
}

L_CHAR
output_jisx0201_r(char * col)
{
int code;
	code = get_col_row(col);
	return LCZ_1BC_JISX0201|code;
}

L_CHAR
output_jisx0201_k(char * col)
{
int code;
	code = get_col_row(col);
	return LCZ_1BC_JISX0201|0x80|code;
}

void
yasuoka_a()
{
char * s;
int i;
L_CHAR unicode,rk_code,jisx0_code,jisx1_code,jisx2_code,jisx_s_code;

	ct_unicode = get_code_table_by_lcz(LCZ_2BC_UNICODE_v1_1_UN);
	ct_rk = get_code_table_by_lcz(LCZ_1BC_JISX0201);
	ct_jisx0 = get_code_table_by_lcz(LCZ_2BC_JISX0208_1978);
	ct_jisx1 = get_code_table_by_lcz(LCZ_2BC_JISX0208_1983);
	ct_jisx2 = get_code_table_by_lcz(LCZ_2BC_JISX0208_1990);
	ct_jisx_s = get_code_table_by_lcz(LCZ_2BC_JISX0212_1990);

	for ( ; ; ) {
		s = fgets(buffer,BSIZE-1,stdin);
		if ( s == 0 )
			break;
		sscanf(buffer,"%s %s %s %s %s %s\n",
			col[0],
			col[1],
			col[2],
			col[3],
			col[4],
			col[5]);
		if ( col[0][0] == '#' )
			continue;
		sscanf(col[0],"%X",&unicode);
		unicode |= LCZ_2BC_UNICODE_v1_1_UN;

		rk_code = jisx0_code = jisx1_code = jisx2_code
			= jisx_s_code = 0;

		for ( i = 1 ; i < MAX ; i ++ ) {
			switch ( col[i][0] ) {
			case '#':
				goto next;
			case 'R':
				rk_code = output_jisx0201_r(col[i]);
				if ( rk_code )
					set_correspond(
						unicode,
						rk_code);
				break;
			case 'K':
				rk_code = output_jisx0201_k(col[i]);
				if ( rk_code )
					set_correspond(
						unicode,
						rk_code);
				break;
			case '0':
				jisx0_code = output_jisx(col[i],
					LCZ_2BC_JISX0208_1978);
				if ( jisx0_code )
					set_correspond(
						unicode,
						jisx0_code);
				break;
			case '1':
				jisx1_code = output_jisx(col[i],
					LCZ_2BC_JISX0208_1983);
				if ( jisx1_code )
					set_correspond(
						unicode,
						jisx1_code);
				break;
			case '2':
				jisx2_code = output_jisx(col[i],
					LCZ_2BC_JISX0208_1990);
				if ( jisx2_code )
					set_correspond(
						unicode,
						jisx2_code);
				break;
			case 'S':
				jisx_s_code = output_jisx(col[i],
					LCZ_2BC_JISX0212_1990);
				if ( jisx_s_code )
					set_correspond(
						unicode,
						jisx_s_code);
				break;
			default:
				fprintf(stderr,"???? %s\n",col[i]);
				exit(1);
			}
		}
	next:
		if ( output_type == 't' ){
			if ( unicode )
				printf("0x%x",unicode);
			if ( rk_code )
				printf("\t0x%x",rk_code);
			if ( jisx0_code )
				printf("\t0x%x",jisx0_code);
			if ( jisx1_code )
				printf("\t0x%x",jisx1_code);
			if ( jisx2_code )
				printf("\t0x%x",jisx2_code);
			if ( jisx_s_code )
				printf("\t0x%x",jisx_s_code);
			printf("\t#\n");
		}
	}
	return;
}


void
tab()
{
int i;
L_CHAR code1, code2;
CODE_TABLE_HEADER * ct;
char * s;
	for ( ; ; ) {
		s = fgets(buffer,BSIZE-1,stdin);
		if ( s == 0 )
			break;
		sscanf(buffer,"%s %s %s %s %s %s\n",
			col[0],
			col[1],
			col[2],
			col[3],
			col[4],
			col[5]);
		if ( col[0][0] == '#' )
			continue;
		sscanf(col[0],"%x",&code1);
		ct = get_code_table_by_lcz(code1&(get_lc_mask(code1)));
		if ( code1 && output_type == 't' )
			printf("0x%x\t",code1);
		for ( i = 1 ; i < MAX ; i ++ ) {
			if ( col[i][0] == '#' )
				break;
			sscanf(col[i],"%x",&code2);
			ct = get_code_table_by_lcz(
				code2&get_lc_mask(code2));
			set_correspond(code1,code2);
			if ( code2 && output_type == 't' )
				printf("0x%x\t",code2);
		}
		if ( output_type == 't' )
			printf("#\n");
	}
}



int
main(int argc,char ** argv)
{
	if ( argc < 2 ) {
		fprintf(stderr,"too few argments\n");
		exit(1);
	}
	if ( strcmp(argv[1],"tab") == 0 ) {
		conv_func = tab;
	}
	else if ( strcmp(argv[1],"yasuoka-a") == 0 ) {
		conv_func = yasuoka_a;
	}
	else {
		fprintf(stderr,"invalid format\n");
		exit(1);
	}
	if ( argc >= 3 ) {
		if ( strcmp(argv[2],"c") == 0 ) {
			output_type = 'c';
		}
		else if ( strcmp(argv[2],"t") == 0 ) {
			output_type = 't';
		}
		else {
			fprintf(stderr,"invalid outpout type\n");
			exit(1);
		}
	}
	else {
		output_type = 'c';
	}
	(*conv_func)(argc,argv);
	if ( output_type == 'c' ) {
		print_code_table();
	}
	return 0;
}


