#include    <stdio.h>
#include    <stdlib.h>
#include    <stdarg.h>
#include    <string.h>
#include    <ctype.h>
#include    <mos.h>
#include    "dir.h"
#include    "scrn.h"
#include    "keyword.h"
#include    "graphic.h"
#include    "event.h"
#include    "coldef.h"
#include    "bitmap.h"

#define	TRUE	1
#define	FALSE	0
#define	ERR	(-1)

#define	PAGE		0x40000

#define	INST_X1		133
#define	INST_Y1		110
#define	INST_X2		(INST_X1 + 372 - 1)
#define	INST_Y2		(INST_Y1 + 244 - 1)

#define	INST_BOX_X1	(INST_X1 - 4)
#define	INST_BOX_Y1	(INST_Y1 + 16)
#define	INST_BOX_X2	INST_X2
#define	INST_BOX_Y2	INST_Y2

#define	TITLE_NO	0
#define	TITLE_X1	(INST_X1 + 8)
#define	TITLE_Y1	(INST_Y1 + 8)
#define	TITLE_X2	(TITLE_X1 + 354 - 1)
#define	TITLE_Y2	(TITLE_Y1 + 20 - 1)

#define	SCRDIR_NO	1
#define	SRCDIR_X1	(INST_X1 + 8)
#define	SRCDIR_Y1	(INST_Y1 + 45)
#define	SRCDIR_X2	(SRCDIR_X1 + 292 - 1)
#define	SRCDIR_Y2	(SRCDIR_Y1 + 20 - 1)

#define	SRCSIZE_NO	2
#define	SRCSIZE_X1	(INST_X1 + 310)
#define	SRCSIZE_Y1	(INST_Y1 + 45)
#define	SRCSIZE_X2	(SRCSIZE_X1 + 52 - 1)
#define	SRCSIZE_Y2	(SRCSIZE_Y1 + 20 - 1)

#define	DOCOPY_NO	3
#define	DOCOPY_X1	(INST_X1 + 182)
#define	DOCOPY_Y1	(INST_Y1 + 52)
#define	DOCOPY_X2	(DOCOPY_X1 + 20 - 1)
#define	DOCOPY_Y2	(DOCOPY_Y1 + 20 - 1)

#define	DRV_LEFT_NO	4
#define	DRV_LEFT_X1	(INST_X1 + 8)
#define	DRV_LEFT_Y1	(INST_Y1 + 74)
#define	DRV_LEFT_X2	(DRV_LEFT_X1 + 18 - 1)
#define	DRV_LEFT_Y2	(DRV_LEFT_Y1 + 34 - 1)

#define	DRV_RIGHT_NO	5
#define	DRV_RIGHT_X1	(INST_X1 + 70)
#define	DRV_RIGHT_Y1	(INST_Y1 + 74)
#define	DRV_RIGHT_X2	(DRV_RIGHT_X1 + 18 - 1)
#define	DRV_RIGHT_Y2	(DRV_RIGHT_Y1 + 34 - 1)

#define	DRV_ICON_NO	20
#define	DRV_ICON_X1	(INST_X1 + 31)
#define	DRV_ICON_Y1	(INST_Y1 + 74)
#define	DRV_ICON_X2	(DRV_ICON_X1 + 34 - 1)
#define	DRV_ICON_Y2	(DRV_ICON_Y1 + 34 - 1)

#define	DRV_ALL_NO	21
#define	DRV_ALL_X1	(INST_X1 + 8)
#define	DRV_ALL_Y1	(INST_Y1 + 114)
#define	DRV_ALL_X2	(DRV_ALL_X1 + 80 - 1)
#define	DRV_ALL_Y2	(DRV_ALL_Y1 + 20 - 1)

#define	DIR_LEFT_NO	6
#define	DIR_LEFT_X1	(INST_X1 + 96)
#define	DIR_LEFT_Y1	(INST_Y1 + 98)
#define	DIR_LEFT_X2	(DIR_LEFT_X1 + 16 - 1)
#define	DIR_LEFT_Y2	(DIR_LEFT_Y1 + 106 - 1)

#define	DIR_RIGHT_NO	7
#define	DIR_RIGHT_X1	(INST_X1 + 345)
#define	DIR_RIGHT_Y1	(INST_Y1 + 98)
#define	DIR_RIGHT_X2	(DIR_RIGHT_X1 + 16 - 1)
#define	DIR_RIGHT_Y2	(DIR_RIGHT_Y1 + 106 - 1)

#define	INSTALL_NO	8
#define	INSTALL_X1	(INST_X1 + 8)
#define	INSTALL_Y1	(INST_Y1 + 214)
#define	INSTALL_X2	(INSTALL_X1 + 80 - 1)
#define	INSTALL_Y2	(INSTALL_Y1 + 20 - 1)

#define	CANCEL_NO	9
#define	CANCEL_X1	(INST_X1 + 94)
#define	CANCEL_Y1	(INST_Y1 + 214)
#define	CANCEL_X2	(CANCEL_X1 + 80 - 1)
#define	CANCEL_Y2	(CANCEL_Y1 + 20 - 1)

#define	MKDIR_NO	10
#define	MKDIR_X1	(INST_X1 + 180)
#define	MKDIR_Y1	(INST_Y1 + 214)
#define	MKDIR_X2	(MKDIR_X1 + 42 - 1)
#define	MKDIR_Y2	(MKDIR_Y1 + 20 - 1)

#define	DISDIR_NO	11
#define	DISDIR_X1	(INST_X1 + 96)
#define	DISDIR_Y1	(INST_Y1 + 74)
#define	DISDIR_X2	(DISDIR_X1 + 266 - 1)
#define	DISDIR_Y2	(DISDIR_Y1 + 20 - 1)

#define	FREESIZE_X1	(INST_X1 + 18)
#define	FREESIZE_Y1	(INST_Y1 + 158)

#define	DISFREE_NO	12
#define	DISFREE_X1	(INST_X1 + 16)
#define	DISFREE_Y1	(INST_Y1 + 174)
#define	DISFREE_X2	(DISFREE_X1 + 60 - 1)
#define	DISFREE_Y2	(DISFREE_Y1 + 20 - 1)

#define	DISSIZE_NO	13
#define	DISSIZE_X1	(INST_X1 + 16)
#define	DISSIZE_Y1	(INST_Y1 + 184)
#define	DISSIZE_X2	(DISSIZE_X1 + 60 - 1)
#define	DISSIZE_Y2	(DISSIZE_Y1 + 20 - 1)

#define	DISMKDIR_NO	14
#define	DISMKDIR_X1	(INST_X1 + 230)
#define	DISMKDIR_Y1	(INST_Y1 + 212)
#define	DISMKDIR_X2	(DISMKDIR_X1 + 106 - 1)
#define	DISMKDIR_Y2	(DISMKDIR_Y1 + 20 - 1)

#define	DISLIST_NO	100
#define	DISLIST_X1	(INST_X1 + 118)
#define	DISLIST_Y1	(INST_Y1 + 98)
#define	DISLIST_X2	(DISLIST_X1 + 106 - 1)
#define	DISLIST_Y2	(DISLIST_Y1 + 20 - 1)

#define	DISPOS_NO(n)	(DISLIST_NO + n)
#define	DISPOS_X1(n)	(DISLIST_X1 + ((n) / 5) * 114)
#define	DISPOS_Y1(n)	(DISLIST_Y1 + ((n) % 5) * 22)
#define	DISPOS_X2(n)	(DISLIST_X1 + ((n) / 5) * 114 + 106 - 1)
#define	DISPOS_Y2(n)	(DISLIST_Y1 + ((n) % 5) * 22 + 20 - 1)

extern	unsigned long	fcopy_max;
extern	unsigned long	fcopy_pos;

static	int	drv_max = 0;
static	char	drv_num[26];
static	char	num_drv[26];

static	EVENT	*EventBotton(EVENT *ep,
	int x1, int y1, int x2, int y2, int no, char *str)
{
    DSP_wbox(x1, y1, x2, y2, LINE_COL, WIND_COL, M_PSET);
    gputs((x1 + x2 + 1) / 2 - strlen(str) * 4,
	  (y1 + y2 + 1) / 2 - 8,
	  CHR_COL, WIND_COL, str);
    return EVT_set(ep, no, x1, y1, x2, y2, EVT_proc);
}
char	*strsize(unsigned long sz)
{
    int t, g, m, k, b;
    static char tmp[16];

    b = sz % 1000; sz /= 1000;
    k = sz % 1000; sz /= 1000;
    m = sz % 1000; sz /= 1000;
    g = sz % 1000; sz /= 1000;
    t = sz % 1000; sz /= 1000;

    if ( t > 0 )
	sprintf(tmp, "%d.%03dT", t, g);
    else if ( g >= 100 )
	sprintf(tmp, "%d.%01dG", g, m / 1000);
    else if ( g >= 10 )
	sprintf(tmp, "%d.%02dG", g, m / 10);
    else if ( g > 0 )
	sprintf(tmp, "%d.%03dG", g, m);
    else if ( m >= 100 )
	sprintf(tmp, "%d.%01dM", m, k / 100);
    else if ( m >= 10 )
	sprintf(tmp, "%d.%02dM", m, k / 10);
    else if ( m > 0 )
	sprintf(tmp, "%d.%03dM", m, k);
    else if ( k >= 100 )
	sprintf(tmp, "%d.%01dK", k, b / 100);
    else if ( k >= 10 )
	sprintf(tmp, "%d.%02dK", k, b / 10);
    else if ( k > 0 )
	sprintf(tmp, "%d.%03dK", k, b);
    else
	sprintf(tmp, "%d", b);

    return tmp;
}
char	*strnpath(char *str, int max)
{
    int i, n = 0;
    static char tmp[128];

    strcpy(tmp, str);
    if ( (i = strlen(tmp)) <= max )
	return tmp;

    strcpy(tmp, "...");

    i -= (max - 3);
    while ( i > 0 ) {
	n = (iskan(str) ? 2 : 1);
	str += n;
	i -= n;
    }
    strcpy(tmp + 3, str);

    return tmp;
}
unsigned long	sizecopy(int ac, char *av[])
{
    int n;
    char *p;
    unsigned long sz = 0;

    DSP_mos(2);
    for ( n = 0 ; n < ac ; n++ ) {
	if ( (p = strrchr(av[n], '.')) != NULL && strcmp(p,".QQQ") == 0 ) {
	    sz = 0L;
	    break;
	}
	sz += sizedir(av[n]);
    }
    DSP_mos(0);

    return sz;
}
int	DriveSelect(int drv)
{
    int n, x, y;
    int x1, y1, x2, y2;
    BLOCK *sp;
    EVENT *ep = NULL;

    x = 40 * 8 + 16;
    y = ((drv_max + 7) / 8) * 40 + 16;
    x1 = (640 - x) / 2;
    x2 = x1 + x - 1;
    y1 = (480 - y) / 2;
    y2 = y1 + y - 1;
    x = x1 + 8;
    y = y1 + 8;

    MOS_disp(OFF);
    sp = DSP_push_vram(x1, y1, x2, y2);
    DSP_opbox(x1, y1, x2, y2);
    DSP_wbox(x1, y1, x2, y2, LINE_COL, FILD_COL, M_PSET);

    for ( n = 0 ; n < drv_max ; n++ ) {
	ICON_disp(x + (n % 8) * 40,
		  y + (n / 8) * 40, num_drv[n]);
	ep = EVT_set(ep, n,
		x + (n % 8) * 40, y + (n / 8) * 40,
		x + (n % 8) * 40 + 31, y + (n / 8) * 40 + 31, EVT_proc);
    }

    x = x + (drv_num[drv] % 8) * 40;
    y = y + (drv_num[drv] / 8) * 40;
    DSP_box(x, y, x + 33, y + 33, 11, M_XOR);
    MOS_disp(ON);

    n = EVT_wait(ep);
    drv = num_drv[n];

    EVT_free(ep);
    MOS_disp(OFF);
    DSP_pop_vram(sp);
    DSP_clbox(x1, y1, x2, y2);
    MOS_disp(ON);

    return drv;
}
void	Install(PRGPTR *pp)
{
    int n, st;
    int sw, bx, by;
    int drv, odrv, dfg;
    BLOCK *sp;
    EVENT *ep = NULL;
    unsigned long fr, ta;
    long nw, od;
    char *p;
    DIR *dir = NULL;
    DIRECT *dp;
    DIRECT *ptr[10];
    int top, now, max;
    char mdir[128];
    char tmp[128];

    MOS_disp(OFF);
    sp = DSP_push_vram(INST_BOX_X1, INST_BOX_Y1, INST_BOX_X2, INST_BOX_Y2);
    DSP_opbox(INST_BOX_X1, INST_BOX_Y1, INST_BOX_X2, INST_BOX_Y2);
    DSP_wbox(INST_BOX_X1, INST_BOX_Y1,
		INST_BOX_X2, INST_BOX_Y2, LINE_COL, FILD_COL, M_PSET);

    DSP_strimg(drive_select_img,
	(INST_BOX_X1 + INST_BOX_X2 + 1) / 2 - 86,
	INST_BOX_Y1 + 10, CHR_COL, FILD_COL, M_PSET);

    DSP_strimg(free_size_img,
	FREESIZE_X1, FREESIZE_Y1, CHR_COL, FILD_COL, M_PSET);

    ep = EventBotton(ep, DRV_LEFT_X1, DRV_LEFT_Y1,
		DRV_LEFT_X2, DRV_LEFT_Y2, DRV_LEFT_NO, "<");

    ep = EventBotton(ep, DRV_RIGHT_X1, DRV_RIGHT_Y1,
		DRV_RIGHT_X2, DRV_RIGHT_Y2, DRV_RIGHT_NO, ">");

    ep = EVT_set(ep, DRV_ICON_NO, DRV_ICON_X1, DRV_ICON_Y1,
		DRV_ICON_X2, DRV_ICON_Y2, EVT_proc);

    ep = EventBotton(ep, DIR_LEFT_X1, DIR_LEFT_Y1,
		DIR_LEFT_X2, DIR_LEFT_Y2, DIR_LEFT_NO, "<");

    ep = EventBotton(ep, DIR_RIGHT_X1, DIR_RIGHT_Y1,
		DIR_RIGHT_X2, DIR_RIGHT_Y2, DIR_RIGHT_NO, ">");

    ep = EventBotton(ep, DISMKDIR_X1, DISMKDIR_Y1,
		DISMKDIR_X2, DISMKDIR_Y2, DISMKDIR_NO, "");

/********************
    ep = EventBotton(ep, DRV_ALL_X1, DRV_ALL_Y1,
		DRV_ALL_X2, DRV_ALL_Y2, DRV_ALL_NO, "All Drive");

    ep = EventBotton(ep, INSTALL_X1, INSTALL_Y1,
		INSTALL_X2, INSTALL_Y2, INSTALL_NO, "INSTALL");

    ep = EventBotton(ep, CANCEL_X1, CANCEL_Y1,
		CANCEL_X2, CANCEL_Y2, CANCEL_NO, "CANCEL");

    ep = EventBotton(ep, MKDIR_X1, MKDIR_Y1,
		MKDIR_X2, MKDIR_Y2, MKDIR_NO, "MKDIR");
*********************/

    ep = EVT_img(ep, DRV_ALL_NO,
	DRV_ALL_X1 + 3, DRV_ALL_Y1, CHR_COL, WIND_COL, 73, all_drive_img);

    ep = EVT_img(ep, INSTALL_NO,
	INSTALL_X1 + 3, INSTALL_Y1, CHR_COL, WIND_COL, 73, install_img);

    ep = EVT_img(ep, CANCEL_NO,
	CANCEL_X1 + 3, CANCEL_Y1, CHR_COL, WIND_COL, 68, cancel_img);

    ep = EVT_img(ep, MKDIR_NO,
	MKDIR_X1, MKDIR_Y1, CHR_COL, WIND_COL, 40, mkdir_img);

    for ( n = 0 ; n < 10 ; n++ )
	ep = EventBotton(ep, DISPOS_X1(n), DISPOS_Y1(n),
		DISPOS_X2(n), DISPOS_Y2(n), DISPOS_NO(n), "");

/******************
    DSP_wbox(TITLE_X1, TITLE_Y1, TITLE_X2, TITLE_Y2,
		LINE_COL, WIND_COL, M_PSET);
*******************/

    DSP_wbox(SRCDIR_X1, SRCDIR_Y1, SRCDIR_X2, SRCDIR_Y2,
		LINE_COL, WIND_COL, M_PSET);

    DSP_wbox(SRCSIZE_X1, SRCSIZE_Y1, SRCSIZE_X2, SRCSIZE_Y2,
		LINE_COL, WIND_COL, M_PSET);

/********************
    DSP_wbox(DOCOPY_X1, DOCOPY_Y1, DOCOPY_X2, DOCOPY_Y2,
		LINE_COL, WIND_COL, M_PSET);
*********************/

    DSP_wbox(DISDIR_X1, DISDIR_Y1, DISDIR_X2, DISDIR_Y2,
		LINE_COL, WIND_COL, M_PSET);

    DSP_wbox(DISFREE_X1, DISFREE_Y1, DISFREE_X2, DISFREE_Y2,
		LINE_COL, WIND_COL, M_PSET);

    if ( pp->dir != NULL ) {
	gprintf(SRCDIR_X1 + 2, SRCDIR_Y1 + 2,
		CHR_COL, WIND_COL, "%-36.36s", strnpath(pp->dir, 36));
	if ( (p = strrchr(pp->dir, '\\')) != NULL ||
	     (p = strrchr(pp->dir, ':')) != NULL )
	    p++;
	else
	    p = pp->dir;
	strcpy(mdir, p);
    } else {
	mdir[0] = '\0';
    }

    gprintf(DISMKDIR_X1 + 2, DISMKDIR_Y1 + 2, CHR_COL, WIND_COL,
	"%-12.12s", mdir);

    MOS_rdpos(&sw, &bx, &by);
    MOS_setpos((INSTALL_X1 + INSTALL_X2) / 2, (INSTALL_Y1 + INSTALL_Y2) / 2);
    MOS_disp(ON);

    fcopy_max = fcopy_pos = 0;
    if ( (ta = sizecopy(pp->copycnt, pp->copy)) > 0 ) {
	fcopy_max = ta;
	MOS_disp(OFF);
	gprintf(SRCSIZE_X1 + 2, SRCSIZE_Y1 + 2, CHR_COL, WIND_COL,
		"%6.6s", strsize(ta));
	MOS_disp(ON);
    }

    odrv = (-1);
    dfg = TRUE;
    drv = getdrv();
    od = 0;

    for ( n = drv_max = 0 ; n < 26 ; n++ ) {
	drv_num[n] = drv_max;
	if ( drv_tbl[n] != IS_NON )
	    num_drv[drv_max++] = n;
    }

    for ( st = FALSE ; st == FALSE ; ) {
	if ( od != 0 ) {
	    time(&nw);
	    if ( nw >= od ) {
		dfg = TRUE;
		odrv = (-1);
		od = 0;
	    }
	}

	if ( drv != odrv ) {
	    MOS_disp(OFF);
	    ICON_disp(DRV_ICON_X1, DRV_ICON_Y1, drv);
	    if ( dfg == FALSE || chdrv(drv) || getdir(tmp) ||
			disk_free(drv, &fr, &ta) ) {
		gprintf(DISFREE_X1 + 2, DISFREE_Y1 + 2, CHR_COL, WIND_COL,
			"       ");
	        gprintf(DISDIR_X1 + 2, DISDIR_Y1 + 2, CHR_COL, WIND_COL,
			"%-32.32s", "");
		if ( dir != NULL )
		    closedir(dir);
		dir = NULL;
	    } else {
	        gprintf(DISFREE_X1 + 2, DISFREE_Y1 + 2, CHR_COL, WIND_COL,
			"%7.7s", strsize(fr * 1024));
	        gprintf(DISDIR_X1 + 2, DISDIR_Y1 + 2, CHR_COL, WIND_COL,
			"%-32.32s", strnpath(tmp, 32));

		joint_path(tmp, "*.*");
		if ( dir != NULL )
		    closedir(dir);
		if ( (dir = opendir(tmp)) != NULL ) {
		    stripdir(dir);
		    max = countdir(dir);
		}
	    }
	    MOS_disp(ON);
	    odrv = drv;
	    dfg = FALSE;
	    top = 0;
	    now = (-1);
	}

	if ( top != now ) {
	    if ( dir != NULL )
		seekdir(dir, top);
	    MOS_disp(OFF);
	    for ( n = 0 ; n < 10 ; n++ ) {
		if ( dir != NULL )
		    ptr[n] = dp = readdir(dir);
		else
		    ptr[n] = dp = NULL;

		gprintf(DISPOS_X1(n) + 2, DISPOS_Y1(n) + 2,
			CHR_COL, WIND_COL, "%-12.12s",
			(dp == NULL ? "" : dp->d_name));
	    }
	    MOS_disp(ON);
	    now = top;
	}

	EVT_msg_no = ERR;
	EVT_loop(ep);

	switch(EVT_msg_no) {
	case INSTALL_NO:
	    st = TRUE;
	    break;

	case CANCEL_NO:
	    st = ERR;
	    break;

	case DRV_ALL_NO:
	    drv = DriveSelect(drv);

	case DRV_ICON_NO:
	    odrv = (-1);
	    dfg = TRUE;
	    od = 0;
	    break;

	case DRV_RIGHT_NO:
	    n = drv_num[drv];
	    if ( ++n >= drv_max )
		n = 0;
	    drv = num_drv[n];
	    time(&od); od += 5;
	    break;

	case DRV_LEFT_NO:
	    n = drv_num[drv];
	    if ( --n < 0 )
		n = drv_max - 1;
	    drv = num_drv[n];
	    time(&od); od += 5;
	    break;

	case MKDIR_NO:
	    if ( !mkdir(mdir) && !chdir(mdir) ) {
		mdir[0] = '\0';
		MOS_disp(OFF);
		gprintf(DISMKDIR_X1 + 2, DISMKDIR_Y1 + 2, CHR_COL, WIND_COL,
			"%-12.12s", mdir);
		MOS_disp(ON);
	        odrv = (-1);
	        dfg = TRUE;
	        od = 0;
	    } else
		kakunin("ディレクトリ−の作成に失敗しました");
	    break;

	case DISMKDIR_NO:
	    MOS_disp(OFF);
	    input(DISMKDIR_X1 + 2, DISMKDIR_Y1 + 2, 12, mdir);
	    gprintf(DISMKDIR_X1 + 2, DISMKDIR_Y1 + 2, CHR_COL, WIND_COL,
		"%-12.12s", mdir);
	    MOS_disp(ON);
	    break;

	case DIR_LEFT_NO:
	    if ( dir == NULL )
		break;
	    if ( top > 0 )
		top -= 5;
	    break;

	case DIR_RIGHT_NO:
	    if ( dir == NULL )
		break;
	    if ( (top += 5) >= max )
		top -= 5;
	    break;

	default:
	    if ( (n = EVT_msg_no - DISLIST_NO) < 0 || n >= 10 )
		break;
	    if ( dir == NULL || ptr[n] == NULL )
		break;
	    if ( chdir(ptr[n]->d_name) )
		break;
	    odrv = (-1);
	    dfg = TRUE;
	    od = 0;
	    break;	    
	}
    }

    if ( dir != NULL )
	closedir(dir);

    EVT_free(ep);
    MOS_disp(OFF);
    DSP_pop_vram(sp);
    DSP_clbox(INST_BOX_X1, INST_BOX_Y1, INST_BOX_X2, INST_BOX_Y2);
    MOS_setpos(bx, by);
    MOS_disp(ON);

    if ( st == TRUE )
	zcopy(pp->copycnt, pp->copy);
}
