/***************************************************************************
                          proto_uci.cpp  -  description
                             -------------------
    begin                : Sat Oct 26 2002
    copyright            : (C) 2003 by Troy Corbin Jr.
    email                : tcorbin@users.sf.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include <tqstringlist.h>
#include <tqregexp.h>

#include "proto_uci.moc"
#include "definitions.h"

proto_uci::proto_uci( const int ID ) : proto_base( ID )
{
	hintMode = FALSE;
	initMode = FALSE;
	JustMoved = FALSE;
	myArmy = BLACK;
	Turn = WHITE;
	CMDList = new CommandList;
}
proto_uci::~proto_uci()
{
	delete CMDList;
}
///////////////////////////////////////
//
//	proto_uci::parse( const Command &command )
//
///////////////////////////////////////
void proto_uci::parse( const Command &command )
{
	Command cmd = command;

	if( initMode )
	{
		CMDList->append( command );
		return;
	}

	switch( cmd.getCommand() )
	{
		/* Command: Init */
		case CMD_Init:
			emit output( "uci" );
			initMode = TRUE;
			break;

		/* Command: New Game */
		case CMD_NewGame:
			emit output( "isready" );
			break;

		/* Command: Exit */
		case CMD_Exit:
			emit output( "quit" );
			break;

		/* Command: Move */
		case CMD_Move:
			if( JustMoved )
			{
				JustMoved = FALSE;
				break;
			}
			if( FEN.isEmpty() )
			{
				emit output( TQString("position startpos moves %1").arg( cmd.getData() ) );
			}
			else
			{
				emit output( TQString("position fen %1 moves %2").arg( FEN ).arg( cmd.getData() ) );
			}
			emit output( TQString("go wtime %1 btime %2 depth %3").arg( cmd.getWhiteTime() ).arg( cmd.getBlackTime() ).arg( difficulty ) );
			break;

		/* Command: Set Difficulty */
		case CMD_Set_Difficulty:
			difficulty = cmd.getData();
			break;

		/* Command: Set Board */
		case CMD_Set_Board:
			FEN = cmd.getData();
			break;

		/* Command: Move Now */
		case CMD_MoveNow:
			emit output( "stop" );
			break;

		/* Command: UCI Hint */
		case CMD_UCI_Hint:
			hintMode = TRUE;
			if( FEN.isEmpty() )
			{
				emit output( TQString("position startpos moves %1").arg( cmd.getData() ) );
			}
			else
			{
				emit output( TQString("position fen %1 moves %2").arg( FEN ).arg( cmd.getData() ) );
			}
			emit output( TQString("go wtime %1 btime %2 depth %3").arg( cmd.getWhiteTime() ).arg( cmd.getBlackTime() ).arg( difficulty ) );
			break;

		/* Command: Play White */
		case CMD_Play_White:
			myArmy = WHITE;
			break;

		/* Command: Play Black */
		case CMD_Play_Black:
			myArmy = BLACK;
			break;

		/* Command: Set Name */
		case CMD_Set_Name:
			engineName = cmd.getData();
			break;
	}
}
///////////////////////////////////////
//
//	proto_uci::parse( const TQString &string )
//
///////////////////////////////////////
void proto_uci::parse( const TQString &string )
{
	TQString strIn = string;
	TQStringList strList( TQStringList::split( ' ', strIn ) );

	/* Bestmove */
	if( strList[0] == "bestmove" )
	{
		if( strList.count() < 2 )
		{
			kdWarning() << "proto_uci::parse: Incomplete Bestmove command" << endl;
			return;
		}
		Command::clearMove( &myMove );
		strcpy( myMove.CAN, strList[1].latin1() );
		if( hintMode )
		{
			/* The Engine Gives a Hint */
			hintMode = FALSE;
//			emit output( Command( myID, CMD_Hint, i18n( "%1 suggests this move:\n%2" ).arg( engineName ).arg( strList[1] ) ) );
			emit output( Command( myID, CMD_Hint, TQString( "%1 suggests this move:\n%2" ).arg( engineName ).arg( strList[1] ) ) );
		}
		else
		{
			/* The Engine Moves */
			JustMoved = TRUE;
			emit output( Command( myID, CMD_Move, 0, 0, myMove ) );
		}
	}

	/* UCIOK */
	if( strList[0] == "uciok" )
	{
		initMode = FALSE;
		releaseBuffer();
	}

	/* READYOK */
	if( strList[0] == "readyok" )
	{
		initMode = FALSE;
		releaseBuffer();
	}

	/* ID */
	if( strList[0] == "id" )
	{
		if( strList[1] == "name" )
		{
			engineName = strIn.right( strIn.length() - 8 );
		}
		if( strList[1] == "author" )
		{
			engineAuthor = strIn.right( strIn.length() - 10 );
		}
	}

	/* COPYPROTECTION */
	if( strList[0] == "copyprotection" )
	{
		if( strList[1] == "error" )
		{
//			emit output( Command( myID, CMD_Tell_User_Error, i18n( "%1 did not pass it's copy protection check." ).arg( engineName ) ) );
			emit output( Command( myID, CMD_Tell_User_Error, TQString( "%1 did not pass it's copy protection check." ).arg( engineName ) ) );
		}
	}
}
///////////////////////////////////////
//
//	proto_uci::releaseBuffer
//
///////////////////////////////////////
void proto_uci::releaseBuffer( void )
{
	CommandList::Iterator it;
	for( it = CMDList->begin(); it != CMDList->end(); it++ )
	{
		parse( *it );
	}
	CMDList->clear();
}
