#include <tos.h>
#include <vdi.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ext.h>
#include <screen.h>

#include "gfx.h"
#include "gui.h"

#ifdef WITHOUT_VDI
# ifndef WITHOUT_GFX
#  error "GFX without VDI currently unsupported!"
# endif
#else
static short old_bgcolor[3];
static short old_fgcolor[3];
static short old_rez = -1;
static short medres = 0;
#endif

short vdih;
short vdiph;
short vdivh;
short workin[16];
short workout[58];

/* textmode resolution: */
short c_rows;
short c_cols;

short cell_h = 16;
short cell_w = 8;

short res_w;
short res_h;

void * screen;
short screen_bpp;
long screen_ncolors;

static short appl_id;

extern void die(char *);

static short linea_word( short idx  )
{
	return( *(short*)(lineavar+idx) );
}


void textxy(short x, short y, short inv, char * str)
{
	if( inv ) {
		Rev_on();
	}
	Goto_pos( y, x );
	Cconws( str );
	if( inv ) {
		Rev_off();
	}
}

void fillspace(short x, short y, short w, short black)
{
	short n =  w;
	char mem[1024];
	char * line = (char*)&mem; 
	n = ( n > 1023 ) ? 1023 : n;
	memset( line, ' ', n );
	line[n] = 0;
	textxy( x, y, black, line );
}

void draw_title( char * txt )
{

	char spare[255];
#ifndef WITHOUT_GFX /* Grahic support enabled? */
	txt = txt;
	textxy( 26, 1, 0, VERSION );
	sprintf(spare, "%dx%d@%d", res_w, res_h, screen_bpp );
	textxy( c_cols-(strlen((char*)&spare)+4), 0, 1, (char*)&spare );
	draw_logo( 0, 0 );
#else
	fillspace(0, 0, c_cols, 1);
	if( txt == NULL ) {
		textxy( 1, 0, 1, "ColdBoot " VERSION );
		sprintf(spare, "%dx%d@%d", res_w, res_h, screen_bpp );
		textxy( c_cols-(strlen((char*)&spare)+4), 0, 1, (char*)&spare );
	} else {
		textxy( 1, 0, 1, txt );
	}
#endif
}


void draw_info( char * txt )
{
	fillspace( 0, c_rows-1, c_cols, 1);
	textxy( 0, c_rows-1, 1, txt );
}

void clear_workarea( void ){
	int i;
	for( i=1; i<c_rows-1; i++ ){
		fillspace(0, i, c_cols, 0);
	}
}

void exit_proc( void ) 
{
	appl_exit( appl_id );
#ifndef WITHOUT_VDI
	vs_color( vdih, 0, old_bgcolor );
	vs_color( vdih, 1, old_fgcolor );
	if ( old_rez == 0 && medres == 1 ) {
		Setscreen( -1, -1, 0 );	
	}
#endif

}


void init_gui( void )
{

	short i = 0;
	

#ifdef WITHOUT_VDI
	vdih = 0;
	vdiph = 0;
	vdivh = 0;
#ifdef __COLDFIRE__
	linea_init_cf();
#else
	linea_init();
	if( Getrez() == 0 ){
		Setscreen( -1, -1, 1 );	
		if( Getrez() == 1 ) {
			medres = 1;
			old_rez = 0;
		}
	}
#endif
	cell_h = linea_word( LINEA_CELL_H );
	res_w = linea_word( LINEA_RES_W );
	res_h = linea_word( LINEA_RES_H );
	c_rows = res_h / cell_h;
	c_cols = res_w / cell_w;
	screen_bpp = linea_word( LINEA_PLANES );
#else

	short bgcolor[3] = { 0, 0, 0};
	short fgcolor[3] = { 0, 0, 1000 };
	medres = 0;
	/* looks like we need LineA to inquire screen char cells: */
	linea_init();
	if( Getrez() == 0 ){
		Setscreen( -1, -1, 1 );	
		if( Getrez() == 1 ) {
			medres = 1;
			old_rez = 0;
		}
	}

	for( i=1; i< 10; i++)
		workin[i]=1;
	workin[0] = 1;
	workin[10] = 2;
	appl_id = appl_init();
	if( appl_id == -1 ) {
		v_opnwk( workin, (short*)&vdiph, workout );
		if( vdiph == 0 ) {
			printf("Error opening Physical VDI Workstation");
		}
		vdih = vdiph;
	} else {	
		v_opnvwk( workin, (short*)&vdivh, workout );
		if( vdivh == 0 ) {
			die("Error opening Virtual VDI Workstation");
		}
		vdih = vdivh;
		atexit( exit_proc );
	}
	res_w = workout[0]+1;
	res_h = workout[1]+1;
	screen_ncolors = workout[13];
	if( 1 ) {
		cell_h = linea_word( LINEA_CELL_H );
		res_w = linea_word( LINEA_RES_W );
		res_h = linea_word( LINEA_RES_H );
		c_rows = res_h / cell_h;
		c_cols = res_w / cell_w;
		screen_bpp = linea_word( LINEA_PLANES );	
	} else {
		/* looks like this doesn't work on plain ST: */
		vq_chcells( vdih, &c_rows, &c_cols ); 	
	}
	vq_color( vdih, 0, 1, old_bgcolor );
	vq_color( vdih, 1, 1, old_fgcolor );
	vs_color( vdih, 0, bgcolor );
	vs_color( vdih, 1, fgcolor );
#endif
/*
	sprintf(spare, "c: %d, r: %d, x: %d, y: %d, stride: %d", c_cols, c_rows, 
		res_w, res_h, linea_word( LINEA_BYTES_PER_ROW )
	);
	Cconws( spare );
*/
	/*getch();*/
	/* Bildschirm loeschen und standard Werte setzen: */
	for( i=0; i<c_rows; i++ ){
		fillspace(0, i, c_cols, 0);
	}
	Cur_home();
}

void exit_gui(void)
{
	
}


short getkey( char * shift, short * keycode, char * ascii )
{
	long in = Cnecin();
	*ascii = (in & 0xFF);
	*keycode = ((in & 0xFF0000L)>>8);
	*shift =  ((in & 0xFF000000L)>>24);
	if( (in & 0xFF) == 0 ){
		in = ( (in & 0xFF0000L)>>8 );
	} else {
		in = (char)(in & 0xFF);
	}
	return( (short)in );
}
