#include "NTScreen.h"
#include "NTForm.h"
#include "NTButton.h"
#include <sys/stat.h>
#include <unistd.h>
#ifdef WIN32
#include <windows.h>
#endif

namespace NTCurses {

NTScreen *oGlobalScreen = NULL;

NTScreen *NTGetGlobalScreen( void ) { return oGlobalScreen; }
void NTSetGlobalScreen( NTScreen *val ) { oGlobalScreen = val; }

unsigned int NT_rotcolorbits( unsigned int a ) {
#ifdef WIN32
	return a;
#else
	unsigned int r;
	switch (a) {
	default: r=a;break;
	case 1: r=4;break;
	case 3: r=6;break;
	case 4: r=1;break;
	case 6: r=3;break;
	}
	return r;	
#endif
}

NTScreen::NTScreen() {
	bDirty=true;
	wGlobal = initscr();
	start_color();
	noecho();
	cbreak();
	halfdelay( 1 );
	keypad( wGlobal , true );
	mousemask( ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION , &oldmousemask );

	for (int bg=0;bg<8;bg++) for (int fg=0;fg<8;fg++) init_pair( bg*8+fg+1,
		NT_rotcolorbits( fg ) ,
		NT_rotcolorbits( bg ) );

	int width,height;
	getmaxyx( wGlobal , height , width );
	uWidth = width;
	uHeight = height;
}

NTScreen::~NTScreen() {
	mousemask( oldmousemask , NULL );
	endwin();
}

void NTScreen::SetDirty( bool val ) {
	bDirty = val;
}

unsigned int NTScreen::GetWidth( void ) { return uWidth; }
unsigned int NTScreen::GetHeight( void ) { return uHeight; }

int NTScreen::TranslateChar( int ch ) {
	int retval;
	switch (ch) {
	case 369:
	case 507:
	   	retval=251;break;	// û
	case 368:
	case 491:
		retval=219;break;	// Û
	case 395:
		retval=0xf5;break;	// õ
	case 394:
		retval=0xd5;break;	// Õ
#ifdef WIN32
	// shift + function keys in pdcurses
	case 277:
	case 278:
	case 279:
	case 280:
	case 281:
	case 282:
	case 283:
	case 284:
	case 285:
	case 286:
		retval=ch-2;
		break;
#endif
	default:
		retval=ch;
		break;
	}
	return retval;
}

int NTScreen::GetChar( void ) {
	struct stat buf;
	int retval;

	SetDirty( true );
	Idle();
	retval = getch();
	NT::micro_log( "keypress wait" );
	while (retval == ERR) {
		Idle();
		retval = getch();
	}
	NT::micro_log( "keypress got" );
	Idle();
	retval = TranslateChar( retval );
	if (!stat( "./keys.log" , &buf )) {
		FILE *x = fopen( "./keys.log" , "a" );
		if (x) {
			time_t mytime = time( NULL );
			struct tm *tm = localtime( &mytime );
			fprintf( x , "%04d-%02d-%02d %02d:%02d:%02d - %5d - key:%d\n" ,
				tm->tm_year+1900,
				tm->tm_mon+1,
				tm->tm_mday,
				tm->tm_hour,
				tm->tm_min,
				tm->tm_sec,
				getpid(),
				retval );
			fclose( x );
		}
	}
	NT::micro_log( "keypress return" );
#ifdef WIN32
	retval = NT::XlatChar( retval , 852 , 28592 );
#endif
	return retval;
}

int NTScreen::GetImmedChar( void ) {
	nodelay( stdscr , true );
	int retval = getch();
	halfdelay( 1 );
	return retval;
}

NTMouseEvent NTScreen::GetMouseEvent( void ) {
	MEVENT mevent;
#ifdef WIN32
	nc_getmouse( &mevent );
#else
	getmouse( &mevent );
#endif
	return NTMouseEvent(
		mevent.x,
		mevent.y,
		mevent.z,
		mevent.bstate );
}

void NTScreen::ProgrammaticIdle( void ) {
	Idle();
}

void NTScreen::Idle( void ) {
}

void NTScreen::ShowCursor( bool show ) {
	curs_set( show );
}

void NTScreen::SetCursorState( bool show ) {
	bShowCursor = show;
}

bool NTScreen::GetCursorState( void ) {
	return bShowCursor;
}

}
