#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <ctype.h>
#include    <setjmp.h>
#include    <mos.h>
#include    <fmcfrb.h>
#include    <kkstr2.h>
#include    "scrn.h"
#include    "keyword.h"
#include    "graphic.h"
#include    "dir.h"
#include    "file.h"
#include    "coldef.h"
#include    "exec.h"

#define	TRUE	1
#define	FALSE	0
#define	ERR	(-1)

extern	char	*crent_drive;
extern	char	work[];
extern	int	act_fwc_cdrom;

	char	index_file[128];
	int	cur_x=0;
	int	cur_y=0;
static	int	kb_act=0;
static	int 	kb_flg=0;
static	int 	ch_bak=0;
static	unsigned ec_bak=0;
static	int	kan_col[]={ 15,14,2,13,4,5,6,8,7,9,10,11,12,3,6,0 };
static	jmp_buf	sysreturn;

char	*strdup();
int	CTRL_sysdrv();
int	CTRL_command(int code, char *str);
int	PROG_command(char *str);

void	GetDspPos(int *x, int *y)
{
    *x = cur_x;
    *y = cur_y;
}
void	Tango_Touroku(char *str)
{
    memcpy(str,0,80);
}
void	INKEY_start(void)
{
    kb_act = 1;
    KYB_clrbuf();
    KAN_disp(KAN_DISPON);
}
void	INKEY_end(void)
{
    kb_act = 0;
    KAN_disp(KAN_DISPOFF);
}
int	kbhit(void)
{
    if ( kb_flg != 0 )
	return 1;

    do {
	ch_bak = KYB_read(1,&ec_bak);
    } while ( KAN_inpchk() == KAN_MISET );

    if ( (ec_bak & 0xFF00) == 0xFF00 )
	return 0;

    kb_flg = 1;
    return 1;
}
int	getch(void)
{
    if ( kbhit() == 0 )
	return EOF;

    kb_flg = 0;
    if ( ch_bak  != 0xFFFF ) {
	if ( (ch_bak & 0x8000) != 0 || (ec_bak & 0xFF00) > 0x5100 )
	    ch_bak = 0xFFFF;
	switch(ec_bak&0xFF00) {
	case 0x7300: ch_bak = 0x000D; break;
	case 0x7200: ch_bak = 0x001B; break;
	}
    }
    return ((ch_bak & 0xFF00) == 0xFF00 ? EOF:ch_bak);
}
void	KAN_init()
{
    KANJ    kana;

    kana.scrn   = KAN_SCRN16;   /*  画面ﾓｰﾄﾞは16色モード               */
    kana.egbw   = work;         /*  EGBのﾜｰｸｱﾄﾞﾚｽを設定する            */
    kana.wPage  = 0;            /*  表示ページを0にする                */
    kana.mosAp  = KAN_MOSON;    /*  マウスの制御をする                 */
    kana.gets   = Tango_Touroku;/*  文字取得ﾙｰﾁﾝの設定                 */
    kana.getPos = GetDspPos;    /*  未確定文字列表示位置取得関数の設定 */
    kana.maxX   = 639;          /*  画面の最大X座標                    */
    kana.maxY   = 479;          /*  画面の最大Y座標                    */

    KAN_prepare(&kana);
    KAN_setClrTbl(kan_col);
}
int	PRG_clic(int no)
{
    int     i,n,a;
    int     fg;
    char    tmp[256];

    if ( prg_tbl[no] == NULL )
	return (no + PRG_NO);

    if ( act_fwc_cdrom != prg_tbl[no]->cdrom ) {
	if ( pause("フリコレ%dをセットしてください",
		prg_tbl[no]->cdrom) == ERR )
	    return (no + PRG_NO);
	act_fwc_cdrom = prg_tbl[no]->cdrom;
    }

    if ( prg_tbl[no]->dir != NULL ) {
	DSP_mos(2);
	if ( prg_tbl[no]->manual == NULL ) {
	    if ( (prg_tbl[no]->manual = 
			file_serch(prg_tbl[no]->dir,"*.RRR")) == NULL ) {
	        if ( (prg_tbl[no]->manual = 
			    file_serch(prg_tbl[no]->dir,"*.MAN")) == NULL )
		    prg_tbl[no]->manual = 
			        file_serch(prg_tbl[no]->dir,"*.DOC");
	    }
	}
	if ( prg_tbl[no]->readme == NULL ) {
	    if ( (prg_tbl[no]->readme = 
			file_serch(prg_tbl[no]->dir,"*.GGG")) == NULL )
		prg_tbl[no]->readme = 
			    file_serch(prg_tbl[no]->dir,"*.DOC");
	}
	if ( prg_tbl[no]->copycnt == 0 ) {
	    if ( (prg_tbl[no]->copy[0] = 
			file_serch(prg_tbl[no]->dir,"*.QQQ")) == NULL ) {
		strcpy(tmp,prg_tbl[no]->dir);
		joint_path(tmp,"*.*");
		prg_tbl[no]->copy[0] = strdup(tmp);
	    }
	    prg_tbl[no]->copycnt++;
	}
	DSP_mos(0);
    }

REDISP:

    MSG_disp("%-41.41s",prg_tbl[no]->name);
    MENU_mask(RETN_NO,ON);
    MENU_mask(LIST_NO,OFF);
    MENU_mask(PRNT_NO,OFF);
    MENU_mask(INST_NO,(prg_tbl[no]->copycnt > 0 ? ON:OFF));
    MENU_mask(EXEC_NO,(prg_tbl[no]->exec != NULL ? ON : (-1)));

    if ( prg_tbl[no]->readme != NULL ) {
	MENU_mask(LIST_NO,prg_tbl[no]->manual != NULL ? ON:OFF);
	FILE_open(prg_tbl[no]->readme);
	fg = 0;
    } else if ( prg_tbl[no]->manual != NULL ) {
	MENU_mask(TEXT_NO,prg_tbl[no]->readme != NULL ? ON:OFF);
	FILE_open(prg_tbl[no]->manual);
	fg = 1;
    } else {
	FILE_open(NULL);
	fg = (-1);
    }

    for ( ; ; ) {
	while ( (i = MENU_no(0)) == NON_NO )
	    FILE_irq();

	if ( i == CLER_NO )
	    break;
	else if ( i == LIST_NO ) {
	    if ( fg == 0 && prg_tbl[no]->manual != NULL ) {
		MENU_mask(TEXT_NO,prg_tbl[no]->readme != NULL ? ON:OFF);
		FILE_open(prg_tbl[no]->manual);
		fg = 1;
	    } else if ( fg == 1 && prg_tbl[no]->readme != NULL ) {
		MENU_mask(LIST_NO,prg_tbl[no]->manual != NULL ? ON:OFF);
		FILE_open(prg_tbl[no]->readme);
		fg = 0;
	    }
	} else if ( i == PRNT_NO )
	    FILE_lpt();
/***********************
	else if ( i == INST_NO )
	    COPY_all(prg_tbl[no]->copycnt,prg_tbl[no]->copy);
************************/
	else if ( i == INST_NO )
	    Install(prg_tbl[no]);
	else if ( i == BACK_NO )
	    FILE_back();
	else if ( i == NEXT_NO )
	    FILE_next();
	else if ( i == EXIT_NO ) {
	    a = getdrv();
	    getdir(tmp);
	    if ( prg_tbl[no]->dir[1] == ':' ) {
		if ( !chdrv(toupper(prg_tbl[no]->dir[0])-'A') )
		    chdir(prg_tbl[no]->dir);
	    } else
		chdir(prg_tbl[no]->dir);

	    if ( prg_tbl[no]->exec != NULL ) {
		if ( !PROG_command(prg_tbl[no]->exec) )
		    JOKE_run(prg_tbl[no]->exec);
	    } else
		LIST_proc();

	    if ( !chdrv(a) )
		chdir(tmp);

/*********************************
	    if ( fg == 0 && prg_tbl[no]->readme != NULL )
		FILE_open(prg_tbl[no]->readme);
	    else if ( fg == 1 && prg_tbl[no]->manual != NULL )
		FILE_open(prg_tbl[no]->manual);
**********************************/
	    goto REDISP;
	}
    }

#ifdef	DEBUG
    MENU_mask(CLER_NO,OFF);
    MENU_mask(LIST_NO,ON);
    MENU_mask(PRNT_NO,ON);
    MENU_mask(INST_NO,ON);
    MENU_mask(EXIT_NO,ON);
#else
    MENU_mask(CLER_NO,OFF);
    MENU_mask(LIST_NO,(-1));
    MENU_mask(PRNT_NO,OFF);
    MENU_mask(INST_NO,(-1));
    MENU_mask(EXIT_NO,ON);
#endif
    MSG_disp("%-41.41s","");
    FILE_close();
    PRG_status();

    return i;
}
int	LIST_proc(void)
{
    int     i,n;
    int     fg=0;
    char    *p,*s;

LOOP:
    if ( (p = FILE_select()) == NULL )
	return LIST_NO;

    if ( PROG_command(p) )
	goto LOOP;
    if ( JOKE_run(p) )
	goto LOOP;

    MENU_mask(RETN_NO,ON);
    MENU_mask(LIST_NO,OFF);
    MENU_mask(PRNT_NO,ON);
    MENU_mask(INST_NO,OFF);
    MENU_mask(EXIT_NO,OFF);
    FILE_open(p);

    for ( ; ; ) {
	while ( (i = MENU_no(0)) == NON_NO )
	    FILE_irq();

	if ( i == CLER_NO )
	    break;
	else if ( i == PRNT_NO )
	    FILE_lpt();
	else if ( i == BACK_NO )
	    FILE_back();
	else if ( i == NEXT_NO )
	    FILE_next();

    }

#ifdef	DEBUG
    MENU_mask(CLER_NO,OFF);
    MENU_mask(LIST_NO,ON);
    MENU_mask(PRNT_NO,ON);
    MENU_mask(INST_NO,ON);
    MENU_mask(EXIT_NO,ON);
#else
    MENU_mask(CLER_NO,OFF);
    MENU_mask(LIST_NO,(-1));
    MENU_mask(PRNT_NO,OFF);
    MENU_mask(INST_NO,(-1));
    MENU_mask(EXIT_NO,ON);
#endif
    FILE_close();
    PRG_status();

    goto LOOP;
}

int	PROG_command(char *cmds)
{
    int n;
    char *p;
    EXEPTR *ep;
    char tmp[256];
    char path[128];

    p = cmds;
    while ( isspace(*p) )
	p++;
    for ( n = 0 ; n < 127 && *p != '\0' && !isspace(*p) ; )
	tmp[n++] = *(p++);
    tmp[n] = '\0';

    if ( (p = strrchr(tmp, '\\')) != NULL ||
	 (p = strrchr(tmp, ':')) != NULL )
	p++;
    else {
	p = tmp;
	path[0] = getdrv() + 'A';
	path[1] = ':';
	getdir(path + 2);
	joint_path(path, cmds);
	cmds = path;
    }

    for ( n = 0 ; n < PROG_MAX ; n++ ) {
	ep = &(prog_tab[n]);
	if ( ep->wild != NULL && wild_mach(ep->wild, p) ) {
	    strcpy(tmp, (ep->prog == NULL ? "" : ep->prog));
	    strcat(tmp, " ");
	    strcat(tmp, cmds);
	    if ( !EXEC_input(tmp) && !CTRL_command(1, tmp) )
		longjmp(sysreturn, 1);
	    break;
	}
    }
    return 0;
}

int	main(int argc,char *argv[])
{
    int     i,n,cdrv;
    char    *p;
    char    *exp;
    char    tmp[4];
    char    dmy[64];

    cdrv = getdrv();
    tmp[0] = cdrv + 'A'; tmp[1] = ':'; tmp[2] = '\0';
    crent_drive = tmp;
    exp = argv[0];
    index_file[0] = '\0';

    if ( argc > 1 ) {
	while ( --argc > 0 ) {
	    p = *(++argv);
	    if ( *p == '-' || *p == '/' ) {
		switch(toupper(*(p+1))) {
		case 'D':
		    p += (*(p+2) == '=' ? 3:2);
		    crent_drive = p;
		    break;
		}
	    } else
		strcpy(index_file,p);
	}

    }

    if ( index_file[0] == '\0' ) {
	p = exp;
	if ( p[0] != '\0' && p[1] == ':' ) {
	    index_file[0] = *(p++);
	    index_file[1] = *(p++);
	} else {
	    index_file[0] = 'A' + cdrv;
	    index_file[1] = ':';
	}
	index_file[2] = '\0';

	if ( crent_drive == tmp )
	    crent_drive = strdup(index_file);

	if ( *p != '\\' ) {
	    getdir(index_file+2);
	    if ( index_file[3] != '\0' )
		strcat(index_file,"\\");
	}
	strcat(index_file,p);
	if ( (p = strrchr(index_file,'\\')) == NULL )
	    for ( p = index_file ; *p != '\0' ; p++ );
	strcpy(p,"\\HELPER.IDX");
    }

    _XLD_init(0);
    _XLD_setMemFunc(malloc, free);

    ABORT_init();
    DSP_init();
    KAN_init();

    DSP_mos(2);

    ICON_init();
    SCRN_init();
    DB_init(index_file);
    KEY_cler();

#ifdef	DEBUG
    MENU_mask(CLER_NO,OFF);
    MENU_mask(LIST_NO,ON);
    MENU_mask(PRNT_NO,ON);
    MENU_mask(INST_NO,ON);
    MENU_mask(EXIT_NO,ON);
#else
    MENU_mask(CLER_NO,OFF);
    MENU_mask(LIST_NO,(-1));
    MENU_mask(PRNT_NO,OFF);
    MENU_mask(INST_NO,(-1));
    MENU_mask(EXIT_NO,ON);
#endif

    DSP_mos(0);

    if ( setjmp(sysreturn) != 0 ) {
	KEYWORD_save();
	goto ENDOF;
    }

    sprintf(dmy, "%s\\RUN386.EXE", crent_drive);
    PROG_append("*.EXP", dmy);
    sprintf(dmy, "%s\\RUN386.EXE %s\\GSTART.EXP", crent_drive, crent_drive);
    PROG_append("*.EXG", dmy);
    sprintf(dmy, "%s\\TMENU.IF2", crent_drive);
    IF2_load(dmy);

    KEYWORD_load();

    for ( ; ; ) {
	while ( (i = MENU_no(1)) == NON_NO )
	    ;

	if ( i == EXIT_NO ) {
	    if ( yesno("Are You Sure ?") != (-1) )
	        break;
	} else if ( i == CLER_NO )
	    KEY_cler();
	else if ( i == LIST_NO )
	    LIST_proc();
#ifdef	DEBUG
	else if ( i == PRNT_NO )
	    PLT_control();
	else if ( i == INST_NO )
	    KEY_input();
#else
	else if ( i == INST_NO )
	    IFSET_cmds();
#endif
	else if ( i == BACK_NO )
	    PRG_back();
	else if ( i == NEXT_NO )
	    PRG_next();
	else if ( i == TITL_NO )
	    TITL_clic();
	else if ( i == WRIT_NO )
	    WRIT_clic();
	else if ( i >= PRG_NO )
	    PRG_clic(i - PRG_NO);
	else if ( i >= KEY_NO )
	    KEY_clic(i - KEY_NO);
    }

    CTRL_command(0x00FF, "");

ENDOF:
    KAN_disp(KAN_DISPOFF);
    KAN_finish();
    DSP_end();

/********************
    chdrv(cdrv);
*********************/

    return 0;
}
