#include "NTCurses.h"
#include <string.h>
#include "NTScreen.h"

namespace NTCurses {

NT::NTString global_clipboard;

NTCurses::NTCurses( unsigned int x , unsigned int y , unsigned int width , unsigned int height , bool makepanel ) {
	uX = x;
	uY = y;
	uWidth = width;
	uHeight = height;
	wWindow = newwin( uHeight , uWidth , uY , uX );
	if (makepanel) {
		pPanel = new_panel( wWindow );
	} else {
		pPanel = NULL;
	}
}

NTCurses::~NTCurses() {
	if (pPanel) {
		hide_panel( pPanel );
		del_panel( pPanel );
		UpdatePanels();
		pPanel = NULL;
	}
	if (wWindow) {
		delwin( wWindow );
		wWindow = NULL;
	}
	NTGetGlobalScreen()->SetDirty(true);
}

void NTCurses::Move( unsigned int x , unsigned int y , bool cursormove ) {
	if (!wWindow) return;
	wmove( wWindow , y , x );
#ifdef WIN32
	/* pdcurses workaround */
	if (cursormove) {
		NT::micro_log( "cursormove begin" );
		int bx,by;
		getbegyx( wWindow , by , bx );
		wmove( stdscr , by+y , bx+x );
		wrefresh( stdscr );
		NT::micro_log( "cursormove end" );
	}
#endif
}

unsigned int NTCurses::GetAttrFromString( NT::NTString str ) {
	if (strlen( str.c_str() )<3) return 0;
	unsigned int fgc=0;
	unsigned int bgc=0;
	unsigned int fgci,retval;

	char fg = tolower( str[0] );
	char fgi = tolower( str[1] );
	char bg = tolower( str[2] );

	switch (fg) {
	case 'n': fgc=0;break;
	case 'b': fgc=1;break;
	case 'g': fgc=2;break;
	case 'c': fgc=3;break;
	case 'r': fgc=4;break;
	case 'm': fgc=5;break;
	case 'y': fgc=6;break;
	case 'w': fgc=7;break;
	}

	switch (bg) {
	case 'n': bgc=0;break;
	case 'b': bgc=1;break;
	case 'g': bgc=2;break;
	case 'c': bgc=3;break;
	case 'r': bgc=4;break;
	case 'm': bgc=5;break;
	case 'y': bgc=6;break;
	case 'w': bgc=7;break;
	}

	fgci = (fgi=='+') ? 1 : 0;

	retval = COLOR_PAIR( bgc*8 + fgc + 1 );
	if (fgci) retval|=A_BOLD;
	return retval;
}

NTString NTCurses::GetStringFromAttr( unsigned int attr ) {
	NTString retval;
	bool bold;

	if (attr&A_BOLD) {
		attr = attr & ~A_BOLD;
		bold = true;
	} else {
		bold = false;
	}

	unsigned int fgc = PAIR_NUMBER(attr-1)&7;
	unsigned int bgc = ((PAIR_NUMBER(attr-1)>>3))&7;
	switch (fgc) {
	case 0:retval+="N";break;
	case 1:retval+="B";break;
	case 2:retval+="G";break;
	case 3:retval+="C";break;
	case 4:retval+="R";break;
	case 5:retval+="M";break;
	case 6:retval+="Y";break;
	case 7:retval+="W";break;
	}
	retval+=(bold) ? "+" : "-";
	switch (bgc) {
	case 0:retval+="N";break;
	case 1:retval+="B";break;
	case 2:retval+="G";break;
	case 3:retval+="C";break;
	case 4:retval+="R";break;
	case 5:retval+="M";break;
	case 6:retval+="Y";break;
	case 7:retval+="W";break;
	}
	return retval;
}

void NTCurses::SetAttr( unsigned int attr ) {
	if (!wWindow) return;
#ifndef WIN32
	attr|=A_PROTECT;
#endif
	wattrset( wWindow , attr );
}

void NTCurses::Refresh( void ) {
	if (!wWindow) return;
	NT::micro_log( "refresh begin" );
	wrefresh( wWindow );
	NT::micro_log( "refresh end" );
}

void NTCurses::ShowPanel( bool show = true ) {
	if (!pPanel) return;
	if (show)
		show_panel( pPanel );
	else
		hide_panel( pPanel );
}

void NTCurses::TopPanel( void ) {
	if (!pPanel) return;
	top_panel( pPanel );
}

void NTCurses::Clear() {
	if (!wWindow) return;
	werase( wWindow );
}

void NTCurses::PutChar( chtype ch ) {
	if (!wWindow) return;
	waddch( wWindow , NT::XlatChar( ch ) );
}


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

void NTCurses::PutString( NT::NTString str , unsigned int attr , char_replace_callback rc ) {
	if (!wWindow) return;

	unsigned int len = str.length();
	for (unsigned int i=0;i<len;i++) {
		unsigned int ch = ((unsigned char)str.at(i));
		if (rc) ch = ((*rc)(ch));
		ch = NT::XlatChar( ch );
		waddch( wWindow , ch | attr );
	}
}

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

void NTCurses::Box( void ) {
	if (!wWindow) return;
	box( wWindow , ACS_VLINE , ACS_HLINE );
}

void NTCurses::UpdatePanels( void ) {
	NT::micro_log( "update panels begin" );
	update_panels();
	doupdate();
	NT::micro_log( "update panels end" );
}

void NTCurses::Beep( void ) {
	beep();
	beep();
}

void NTCurses::Flash( void ) {
	beep();
	flash();
}

void NTCurses::SetGlobalClipboard( NT::NTString clp ) {
	global_clipboard = clp;
}

NT::NTString NTCurses::GetGlobalClipboard( void ) {
	return global_clipboard;
}

}
