#include <stdio.h>
#include <string.h>
#include <dir.h>
#include <sys/extender.h>
#include <egb.h>
#include "fsdat.c"

#define ERR		1
#define NOERR	0

#define A_RAF	0x00
#define A_ROF	0x01
#define A_HND	0x02
#define A_SYS	0x04
#define A_SUB	0x10

#define	ON		1
#define	OFF		0

typedef struct
{
	char	name[9];
	char	kaku[4];
	char	attrib;
} FILEINF ;


extern int	FS_fileSelect( char *, char *, char * );
extern int	FS_locate( int, int );
static int	FS_x = 0;
static int	FS_y = 0;
static char	c_dir[256];
static char	drv[2];
static char *egbwork;
static void	symbol( char *, int, int, char * );

static void	symbol( char *egbwork, int x, int y, char *str )
{
	int		l;

	l = strlen( str );

	{
		char	para[l+6];
	 	WORD( para + 0 ) = x;
		WORD( para + 2 ) = y;
		WORD( para + 4 ) = strlen( str );
		strcpy( para + 6, str );
		EGB_sjisString( egbwork, para );
	}

	return;
}

int		FS_locate( int x, int y )
{
	if( x<0 || x>511 || y<0 || y>263 )
		return ERR;

	FS_x = x;
	FS_y = y;

	return NOERR;
}

static void	FS_end( char *grp_buf )
{
	MOS_disp( 0 );
	EGB_writeMode( egbwork, 0 );
	EGB_putRect( egbwork, 0, grp_buf, FS_x, FS_y, 127+FS_x, 215+FS_y );
	return;
}

static int	upButton( int cx, int cy )
{
	static int	UB_flg = OFF;

	if( cx<108+FS_x || cy<49+FS_y || cx>122+FS_x || cy>63+FS_y )
	{
		if( UB_flg == ON )
		{
			UB_flg = OFF;
			MOS_disp( 0 );
			EGB_writeMode( egbwork, 4 );
			EGB_paintMode( egbwork, 0x22 );
			EGB_foreColor( egbwork, 15 );
			EGB_paintColor( egbwork, 15 );
			EGB_box( egbwork, 108+FS_x, 49+FS_y, 122+FS_x, 63+FS_y );
			MOS_disp( 1 );
		}
		return 0;
	}

	if( UB_flg != ON )
	{
		UB_flg = ON;
		MOS_disp( 0 );
		EGB_writeMode( egbwork, 4 );
		EGB_paintMode( egbwork, 0x22 );
		EGB_foreColor( egbwork, 15 );
		EGB_paintColor( egbwork, 15 );
		EGB_box( egbwork, 108+FS_x, 49+FS_y, 122+FS_x, 63+FS_y );
		MOS_disp( 1 );
	}

	return 1;
}

static int	downButton( int cx, int cy )
{
	static int	DB_flg = OFF;

	if( cx<108+FS_x || cy<196+FS_y || cx>122+FS_x || cy>210+FS_y )
	{
		if( DB_flg == ON )
		{
			DB_flg = OFF;
			MOS_disp( 0 );
			EGB_writeMode( egbwork, 4 );
			EGB_paintMode( egbwork, 0x22 );
			EGB_foreColor( egbwork, 15 );
			EGB_paintColor( egbwork, 15 );
			EGB_box( egbwork, 108+FS_x, 196+FS_y, 122+FS_x, 210+FS_y );
			MOS_disp( 1 );
		}
		return 0;
	}

	if( DB_flg != ON )
	{
		DB_flg = ON;
		MOS_disp( 0 );
		EGB_writeMode( egbwork, 4 );
		EGB_paintMode( egbwork, 0x22 );
		EGB_foreColor( egbwork, 15 );
		EGB_paintColor( egbwork, 15 );
		EGB_box( egbwork, 108+FS_x, 196+FS_y, 122+FS_x, 210+FS_y );
		MOS_disp( 1 );
	}

	return 1;
}

static int	incDriveNum( int cx, int cy )
{
	static int	ID_flg = OFF;

	if( cx<39+FS_x || cy<27+FS_y || cx>55+FS_x || cy>44+FS_y )
	{
		if( ID_flg == ON )
		{
			ID_flg = OFF;
			MOS_disp( 0 );
			EGB_writeMode( egbwork, 4 );
			EGB_paintMode( egbwork, 0x22 );
			EGB_foreColor( egbwork, 15 );
			EGB_paintColor( egbwork, 15 );
			EGB_box( egbwork, 39+FS_x, 27+FS_y, 55+FS_x, 44+FS_y );
			MOS_disp( 1 );
		}
		return 0;
	}

	if( ID_flg != ON )
	{
		ID_flg = ON;
		MOS_disp( 0 );
		EGB_writeMode( egbwork, 4 );
		EGB_paintMode( egbwork, 0x22 );
		EGB_foreColor( egbwork, 15 );
		EGB_paintColor( egbwork, 15 );
		EGB_box( egbwork, 39+FS_x, 27+FS_y, 55+FS_x, 44+FS_y );
		MOS_disp( 1 );
	}

	return 1;

}

static int	decDriveNum( int cx, int cy )
{
	static int	DD_flg = OFF;

	if( cx<9+FS_x || cy<27+FS_y || cx>25+FS_x || cy>44+FS_y )
	{
		if( DD_flg == ON )
		{
			DD_flg = OFF;
			MOS_disp( 0 );
			EGB_writeMode( egbwork, 4 );
			EGB_paintMode( egbwork, 0x22 );
			EGB_foreColor( egbwork, 15 );
			EGB_paintColor( egbwork, 15 );
			EGB_box( egbwork, 9+FS_x, 27+FS_y, 25+FS_x, 44+FS_y );
			MOS_disp( 1 );
		}
		return 0;
	}

	if( DD_flg != ON )
	{
		DD_flg = ON;
		MOS_disp( 0 );
		EGB_writeMode( egbwork, 4 );
		EGB_paintMode( egbwork, 0x22 );
		EGB_foreColor( egbwork, 15 );
		EGB_paintColor( egbwork, 15 );
		EGB_box( egbwork, 9+FS_x, 27+FS_y, 25+FS_x, 44+FS_y );
		MOS_disp( 1 );
	}

	return 1;
}

static int	fileNameCheck( int cx, int cy )
{
	static int	s = 0;

	if( cx<10+FS_x || cy<50+FS_y || cx>105+FS_x || cy>209+FS_y )
	{
		if( s > 0 )
		{
			s = 0;
		}
		return 0;
	}

	if( s != (cy-FS_y-50)/16 + 1 )
	{
		s = (cy-FS_y-50)/16 + 1;
	}

	return s;
}

int		FS_fileSelect( char *w, char *wild, char *path )
{
	struct ffblk	fb;
	int		attrib = 0x17;
	char	wildcard[60];
	FILEINF	f_inf[128];
	int		fnum,ptop,i,j,sw,cx,cy,sel,loop_f;
	char	*fname;
	char	buf1[64];
	char	testname[256];
	char	grp_buf[13824];

	egbwork = w;
	drv[0] = 'A' + _dos_get_default_disk_number();
	drv[1] = 0;
	getcwd( c_dir, 60 );

	EGB_writeMode( egbwork, 0 );
	EGB_getRect( egbwork, grp_buf, FS_x, FS_y, 127+FS_x, 215+FS_y );
	EGB_putRect( egbwork, 0, FS_grp_data, FS_x, FS_y, 127+FS_x, 215+FS_y );

	MOS_sysIcon( 81, 0, 0, 0 );
	MOS_color( 0, 15 );
	MOS_writePage( 1 );
	MOS_disp( 1 );

START:
	MOS_disp( 0 );

	strcpy( wildcard, drv );
	strcat( wildcard, ":" );
	strcat( wildcard, c_dir );
	if( *(c_dir+1) )
		strcat( wildcard, "/" );
	strcat( wildcard, wild );

	fnum = 0;
	if( findfirst( wildcard, &fb, attrib ) == 0 )
	{
		if( (f_inf[fnum].attrib = fb.ff_attrib) & A_SUB )
		{
			strcpy( f_inf[fnum].name, fb.ff_name );
		}
		else
		{
			char	*s,*t;

			s = f_inf[fnum].name;
			t = fb.ff_name;
			while( *t != 0 && *t != '.' )
			{
				*s++ = *t++;
			}
			*s = 0;
			++t;
			strcpy( f_inf[fnum].kaku, t );
		}

		++fnum;
		while( findnext( &fb ) == 0 )
		{
			if( (f_inf[fnum].attrib = fb.ff_attrib) & A_SUB )
			{
				strcpy( f_inf[fnum].name, fb.ff_name );
			}
			else
			{
				char	*s,*t;

				s = f_inf[fnum].name;
				t = fb.ff_name;
				while( *t != 0 && *t != '.' )
				{
					*s++ = *t++;
				}
				*s = 0;

				if( *t == 0 )
					f_inf[fnum].kaku[0] = 0;
				else
				{
					++t;
					strcpy( f_inf[fnum].kaku, t );
				}
			}
			++fnum;
		}
	}

	EGB_writeMode( egbwork, 0 );
	EGB_paintMode( egbwork, 0x22 );
	EGB_foreColor( egbwork, 0 );
	EGB_paintColor( egbwork, 0 );
	EGB_box( egbwork, 10+FS_x, 8+FS_y, 105+FS_x, 23+FS_y );
	EGB_box( egbwork, 58+FS_x, 28+FS_y, 105+FS_x, 43+FS_y );
	EGB_box( egbwork, 28+FS_x, 28+FS_y, 36+FS_x, 43+FS_y );

	EGB_foreColor( egbwork, 15 );
	strcpy( buf1, c_dir );
	buf1[12] = 0;
	symbol( egbwork, 10+FS_x, 23+FS_y, buf1 );
	symbol( egbwork, 58+FS_x, 43+FS_y, wild );
	symbol( egbwork, 28+FS_x, 43+FS_y, drv );

	do
	{
		MOS_rdpos( &sw, &cx, &cy );
	}
	while( sw );

	loop_f = 1;
	ptop = 0;
	while( loop_f )
	{
		EGB_writeMode( egbwork, 0 );
		EGB_paintMode( egbwork, 0x22 );
		EGB_foreColor( egbwork, 0 );
		EGB_paintColor( egbwork, 0 );
		EGB_box( egbwork, 10+FS_x, 50+FS_y, 105+FS_x, 209+FS_y );

		EGB_foreColor( egbwork, 15 );
		for( i=0; i<10; i++ )
		{
			if( ptop+i < fnum )
			{
				if( f_inf[ptop+i].attrib & A_SUB )
				{
					strcpy( buf1, "<" );
					strcat( buf1, f_inf[ptop+i].name );
					strcat( buf1, ">" );
					symbol( egbwork, 10+FS_x, i*16+65+FS_y, buf1 );
				}
				else
				{
					strcpy( buf1, f_inf[ptop+i].name );
					strcat( buf1, "." );
					strcat( buf1, f_inf[ptop+i].kaku );
					symbol( egbwork, 10+FS_x, i*16+65+FS_y, buf1 );
/*
					symbol( egbwork, 10+FS_x, i*16+65+FS_y, f_inf[ptop+i].name );
					symbol( egbwork, 74+FS_x, i*16+65+FS_y, "." );
					symbol( egbwork, 82+FS_x, i*16+65+FS_y, f_inf[ptop+i].kaku );
*/
				}
			}
		}

		MOS_disp( 1 );

		sw = 0;
		while( (sw & 2) == 0 )
		{
			MOS_rdpos( &sw, &cx, &cy );

			if( incDriveNum( cx, cy ) && (sw & 1) )
			{
				drv[0] = ( drv[0] == 'Z' )? 'A':++(drv[0]);
				*(c_dir+1) = 0;
				loop_f = 0;
				sw = 5;
				break;
			}
			if( decDriveNum( cx, cy ) && (sw & 1) )
			{
				drv[0] = ( drv[0] == 'A' )? 'Z':--(drv[0]);
				*(c_dir+1) = 0;
				loop_f = 0;
				sw = 5;
				break;
			}

			if( upButton( cx, cy ) && (sw & 1) && ptop>0 )
			{
				--ptop;
				break;
			}
			if( downButton( cx, cy ) && (sw & 1) && ptop+10<fnum )
			{
				++ptop;
				break;
			}
			if( ( sel = fileNameCheck( cx, cy ) ) && (sw & 1) )
			{
				if( ptop+sel-1 < fnum )
				{
					loop_f = 0;
					break;
				}
			}
		}
		if( sw & 2 )
		{
			FS_end( grp_buf );
			return ERR;
		}
	}

	if( sw == 5 )
		goto START;

	if( f_inf[ptop+sel-1].attrib & A_SUB )
	{
		if( strcmp( f_inf[ptop+sel-1].name, "." ) == 0 )
		{
			goto START;
		}
		if( strcmp( f_inf[ptop+sel-1].name, ".." ) == 0 )
		{
			char	*s;
			s = c_dir;

			while( *s )
				++s;

			while( *s != '/' )
				--s;

			if( s == c_dir )
				*(c_dir+1) = 0;
			else
				*s = 0;

			goto START;
		}

		if( *(c_dir+1) )
			strcat( c_dir, "/" );
		strcat( c_dir, f_inf[ptop+sel-1].name );
		goto START;
	}

	strcpy( path, drv );
	strcat( path, ":" );
	strcat( path, c_dir );
	if( *(c_dir+1) )
		strcat( path, "/" );
	strcat( path, f_inf[ptop+sel-1].name );
	strcat( path, "." );
	strcat( path, f_inf[ptop+sel-1].kaku );

	FS_end( grp_buf );
	return NOERR;
}
