/*************************************************************************
*	アイコンの色を変換する
*************************************************************************/

#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<ctype.h>

#define	CONST	const
#define	UCHAR	unsigned char
#define	SHORT	short

typedef	struct
{
	char	idCode[10];
	SHORT	version;
	SHORT	tblNum;
	SHORT	icnNum;
	long	icnOfs;
	char	rsv[12];
} ICNHEAD_T;

typedef	struct
{
	SHORT	id;
	SHORT	icnNum;
	SHORT	typ;
	SHORT	icnSiz;
	long	infOfs;
	long	ptnOfs;
	char	rsv[16];
} ICNTBL_T;

typedef	struct
{
	SHORT	id;
	SHORT	xb,	yb;
	SHORT	xs,	ys;
	long	col;
	SHORT	siz;
	char	rsv[4];
	long	ptnOfs;
	long	mskOfs;
	char	rsv2[20];
} ICNINFO_T;

unsigned char col_tbl[16] =
{/*	 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15	*/
	 0,12, 7, 6, 4, 5, 6, 4, 8, 9,10,11,12,13,14,15
};
unsigned char	cnv_tbl[256];

void	make_cnvtbl(void)	/* 色変換テーブルの作成	*/
{
	int		i;

	for ( i = 0; i < 256; ++i )
		cnv_tbl[i] = (col_tbl[i>>4]<<4) | col_tbl[i&15];
}


void	icn_chgcol( CONST char *fn )
{
	int			i;
	FILE		*rfp;
	ICNHEAD_T	icnHead;
	ICNTBL_T	icnTbl;
	ICNINFO_T	icnInfo;

	if ( (rfp = fopen(fn,"r+b")) == NULL )
	{
		fprintf(stderr,"@ file open error!! (%s)\n", fn);
		exit(1);
	}
	/* ヘッダ情報の読み取り	*/
	fseek(rfp,0l,SEEK_SET);
	fread(&icnHead,sizeof(ICNHEAD_T),1,rfp);
	if ( memcmp(icnHead.idCode, "ICNFILE", 7) != 0 )
	{
		fclose(rfp);
		fprintf(stdout,"@ icon file header error!!\n");
		exit(1);
	}
	if ( icnHead.tblNum == 0 || icnHead.icnNum == 0 )
	{
		fclose(rfp);
		fprintf(stdout,"@ アイコンデータが存在しません！！\n");
		exit(1);
	}

	for ( i = 0; i < icnHead.tblNum; ++i )
	{
		int		j;

		fseek(rfp, (long)sizeof(ICNHEAD_T) + (long)i*(long)sizeof(ICNTBL_T), SEEK_SET);
		fread(&icnTbl, sizeof(ICNTBL_T),1, rfp);

		for ( j = 0; j < icnTbl.icnNum; ++j )
		{
			UCHAR		*buf;

			fprintf(stderr,"icon table offset $%08lX\n", icnTbl.infOfs);
			fseek(rfp,icnTbl.infOfs, SEEK_SET);
			fread(&icnInfo, sizeof(ICNINFO_T),1,rfp);

			icnTbl.infOfs += sizeof(ICNINFO_T);

			fprintf(stderr,"icon pattern offset $%08lX\n", icnInfo.ptnOfs);

			if ( (buf = malloc(icnInfo.siz)) == NULL )
			{
				fprintf(stderr,"Memory allocation error!!n");
				exit(1);
			}
			fseek(rfp,icnInfo.ptnOfs,SEEK_SET);
			fread((char *)buf, (size_t)icnInfo.siz, 1, rfp);

			fprintf(stderr,"\n/* ID:%03d,#%03d, icon size (%02d,%02d) %3d bytes %d color(s)*/\n", 
			    icnInfo.id>>8, icnInfo.id & 0xFF, icnInfo.xs, icnInfo.ys,
			    icnInfo.siz, icnInfo.col );

			if ( (icnInfo.id>>8) == 9  && icnInfo.id >= 2316 && icnInfo.col == 16 )
			{
				int		k;

				fprintf(stderr,"# convert\n");
				/* モノクロデータに変換	*/
				for ( k = 0; k < icnInfo.siz; ++k)
					buf[k] = cnv_tbl[buf[k]];
				fseek(rfp,icnInfo.ptnOfs,SEEK_SET);
				fwrite((char *)buf, (size_t)icnInfo.siz, 1, rfp);
			}
			free(buf);
		}
	}
	fclose(rfp);
}

void	help(void)
{	exit(1);
}

void	main(int argc,char *argv[])
{
	int		i;
	char	*fn = NULL;
	char	*writePath = NULL;

	for ( i = 1; i < argc; ++i )
	{
		char	*s;

		s = argv[i];
		if ( *s == '?' )
			help();
		if ( *s == '-' || *s == '/' )
		{	/* option(s)	*/
			++s;
			if ( *s == '?' )
				help();
			if ( tolower(*s) == 'w' )
			{
				writePath = &s[1];
			}
		} else if ( fn == NULL )
			fn = s;
	}
	if ( fn == NULL )
		fn = "towns.icn";

	make_cnvtbl();
	icn_chgcol( fn );

	exit(0);
}

