#include	<stdio.h>
#include	<stdlib.h>
#include	<setjmp.h>

#include	<fmcfrb.h>

#include	"tb.h"
#include	"tb_lib.h"
#include	"tb_rand.h"
#include	"tb_scn.h"

static jmp_buf	JmpBufAbort;

static int		graphic_test(int pixel, int flagHr);

#define	ADJX32(_n)	((((_n)+31)/32)*32)

int		tb_main(void)
{
	KYB_init();
	KYB_clic(1);

	tb_init_colorRndTbl();
	if ( (TBcfg.listctrl = tb_listctrl_open()) == NULL )
		return (-1);
	tb_list_putf(TBcfg.listctrl,"\n");
	tb_list_putf(TBcfg.listctrl,"**** TOWNS BENCH MARK : ver." VERSION " #" EDITION " *****\n");
	tb_list_putf(TBcfg.listctrl,"\n");
	{
		char		tmp[80];
		DATETIME	dateToday;

		tb_getNowDate(&dateToday);
		tb_list_putf(TBcfg.listctrl,"# START TIME %s", tb_date2asc(tmp,&dateToday) );
		if ( TBcfg.ttlkey[0] != '\0' )
			tb_list_putf(TBcfg.listctrl," -- %s", TBcfg.ttlkey);
		tb_list_putf(TBcfg.listctrl,"\n\n");
	}

	TBcfg.xsTest = ADJX32(TBcfg.xsTest);

	if ( !(TBcfg.flags & TBFLAGS_MAXSCREEN) )
	{
		tb_list_putf(TBcfg.listctrl,"GRAPHIC TEST FRAME SIZE %3d X %3d\n",
		    TBcfg.xsTest, TBcfg.ysTest);
		tb_list_putf(TBcfg.listctrl,"\n");
	}

	if ( setjmp(JmpBufAbort) == 0 )
	{
		if ( !(TBcfg.flags & TBFLAGS_IGNORE_MR) )
		{
			static int	pixeltbl[] = {4,8,16};
			int			n;

			for ( n = 0; n < sizeof(pixeltbl)/sizeof(*pixeltbl); ++n )
				graphic_test(pixeltbl[n], 0);
		}

		if ( !(TBcfg.flags & TBFLAGS_IGNORE_HR) )
		{
			static int	pixeltbl[] = {4,8,16};
			int			n;

			for ( n = 0; n < sizeof(pixeltbl)/sizeof(*pixeltbl); ++n )
				graphic_test(pixeltbl[n], 1);
		}

		if ( !(TBcfg.flags & TBFLAGS_IGNORE_FC) )
			graphic_test(24, 1);

		tb_list_putf(TBcfg.listctrl,"\n");
		tb_list_putf(TBcfg.listctrl,"# END");
		if ( TBcfg.ttlkey[0] != '\0' )
			tb_list_putf(TBcfg.listctrl," -- %s", TBcfg.ttlkey);
		tb_list_putf(TBcfg.listctrl,"\n");
	}
	tb_term_colorRndTbl();
	tbSCN_initCrtc( 4, 0);

	{
		LISTDATA	*list;

		for ( list = TBcfg.listctrl->datTop; list != NULL; list = list->next )
			fputs(list->ptr,TBcfg.fpTxt);
	}

	return (0);
}

static int		graphic_test(int pixel, int flagHr)
{
	if ( tbSCN_initCrtc( pixel, flagHr) < 0 )
	{
#if	0	/* DEBUG */
		tb_list_putf(TBcfg.listctrl,"PIXEL = %3d ERROR\n",
		    TBscn.resoptr->pixel);
#endif
		return (-1);
	}

	tbSCN_setTestFrame();
	tb_init_pointRndTbl();

	tb_list_putf(TBcfg.listctrl,"RESOLUTION %4d X %4d, PIXEL %2d\n",
	    TBscn.resoptr->d.xs, TBscn.resoptr->d.ys, TBscn.resoptr->pixel );

	{
		tb_abort_check();	tbTST_egb_clearScreen();
		tb_abort_check();	tbTST_dac_clearScreen();
		tb_abort_check();	tbTST_egb_pointset()   ;	tb_get_blockbuffer(0);
		tb_abort_check();	tbTST_egb_line()       ;	tb_get_blockbuffer(1);
		tb_abort_check();	tbTST_egb_boxfill()    ;
		tb_abort_check();	tbTST_egb_circle()     ;
		tb_abort_check();	tbTST_egb_polygon()    ;	tb_get_blockbuffer(2);
		tb_abort_check();	tbTST_egb_putchar()    ;	tb_get_blockbuffer(3);
		tb_abort_check();	tbTST_egb_block()      ;	tb_put_blockbuffer(3);
		tb_abort_check();	tbTST_dac_block()      ;	tb_put_blockbuffer(0);
		tb_abort_check();	tbTST_dac_scroll()     ;
														tb_clear_blockbuffer();
	}
	tb_term_pointRndTbl();

	return (0);
}

void	tb_abort_check(void)
{
	unsigned int		ch, ec;

	ch = KYB_read(1,&ec);
	if ( ch == 0x1B )
	{
		tb_list_putf(TBcfg.listctrl,"\n");
		tb_list_putf(TBcfg.listctrl,"<<<<<ABORT>>>>>\n");
		longjmp(JmpBufAbort, 1);
	}
}

void	tb_error_abort(int err)
{
	tb_list_putf(TBcfg.listctrl,"\n");
	switch ( err )
	{
		case TBERR_OUT_OF_MEMORY:
			tb_list_putf(TBcfg.listctrl,"# OUT OF MEMORY!!\n");
			break;
		default:
			tb_list_putf(TBcfg.listctrl,"# unknown error (%d)!!\n",err);
			break;
	}
	tb_list_putf(TBcfg.listctrl,"<<<<<ERROR ABORT>>>>>\n");
	longjmp(JmpBufAbort, 1);
}
