#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <ctype.h>
#include    <mos.h>
#include    <time.h>
#include    "defs.h"
#include    "event.h"
#include    "graphic.h"
#include    "msg.h"
#include    "oaklib.h"
#include    "buff.h"
#include    "coldef.h"

void	CHK_snd(void);
void	CHK_eup(void);
int	MSG_init(char *env,char *usr);
void	RSB_init(int port);
void	WIN_init(void);
void	WIN_open(int no);
int	SEL_file(void);
void	WIN_loop(void);
void	MSG_end(void);
void	RSB_end(void);
void	KYB_clrbuf();
void	TALK_init(char *file);

extern short int modeW;

int	key_flg=FALSE;
int	cur_x=0,cur_y=0;
int	top_event=0;
int     mos_lock=TRUE;

static int	tm_flg=FALSE;
static int 	kb_flg=FALSE;
static int 	ch_bak=0;
static unsigned ec_bak=0;

void	MAIN_event(EVENT *ep)
{
    switch(ep->now) {

    case EVT_CLIP_MOS:
	if ( ep->no == 9 || ep->no == 10 )
	    tm_flg = TRUE;
	EVT_clip_on(ep);
    case EVT_ON_MOS:
	DSP_mos(1);
	break;

    case EVT_SELECT_MOS:
	if ( ep->no == 9 || ep->no == 10 )
	    tm_flg = FALSE;
	top_event = ep->no;
    case EVT_DOLACK_MOS:
	ep->now = EVT_NON;
    case EVT_MOVE_MOS:
	EVT_clip_off(ep);
    case EVT_OFF_MOS:
	DSP_mos(0);
	break;
    }
}

void	put_put(int x,int y,int len,int pos,char *str,char *att)
{
    int     i,col;
    char    tmp[4];
    static int kan_col[]={ 0,1,14,3,4,5,2,8,9,10,11,12,13,6,15,7 };

    for ( i = 0 ; i < len ; ) {
	col = kan_col[*att];
	if ( i == pos )
	    col = 15;

	if ( iskanji(*str) && iskanji2(*str+1) ) {
	    tmp[0] = *(str++);
	    tmp[1] = *(str++);
	    tmp[2] = '\0';
	    if ( (x + 16) > 640 ) {
		x = 0;
		y += 16;
	    }
	    wrtstr(tmp,0,x/2+y*512,col_cnv[0],col_cnv[col],16);
	    x += 16;
	    att += 2;
	    i += 2;
	} else {
	    tmp[0] = *(str++);
	    tmp[1] = '\0';
	    if ( (x + 8) > 640 ) {
		x = 0;
		y += 16;
	    }
	    wrtstr(tmp,0,x/2+y*512,col_cnv[0],col_cnv[col],16);
	    x += 8;
	    att++;
	    i++;
	}
    }
}

void	putmode(int md,int sf,char *str)
{
    MOS_disp(FALSE);
    wrtstr(str,0,568/2+464*512,col_cnv[COL_CHR],col_cnv[COL_WHIS],16);
    if ( mos_lock == FALSE )
	MOS_disp(TRUE);
}

void	putsys(int len,char *str,char *att)
{
    static BLOCK *save=NULL;

    if ( key_flg == FALSE )
	return;

    MOS_disp(FALSE);

    if ( save != NULL ) {
	DSP_pop_vram(save);
	save = NULL;
    }

    if ( len > 0 ) {
        save = DSP_push_vram(0,464,len*8,479);
	put_put(0,464,len,256,str,att);
    }

    if ( mos_lock == FALSE )
	MOS_disp(TRUE);
}

void	putcnv(int pos,int len,char *str,char *att)
{
    static BLOCK *save1=NULL;
    static BLOCK *save2=NULL;
    int     n;

    if ( key_flg == FALSE )
	return;

    MOS_disp(FALSE);

    if ( save1 != NULL ) {
	DSP_pop_vram(save1);
	save1 = NULL;
    }
    if ( save2 != NULL ) {
	DSP_pop_vram(save2);
	save2 = NULL;
    }

    if ( len > 0 ) {
	if ( (n = cur_x+len*8) > 640 ) {
	    n -= (624);
	    save1 = DSP_push_vram(cur_x,cur_y,639,cur_y+15);
	    save2 = DSP_push_vram(0,cur_y+16,n,cur_y+31);
	} else
	    save1 = DSP_push_vram(cur_x,cur_y,n,cur_y+15);
	put_put(cur_x,cur_y,len,pos,str,att);
    }

    if ( mos_lock == FALSE )
	MOS_disp(TRUE);
}
void	TIME_dsp(void)
{
    static time_t old_t=0;
    time_t    t;
    struct tm *ft;
    char      tmp[32];

    time(&t);
    if ( tm_flg == FALSE && t != old_t ) {
	old_t = t;
	ft = localtime(&t);
	sprintf(tmp,"%02d/%02d/%02d",
		ft->tm_year,ft->tm_mon+1,ft->tm_mday);
	DSP_string(tmp,TIME_X+2,4,COL_WHIS2,COL_WHIS);

	sprintf(tmp,"%02d:%02d:%02d",
		ft->tm_hour,ft->tm_min,ft->tm_sec);
	DSP_string(tmp,TIME_X+72+2,4,COL_WHIS2,COL_WHIS);

	MSG_wind("interval_timer");
    }
}
int	main(int argc,char *argv[])
{
    char    *p;
    char    *work=NULL;
    char    *user=NULL;
    char    *tmp=NULL;

    work = getenv("WHISPER");
    tmp = getenv("TMP");

    while ( --argc > 0 ) {
	p = *(++argv);
	if ( *p == '-' || *p == '/' ) {
	    switch(*(++p)) {
	    case 'R': case 'r':
		modeW = (modeW & 0xFFF3) | 0x0008;
		break;
	    case 'F': case 'f':
		modeW = (modeW & 0xFFCF) | 0x0020;
		break;
	    case 'K': case 'k':
		modeW = (modeW & 0xFE3F) | 0x0080;
		break;
	    case 'H': case 'h':
		modeW = (modeW & 0xFE3F) | 0x0100;
		break;
	    case 'T': case 't':
		if ( *(++p) == '=' ) p++;
		tmp = p;
		break;
	    case 'W': case 'w':
		if ( *(++p) == '=' ) p++;
		work = p;
		break;
	    }
	} else
	    user = p;
    }

    DSP_init();
    if ( MSG_init(work,user) ) {
	wrtstr("うわぁ！ WHISPER.CFG が読み込めな〜い！",
	    0,160/2+220*512,col_cnv[8],col_cnv[0],16);
	DSP_end();
	return 1;
    }

    KAN_open(putcnv,putsys,putmode);
    TALK_init("ONSEI.DIC");
    BUF_init(tmp);
    RSB_init(0);

    MOS_disp(FALSE);

    DSP_box(0,0,639,15,COL_LINE,COL_WHIS);

    EVT_sw(WHIS_X,2,"WHISPER",COL_LOVE,COL_WHIS,100,MAIN_event,0);

    EVT_sw(MIKE_X,2,"    ",COL_WHIS2,COL_WHIS,100,MAIN_event,1);
    EVT_sw(JOHN_X,2,"    ",COL_WHIS2,COL_WHIS,100,MAIN_event,2);
    EVT_sw(KENT_X,2,"    ",COL_WHIS2,COL_WHIS,100,MAIN_event,3);
    EVT_sw(JACK_X,2,"JACK",COL_WHIS2,COL_WHIS,100,MAIN_event,4);

    EVT_sw(HELP_X,2,"HELP",COL_DIA,COL_WHIS,100,MAIN_event,5);
    EVT_sw(EXIT_X,2,"EXIT",COL_RED,COL_WHIS,100,MAIN_event,6);

/**************************
    EVT_sw(CD_X,2,"CD",COL_WHIS2,COL_WHIS,100,MAIN_event,7);
***************************/
    EVT_sw(AUX_X,2,"SETUP",COL_WHIS2,COL_WHIS,100,MAIN_event,8);

    EVT_sw(TIME_X,2,"        ",COL_WHIS2,COL_WHIS,100,MAIN_event,9);
    EVT_sw(TIME_X+72,2,"        ",COL_WHIS2,COL_WHIS,100,MAIN_event,10);

    MOS_disp(TRUE);

    WIN_init();

    MSG_wind(START_MSG);
    mos_lock = FALSE;

    for ( top_event = ERR ; ; ) {

	TIME_dsp();
	EVT_loop(0);

	if ( top_event == 0 ) {
	    MSG_wind(WHISPER_MSG);

	} else if ( top_event == 1 ) {
	    WIN_open(0);

	} else if ( top_event == 2 ) {
	    WIN_open(1);

	} else if ( top_event == 3 ) {
	    WIN_open(2);

	} else if ( top_event == 4 ) {
	    top_event = SEL_file();
	    continue;

	} else if ( top_event == 5 ) {
	    MSG_wind(HELP_MSG);

	} else if ( top_event == 6 ) {
	    if ( MSG_wind(END_OF_MSG) )
	        break;

/*******************************************
	} else if ( top_event == 7 ) {
	    MSG_wind("cdplay");
*******************************************/

	} else if ( top_event == 8 ) {
	    MSG_wind("setup");

	} else if ( top_event == 9 ) {
	    MSG_wind("date_event");

	} else if ( top_event == 10 ) {
	    MSG_wind("time_event");

	}

	top_event = ERR;
	key_flg = TRUE;
	WIN_loop();
	key_flg = FALSE;
    }

    MSG_end();
    BUF_end();
    RSB_end();
    KAN_close();
    DSP_end();
    return 0;
}

int	kbhit(void)
{
    CHK_snd();
    CHK_eup();

    if ( kb_flg != FALSE )
	return TRUE;

    ch_bak = KAN_read(1,&ec_bak);

    if ( (ec_bak & 0xFF00) == 0xFF00 )
	return FALSE;

    kb_flg = TRUE;
    return TRUE;
}

int	getkey(unsigned *ec)
{
    *ec = 0xFF00;
    if ( kbhit() == FALSE )
	return 0xFFFF;

    kb_flg = FALSE;
    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;
	}
    }
    *ec = ec_bak;
    return ch_bak;
}

int	getch(void)
{
    unsigned ec;

    return getkey(&ec);
}

void	key_in(void)
{
    key_flg = TRUE;
    kb_flg = FALSE;
    KYB_clrbuf();
}
void	key_out(void)
{
    key_flg = FALSE;
}
void	KAN_KAN_open(void)
{
    KYB_init();
    KYB_clic(1);
    KAN_open(putcnv,putsys,putmode);
}
