#include <string.h>
int GameMoves[ 1000 ];

void LogOutput ( char *pre, char *s )
{
FILE *fp = fopen ("outlog.txt", "at");
if (fp) {
	fprintf (fp, "%s%s\n", pre, s );
	fclose (fp);
	}
}

void LogBoard ( SBoard &Board )
{
const char cPieces[16] = { 'p', 'n', 'b', 'r', 'q', 'k', 0, 0, 'P', 'N', 'B', 'R', 'Q', 'K',0, 0};
char s[1024];
int j = 0;
strcpy (s, "");
for (int i = 20; i < 100; i++) {
	 if ( (i%10) == 0 || (i%10)==9) continue;
	 if (Board.m_Sqs[i] == 0) j+=sprintf (s+j, " . ");
	 if ((Board.m_Sqs[i]&BLACK)) j+=sprintf (s+j, " %c ", cPieces[(Board.m_Sqs[i]&7)]);
	 if ((Board.m_Sqs[i]&WHITE)) j+=sprintf (s+j, " %c ", cPieces[(Board.m_Sqs[i]&7)+8]);
	 if ( (i%10) == 8) j+=sprintf (s+j, "\n");
	}
j+=sprintf (s+j, "%d, %d : PCSq: %d\n", Board.WMat, Board.BMat, Board.Evaluate());
LogOutput ("", s);
}

void ReplayGame ( SBoard &Board, int nMoves ) {
	Board.Init();
	for( int i = 0; i < nMoves; i++) Board.DoMove ( GameMoves [i] );
}
void GetMoveString ( char *preFix, char *sMove, int move) {
	int Src = SRC(move), Dst = DST(move);
	sprintf (sMove, "%s%c%c%c%c\n", preFix, File(Src)+'a'-1, 9-Rank(Src)+'0', File(Dst)+'a'-1, 9-Rank(Dst)+'0' );
}
void SendMove ( int move) {
	char sMove[128];
	GetMoveString ( "move ",sMove, move );
	printf ( "%s", sMove );
	fflush (stdout);
	LogOutput ("sent> ", sMove);
}
void SendThinking ( int move, int Depth, int Eval, __int64 Nodes, int bFinished )
{
	char sMove[128];
	GetMoveString ( (bFinished)?"":"*", sMove, move );
	printf("%d %d %d %I64d %s\n", Depth, Eval, (clock()-g_start)/10, Nodes, sMove);
	fflush (stdout);
}

int GetMove ( char *s, SBoard &Board )
{
	if (s[0] < 'a' || s[0] > 'h' ||	s[1] < '0' || s[1] > '9' ||	s[2] < 'a' || s[2] > 'h' ||	s[3] < '0' || s[3] > '9') return -1;
	LogOutput ("GotMove> ", s);
	int Src = SQ(s[0]-'a',7-(s[1]-'1')), Dst = SQ(s[2]-'a', 7-(s[3]-'1') ), Upgrade = 3;
	if (s[4]=='n' || s[4]=='N') Upgrade = 0;				
	if (s[4]=='b' || s[4]=='B') Upgrade = 1;
	if (s[4]=='r' || s[4]=='R') Upgrade = 2;
	return Src + (Dst<<7) + (Upgrade<<14);
}

void WinboardLoop ( )
{
SBoard Board;
char CompColor = BLACK;
char line[1024], cmd[1024];
int move = 1, Eval = 0, time, inc = 0;

FILE *fp = fopen ("outlog.txt", "wt");
if (fp) fclose (fp);

while ( 1==1 ) {
	if (!fgets(line, 1000, stdin)) return;
	sscanf (line, "%s", cmd);
	LogOutput ("> ", line);
	move = GetMove ( line, Board );
	if (move > 1) {
		GameMoves [ Board.nMoves ] = move;
		Board.DoMove (move);
		AddRepBoard ( TEntry::HashBoard ( Board ), Board.nMoves);
		LogBoard ( Board );
		}

	if (strcmp (cmd, "go") == 0) CompColor = Board.stm;
	if (strcmp (cmd, "force") == 0) CompColor = -1;
	if (CompColor == Board.stm)	{
		move = 0;
		if (Board.nMoves == 0) {srand ( clock() );
			if (rand()%100 > 40) move = (85)+(65<<7); else move = (84)+(64<<7);
			}
		else ComputerMove ( Board, move, Eval );
		FILE *fp = fopen ("outlog.txt", "at");
		if (fp) {int nps = ((clock()-g_start)==0) ? 0: (int)((g_Nodes*1000)/(clock()-g_start));
				fprintf (fp, "Eval: %d  Nodes %I64d  Time %d  NPS %d\n", Eval, g_Nodes, clock()-g_start, nps );
				fclose (fp);
				}
		if (move) {
			SendMove ( move);
			GameMoves [ Board.nMoves ] = move;
			Board.DoMove ( move );
			AddRepBoard ( TEntry::HashBoard ( Board ), Board.nMoves);
			LogBoard ( Board );
			}
		}
	if (strcmp (cmd, "time")  == 0) {
		sscanf(line, "time %d", &time); 
		g_MaxTime = (CLOCKS_PER_SEC/100) * (time/30) + (inc * CLOCKS_PER_SEC);
		}
	if (strcmp (cmd, "level") == 0) {sscanf(line, "level %d %d %d", &time, &time, &inc); }
	if (strcmp (cmd, "new")   == 0) {Board.Init(); CompColor = BLACK;}
	if (strcmp (cmd, "quit")  == 0) return;
	if (strcmp (cmd, "white") == 0) CompColor = WHITE;
	if (strcmp (cmd, "black") == 0) CompColor = BLACK;
	if (strcmp (cmd, "undo")  == 0)  ReplayGame ( Board, Board.nMoves - 1);
	if (strcmp (cmd, "remove") == 0) ReplayGame ( Board, Board.nMoves - 2);
	}
}