/********************************************************************
*	TownsMenu 背景画選択ﾌﾟﾛｸﾞﾗﾑ										*
********************************************************************/

#include	<stdio.h>
#include	<stdlib.h>
#include	<dos.h>
#include	<string.h>
#include	<tifflib.h>
#include	<egb.h>
#include	<msdos.cf>
#include	<conio.h>


#define		FILEMAX		(1000)
#define		FILEBUF		(8*1024)
#define		GRPHBUF		(150*1024)
#define		PALTBUF		(16*8+4)
#define		COMPBUF		(_max( DECOMP_WORK_SIZE, COMP_WORK_SIZE ))

FILE	*fp;
char	*gwork;
char	*fname;
char	*sfile;
char	*dfile;
char	*fbp;
char	*gbp;
char	*pbp;
char	*cbp;
int		bpp;
int		gx;
int		gy;
int		cmp;
int		fil;
long	str;
long	clt;
int		dx;
int		dy;
int		fsize;


/****************************************************************
*	ﾍﾙﾌﾟ画面表示												*
****************************************************************/
void	help( void )	{
	printf("************************************************************\n");
	printf("*  TownsMenu 背景画選択ﾌﾟﾛｸﾞﾗﾑ (TIFSEL-V1.0L10  by BUN)    *\n");
	printf("*                                                          *\n");
	printf("*   (1)run386 tifsel -S[num] *.tif                         *\n");
	printf("*      *.tifから背景画を選択する                           *\n");
	printf("*      (numで指定した数のﾌｧｲﾙから選択)                     *\n");
	printf("*      (ただし、ﾌｧｲﾙ数は最大1000とする)                    *\n");
	printf("*                                                          *\n");
	printf("*   (2)run386 tifsel -C TIFFFILE.TIF                       *\n");
	printf("*      TIFFFILE.TIFを同ﾌｧｲﾙ名で圧縮保存する                *\n");
	printf("*                                                          *\n");
	printf("*   (3)run386 tifsel -G TIFFFILE.TIF [pg] [md]             *\n");
	printf("*      画面表示している画像をTIFFFILE.TIFに圧縮保存する    *\n");
	printf("*      pg:ﾍﾟ-ｼﾞ番号(省略時0), md:画面ﾓ-ﾄﾞ(省略時1)         *\n");
	printf("*                                                          *\n");
	printf("*   (4)run386 tifsel -D TIFFFILE.TIF                       *\n");
	printf("*      TIFFFILE.TIFを画面に表示する                        *\n");
	printf("*                                                          *\n");
	printf("*                                                          *\n");
	printf("*            << 何かｷ-を押してください！ >>                *\n");
	printf("************************************************************\n");

	while( _kbhit()==0 );
	exit( -1 );
}


/****************************************************************
*	ﾒﾓﾘ不足														*
****************************************************************/
void	memerr( void )	{
	printf("メモリ不足です！！ \n");
	exit( -1 );
}


/****************************************************************
*	画面へﾃﾞ-ﾀを表示する										*
****************************************************************/
int		disp_data( void )	{
	char	para[64];
	int		sx;
	int		sy;

	EGB_init( gwork, EgbWorkSize );
	if( bpp==1 || bpp==4 )	{
		EGB_resolution( gwork, 0, 3 );
		EGB_color( gwork, 0,  0 );
		EGB_color( gwork, 1, 15 );
		if( clt ) EGB_palette( gwork, 1, pbp );

		sx=(640-gx)/2;
		sy=(480-gy)/2;
	}
	else if( bpp==16 )	{
		EGB_resolution( gwork, 0, 10 );
		EGB_displayStart( gwork, 3, 0, 0 );
		EGB_displayStart( gwork, 0, 0, 0 );
		EGB_displayStart( gwork, 1, 0, 0 );
		EGB_displayStart( gwork, 2, 2, 2 );
		EGB_displayStart( gwork, 3, 320, 240 );

		sx=(320-gx)/2;
		sy=(240-gy)/2;
	}
	else	{
		return( -1 );
	}

	DWORD( para+ 0 )=(long)gbp;
	WORD ( para+ 4 )=getds();
	WORD ( para+ 6 )=sx;
	WORD ( para+ 8 )=sy;
	WORD ( para+10 )=sx+gx-1;
	WORD ( para+12 )=sy+gy-1;
	if( bpp!=1 )	{
		EGB_putBlock( gwork, 0, para );
	}
	else	{
		EGB_clearScreen( gwork );
		EGB_putBlockColor( gwork, 0, para );
	}

	return( 0 );
}


/****************************************************************
*	画面からﾃﾞ-ﾀをﾛ-ﾄﾞする										*
****************************************************************/
int		load_scrn( int pg, int md )	{
	char	para[64];

	EGB_getModeInfo( md, NULL, NULL, &gx, &gy, &bpp );
	if( bpp==2 )	{
		bpp=1;
	}
	else if( bpp==16 )	{
		bpp=4;
	}
	else if( bpp==32768 )	{
		bpp=16;
	}
	else	{
		return( -1 );
	}

	EGB_getPalette( pg, pbp );
	clt=1;

	EGB_resolution( gwork, pg, md );
	EGB_writePage( gwork, pg );

	DWORD( para+ 0 )=(long)gbp;
	WORD ( para+ 4 )=getds();
	WORD ( para+ 6 )=0;
	WORD ( para+ 8 )=0;
	WORD ( para+10 )=gx-1;
	WORD ( para+12 )=gy-1;
	EGB_getBlock( gwork, para );

	return( 0 );
}


/****************************************************************
*	ﾌｧｲﾙからﾃﾞ-ﾀをﾛ-ﾄﾞする										*
****************************************************************/
int		put_data( char *bp, int lofs, int line )	{
	if( lofs<gy )	{
		memcpy( gbp+lofs*dx*bpp/8, bp, line*dx*bpp/8 );
		return( 0 );
	}
	else	{
		return( -1 );
	}
}

int		get_file( char *bp, long size )	{
	if( fread( bp, 1, size, fp ) == size )	{
		return( 0 );
	}
	else	{
		return( -1 );
	}
}

int		load_file( char *file )	{
	if( (fp=fopen( file,"rb" ))==NULL ) return(-1);

	fread( fbp, 1, FILEBUF, fp );
	if( TIFF_getHead( fbp, FILEBUF )<0 ) return(-1);

	bpp=TIFF_checkMode( &gx, &gy, &cmp, &fil, &str, &clt );
	if( bpp==1 || bpp==4 )	{
		if( gx>640 || gy>480 ) return(-1);
		dx=(int)((gx+7)/8)*8;
		dy=GRPHBUF/(dx*bpp/8);
	}
	else if( bpp==16 )	{
		if( gx>320 || gy>240 ) return(-1);
		dx=gx;
		dy=GRPHBUF/(dx*bpp/8);
	}
	else	{
		return( -1 );
	}

	if( clt ) TIFF_getPal( pbp );

	TIFF_setLoadFunc( put_data, get_file );
	TIFF_loadImage( bpp, gx, gy, str, fil, cmp, gbp, dx, dy, cbp );

	fclose( fp );
	return( 0 );
}


/****************************************************************
*	ﾌｧｲﾙへﾃﾞ-ﾀをｾ-ﾌﾞする										*
****************************************************************/
int		put_file( char *bp, long size )	{
	if( fwrite( bp, 1, size, fp ) == size )	{
		fsize += size;
		return( 0 );
	}
	else	{
		return( -1 );
	}
}

int		get_data( char *bp, int lofs, int line )	{
	if( lofs<gy )	{
		memcpy( bp, gbp+lofs*dx*bpp/8, line*dx*bpp/8 );
		return( 0 );
	}
	else	{
		return( -1 );
	}
}

int		save_file( char *file, int c )	{
	int		size;
	char	*pbpw;

	if( bpp==1 || bpp==4 )	{
		if( gx>640 || gy>480 ) return(-1);
		dx=(int)((gx+7)/8)*8;
		dy=FILEBUF/(dx*bpp/8);
	}
	else if( bpp==16 )	{
		if( gx>320 || gy>240 ) return(-1);
		dx=gx;
		dy=FILEBUF/(dx*bpp/8);
	}
	else	{
		return( -1 );
	}

	if( (fp=fopen( file,"wb" ))==NULL ) return(-1);

	size=TIFF_setHead( fbp, bpp, gx, gy, 0, NULL );
	fwrite( fbp, 1, size, fp );

	fsize=0;
	TIFF_setSaveFunc( put_file, get_data );
	TIFF_saveImage( bpp, gx, gy, c, fbp, FILEBUF, gbp, dx, gy, cbp );

	if( c==1 )	{
		size=0;
	}
	else	{
		size=fsize;
	}
	if( clt )	{
		pbpw=pbp;
	}
	else	{
		pbpw=NULL;
	}

	rewind( fp );
	size=TIFF_setHead( fbp, bpp, gx, gy, size, pbpw );
	fwrite( fbp, 1, size, fp );

	fclose( fp );
	return( 0 );
}


/****************************************************************
*	ﾌｧｲﾙのﾊﾟｽ作成												*
****************************************************************/
void	make_path( char *fpath, char *path, char *file )	{
	char	*fwp;

	if( path!=NULL )	{
		strcpy( fpath, path );
		if( (fwp=strrchr( fpath, '\\' ))!=NULL )	{
			fwp++;
		}
		else if( (fwp=strchr( fpath, ':' ))!=NULL )	{
			fwp++;
		}
		else	{
			fwp=fpath;
		}
	}
	else	{
		fwp=fpath;
	}
	strcpy( fwp, file );
}


/****************************************************************
*	TIFFﾌｧｲﾙの選択ﾙ-ﾁﾝ											*
****************************************************************/
void	select_tiff( int num, char *path )	{
	struct find_t		file;
	struct dostime_t	time;
	int					x;
	int					t;
	char				*tmenu;

	if( !_dos_findfirst( path, _A_NORMAL, &file ) )	{
		if( num<1 || num>FILEMAX ) num=FILEMAX;
		for( x=0;; )	{
			strcpy( &fname[x*13], file.name );
			x++;
			if( x>=num ) break;
			if( _dos_findnext( &file ) ) break;
		}

		_dos_gettime( &time );
		x=((time.hsecond
            +100*(time.second
            + 60*(time.minute
            + 60* time.hour  )))/8) % x;
		make_path( sfile, path, &fname[x*13] );

		if( (tmenu=getenv("TMENU"))!=NULL )	{
			strcpy( dfile, tmenu );
			t=strlen(dfile)-1;
			if( dfile[t]=='\\' )	{
				dfile[t]='\0';
			}
		}
		else	{
			strcpy( dfile,"\0" );
		}
		strcat( dfile, "\\tmenu.tif" );

		printf( "ﾌｧｲﾙ展開 = %s ", sfile );
		if( load_file( sfile )==0 )	{
			printf( " -> %s \n", dfile );
			save_file( dfile, 1 );
		}
	}
}


/****************************************************************
*	TIFFﾌｧｲﾙの圧縮ﾙ-ﾁﾝ											*
****************************************************************/
void	comp_tiff( char *path )	{
	struct find_t		file;

	if( !_dos_findfirst( path, _A_NORMAL, &file ) )	{
		while( 1 )	{
			make_path( sfile, path, file.name );
			if( load_file( sfile )==0 )	{
				printf( "ﾌｧｲﾙ圧縮 = %s \n", sfile );
				save_file( sfile, 5 );
			}
			if( _dos_findnext( &file ) ) break;
		}
	}
}


/****************************************************************
*	画面からTIFFﾌｧｲﾙ作成ﾙ-ﾁﾝ									*
****************************************************************/
void	read_tiff( char *path, int pg, int md )	{
	if( load_scrn( pg, md )==0 )	{
		printf( "ﾌｧｲﾙ作成 = %s \n", path );
		save_file( path, 5 );
	}
}


/****************************************************************
*	画面にTIFFﾌｧｲﾙ表示ﾙ-ﾁﾝ										*
****************************************************************/
void	disp_tiff( char *path )	{
	struct find_t		file;

	if( !_dos_findfirst( path, _A_NORMAL, &file ) )	{
		while( 1 )	{
			make_path( sfile, path, file.name );
			if( load_file( sfile )==0 )	{
				disp_data();
				while( _kbhit()==0 );
				while( _kbhit() )	{
					_getche();
				}
			}
			if( _dos_findnext( &file ) ) break;
		}
	}
}


/****************************************************************
*	ﾒｲﾝﾙ-ﾁﾝ(ｺﾏﾝﾄﾞ分岐)											*
****************************************************************/
void	main( int ac, char **av )	{
	int		num;
	int		pg;
	int		md;

	if( (gwork=malloc( EgbWorkSize ))==NULL ) memerr();
	if( (fname=malloc( FILEMAX*13 ))==NULL ) memerr();
	if( (sfile=malloc( 256 ))==NULL ) memerr();
	if( (dfile=malloc( 256 ))==NULL ) memerr();
	if( (fbp=malloc( FILEBUF ))==NULL ) memerr();
	if( (gbp=malloc( GRPHBUF ))==NULL ) memerr();
	if( (pbp=malloc( PALTBUF ))==NULL ) memerr();
	if( (cbp=malloc( COMPBUF ))==NULL ) memerr();

	if( ac<3 ) help();
	if( *(av[1]+0)!='-' ) help();
	switch( *(av[1]+1) )	{
		case	's':
		case	'S':
			num=atoi( av[1]+2 );
			select_tiff( num, av[2] );
			break;

		case	'c':
		case	'C':
			comp_tiff( av[2] );
			break;

		case	'g':
		case	'G':
			if( ac>3 )	{
				pg=atoi( av[3] );
			}
			else	{
				pg=0;
			}
			if( ac>4 )	{
				md=atoi( av[4] );
			}
			else	{
				md=1;
			}
			read_tiff( av[2], pg, md );
			break;

		case	'd':
		case	'D':
			disp_tiff( av[2] );
			break;

		default:
			help();
	}

	free( fname );
	free( sfile );
	free( dfile );
	free( fbp );
	free( gbp );
	free( pbp );
	free( cbp );
}
