#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>		// filelength()
#include "defines.h"
#include "astring.h"
#include "u2stbl.h"

// GORRYさんのVTwentyOneセット内のu2stbl.cを改良
// 変換テーブルをファイルから読み込むタイプ

#define DEBUG 0

static	struct U2S *U2Stbl;	// 変換テーブルワーク
static	int tblsize=0;		// テーブル要素数

#define	TBLNAME	"U2STable"	// テーブルファイル名=テーブル識別子

int OpenUni2SJisF( unsigned char *path )
// Unicode→Shift-JIS変換テーブルを読み込む
{
FILE *fp;
long size,ret;
unsigned char fname[MAXPATH];
	// pathの位置にあるTBLNAME.datを読み込む
	// 通常pathはargv[0]なので実行ファイルのフルパス名である
	exedir(path,fname);	/* drv+dir\ ; \が末尾に来る行は//のコメントにしてはいけない */
	strcat(fname,TBLNAME);
	strcat(fname,".dat");
	#if DEBUG
	printf("fname=%s\n",fname);
	#endif
	
	// テーブルオープン
	if ((fp=fopen(fname,"rb"))==NULL) {
		// テーブルが見つからない
		return(2);
	}
	// ファイルヘッダー読み込み
	ret=fread(fname,sizeof(TBLNAME)-1,1,fp); // EOSは入ってない
	if (ret>0) {
		// ファイルヘッダー確認
		if (memcmp(fname,TBLNAME,sizeof(TBLNAME)-1)) {
			// 不一致
			fclose(fp);
			return(4);
		}
		// サイズチェック
		size=filelength(fileno(fp))-(sizeof(TBLNAME)-1);
		#if DEBUG
		printf("size=%ld\n",size);
		#endif
		// ワークエリア確保
		if ((U2Stbl=(struct U2S *)malloc(size))==NULL) {
			// テーブル用のメモリーが確保出来ない
			return(3);
		}
		// 読み込み
		ret=fread(U2Stbl,size,1,fp);
		// テーブルサイズ計算
		tblsize=size/sizeof( struct U2S );
	}
	// ファイルクローズ
	fclose(fp);
	return(ret==0); // ret==0なら読み込みエラー
}

void CloseUni2SJisF()
{
	// テーブル用メモリー解放だけ
	free(U2Stbl);
	tblsize=0;	// 未準備に戻す
}

SJisCode Uni2SJisF( UniCode uni )
// Unicode→Shift-JIS変換
{
int move = tblsize;
int idx = 0;
int sub;
	// 英数字記号はそのままのコードである（ここは常時変換可能）
	if (uni>=0x20 && uni<=0x7e) return((SJisCode)uni); // そのまま
	
	if (tblsize==0) return(L'※'); // テーブルが準備出来てないので変換不可
	
	// テーブル利用で変換
	// 中点法によるコード比較
	while (1) {
		#if 0
		printf( "%d ", idx );
		#endif
		
		if ( idx >= tblsize ) {
			sub = -1;
		} else {
			sub = uni - U2Stbl[idx].uni;
			if ( sub == 0 ) break;
		}
		if ( move == 1 ) {
			// 変換不可文字である
			return(L'※'); // とりあえずこれを返しておく
		}
		move = (move+1)/2; // 半分移動する
		idx += ( sub<0 ? -move : move ); // コード差分の符号によって移動方向を決める
	}
	return ( U2Stbl[idx].sjis );
}

#if (DEBUG)
#include <ctype.h>

main(int argc,unchar *argv[])
{
int i;
UniCode uni;
SJisCode sjis;
	i=OpenUni2SJisF(argv[0]);
	if (i) {
		printf("実行ファイルと同じディレクトリにU2STable.datが見つからない:%d\n",i);
		exit(100);
	}
	
	for ( i=0; i<tblsize; i++ ) {
		uni = U2Stbl[i].uni;
#if 0
		printf( "\n%d: %04X: ", i, uni );
#endif
		sjis = Uni2SJis( uni );
		if ( U2Stbl[i].sjis != sjis ) {
			printf( "\n%d %04X: %04X: notfound", i, uni, sjis );
		}
	}
	printf( "%d種類\n", tblsize );
	CloseUni2SJisF();
}

#endif
