#include    <stdio.h>
#include    <stdlib.h>
#include    "graphic.h"
#include    "event.h"
#include    "coldef.h"

#define	TRUE	1
#define	FALSE	0
#define	ERR	(-1)

#define	EUP_X1		eup_x1
#define	EUP_Y1		eup_y1
#define	EUP_X2		(EUP_X1 + 268)
#define	EUP_Y2		(EUP_Y1 + 128)

#define	EUP_BAR_SIZE	64
#define	EUP_BAR_X1	(EUP_X1+8)
#define	EUP_BAR_Y1	(EUP_Y1+28)
#define	EUP_BAR_X2	(EUP_X1+11)
#define	EUP_BAR_Y2	(EUP_BAR_Y1+EUP_BAR_SIZE)

#define	EUP_SW_X1(n)	(EUP_X1 + (n) * 70 + 84)
#define	EUP_SW_Y1(n)	(EUP_Y1 + 104)
#define	EUP_SW_X2(n)	(EUP_X1 + (n) * 70 + 84- 1)
#define	EUP_SW_Y2(n)	(EUP_Y1 + 104 + 20 - 1)

#define	TRK_MAX		32

static	int	eup_x1 = 184;
static	int	eup_y1 = 180;
static	EVENT	*eup_rpy = NULL;
static	EVENT	*eup_fwe = NULL;

static	int	fwe_flag = FALSE;
static	int	move_flag = FALSE;
static	int	eup_ox, eup_oy;

static	BLOCK	*save = NULL;
static	char	*old_ptr = NULL;
static	int	old_tick = 0;
static	int	note_max[TRK_MAX];
static	int	note_vol[TRK_MAX];

	char	*strnpath(char *file, int max);

void	EUP_move(int x, int y)
{
    BLOCK *sv;

    MOS_disp(OFF);
    if ( (sv = DSP_push_vram(EUP_X1, EUP_Y1, EUP_X2, EUP_Y2)) == NULL )
	goto ENDOF;
    DSP_pop_vram(save);

    eup_x1 = x;
    eup_y1 = y;
    sv->x1 = EUP_X1;
    sv->y1 = EUP_Y1;
    sv->x2 = EUP_X2;
    sv->y2 = EUP_Y2;

    save = DSP_push_vram(EUP_X1, EUP_Y1, EUP_X2, EUP_Y2);
    DSP_pop_vram(sv);

    MOS_horizon(EUP_X1, EUP_X2 - 8);
    MOS_vertical(EUP_Y1 + 96, EUP_Y2 - 6);

    if ( eup_rpy == NULL || eup_fwe == NULL )
	goto ENDOF;

    eup_rpy->x1 = EUP_SW_X1(0) - 4;
    eup_rpy->y1 = EUP_SW_Y1(0) - 2;
    eup_rpy->x2 = EUP_SW_X1(0) + 35;
    eup_rpy->y2 = EUP_SW_Y1(0) + 17;

    eup_fwe->x1 = EUP_SW_X1(1) - 4;
    eup_fwe->y1 = EUP_SW_Y1(1) - 2;
    eup_fwe->x2 = EUP_SW_X1(1) + 35;
    eup_fwe->y2 = EUP_SW_Y1(1) + 17;

ENDOF:
    MOS_disp(ON);
}
void	EUP_open(char *file)
{
    int     n;

    MOS_disp(OFF);
    save = DSP_push_vram(EUP_X1,EUP_Y1,EUP_X2,EUP_Y2);
    DSP_opbox(EUP_X1,EUP_Y1,EUP_X2,EUP_Y2);
    DSP_wbox(EUP_X1,EUP_Y1,EUP_X2,EUP_Y2,LINE_COL,FILD_COL,M_PSET);

    for ( n = 0 ; n < TRK_MAX ; n++ ) {
	note_vol[n] = note_max[n] = (-1);
	DSP_box( EUP_BAR_X1+n*8-1, EUP_BAR_Y1-1,
		 EUP_BAR_X2+n*8+1, EUP_BAR_Y2+1,
		 7, M_PSET);
    }
    old_tick = tick_timer = 0;
    old_ptr = NULL;

    if ( (n = strlen(file)) > 30 )
	n = 30;
    gputs((EUP_X1 + EUP_X2 + 1) / 2 - (n * 4), EUP_Y1 + 8,
		CHR_COL, FILD_COL, strnpath(file, 30));

    eup_rpy = EVT_sw(NULL, 0, EUP_SW_X1(0), EUP_SW_Y1(0),
		CHR_COL, WIND_COL, " |< ");
    eup_fwe = EVT_sw(NULL, 1, EUP_SW_X1(1), EUP_SW_Y1(1),
		CHR_COL, WIND_COL, " >> ");

    MOS_horizon(EUP_X1, EUP_X2 - 8);
    MOS_vertical(EUP_Y1 + 96, EUP_Y2 - 6);

    DSP_mos(3);
    MOS_disp(ON);
}
void	EUP_close()
{
    EVT_free(eup_rpy);
    EVT_free(eup_fwe);

    MOS_disp(OFF);
    DSP_pop_vram(save);
    DSP_clbox(EUP_X1,EUP_Y1,EUP_X2,EUP_Y2);
    DSP_mos(0);
    MOS_horizon(0, 632);
    MOS_vertical(0, 470);
    MOS_disp(ON);

    eup_rpy = eup_fwe = NULL;
    fwe_flag = FALSE;
}
void	EUP_note_on(int trk, int vol)
{
    int n;
    int x1, x2;

    trk = (trk * 32) / 127;
    vol = ((vol * EUP_BAR_SIZE) / 127) & 0xFFFE;

    x1 = EUP_BAR_X1 + trk * 8;
    x2 = EUP_BAR_X2 + trk * 8;

    if ( note_vol[trk] >= 0 && note_max[trk] > vol )
        DSP_box(x1, EUP_BAR_Y2 - note_max[trk],
		x2, EUP_BAR_Y2 - vol,
		7, M_PSET);

    DSP_line(x1, EUP_BAR_Y2 - vol,
	     x2, EUP_BAR_Y2 - vol,
	     2, M_PSET);

    for ( n = vol - 2 ; n >= 0 && n >= note_vol[trk] ; n -= 2 ) {
	DSP_line(x1, EUP_BAR_Y2 - n,
	         x2, EUP_BAR_Y2 - n,
	         10, M_PSET);
    }

    note_vol[trk] = note_max[trk] = vol;
}
int	EUP_chk(char *ptr)
{
    int n, sx, sy;
    int sw, x, y;

    if ( old_tick < tick_timer ) {
	for ( n = 0 ; n < TRK_MAX ; n++ ) {
	    if ( note_vol[n] >= 2 ) {
		note_vol[n] -= 2;
		DSP_line(EUP_BAR_X1 + n * 8,
			 EUP_BAR_Y2 - note_vol[n],
			 EUP_BAR_X2 + n * 8,
			 EUP_BAR_Y2 - note_vol[n],
			 7, M_PSET);
	    } else if ( note_vol[n] == 0 ) {
	        DSP_line(EUP_BAR_X1 + n * 8,
			 EUP_BAR_Y2 - note_max[n],
			 EUP_BAR_X2 + n * 8,
			 EUP_BAR_Y2 - note_max[n],
		         7, M_PSET);
		note_vol[n] = (-1);
	    }
	}
	old_tick += 16;
    }

    if ( ptr == NULL )
	return FALSE;

    if ( old_ptr == NULL )
	old_ptr = ptr;

    while ( old_ptr < ptr ) {
	if ( (*old_ptr & 0xF0) == 0x90 )
	    EUP_note_on(old_ptr[4] & 127, old_ptr[5] & 127);
	old_ptr += 6;
    }

    EVT_msg_no = ERR;
    if ( move_flag ) {
	MOS_rdpos(&sw, &x, &y);
	if ( eup_ox != x || eup_oy != y ) {
	    if ( (sx = eup_x1 + (x - eup_ox)) < 0 )
		sx = 0;
	    else if ( (sx + 268) >= 640 )
		sx = 640 - 268;
	    if ( (sy = eup_y1 + (y - eup_oy)) < 0 )
		sy = 0;
	    else if ( (sy + 128) >= 480 )
		sy = 480 - 128;
	    EUP_move(sx, sy);
	    eup_ox = x;
	    eup_oy = y;
	}
	if ( sw == 0 )
	    move_flag = FALSE;
    } else if ( EVT_chk(eup_rpy) != EVT_NON ) {
	if ( eup_rpy->now == EVT_SELECT_MOS ) {
	    old_ptr = NULL;
	    return TRUE;
	}
    } else if ( EVT_chk(eup_fwe) != EVT_NON ) {
	if ( eup_fwe->now == EVT_CLIP_MOS ) {
	    if ( fwe_flag == FALSE )
		SND_eup_relative_tempo_set(200);
	    fwe_flag = TRUE;
	} else if ( fwe_flag ) {
	    SND_eup_relative_tempo_set(0);
	    fwe_flag = FALSE;
	}
    } else {
	MOS_rdpos(&sw, &x, &y);
	if ( (sw & 2) != 0 )
	    return ERR;
	else if ( (sw & 1) != 0 ) {
	    move_flag = TRUE;
	    eup_ox = x;
	    eup_oy = y;
	}
    }

    return FALSE;
}
