/***************************************************************************
                          TestPosition.cpp  -  description
                             -------------------
    begin                : Tue May 22 2001
    copyright            : (C) 2001 by Sven Reichard
    email                : reichard@math.udel.edu
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 "TestData/TestPosition.h"
# include <Game/Game.h>
# include <Algorithms/HistoryAlphaBeta.h>
# include <Moves/SanNotation.h>
# include <Algorithms/HashedAlphaBeta.h>
# include <sstream>
using namespace Alice;
TestPosition::TestPosition(std::string pForsythe, 
			   std::string pBestMove,
			   std::string pTitle)
  : mTitle(pTitle),
    mForsythe(pForsythe),
    mBestMove(pBestMove)
{

};

TestPosition::TestPosition( const Game& g )
{
  std::string epd = g.getEPDString();
  std::istringstream input(epd);
  readEPD(input);
};

void
TestPosition::read(std::istream& in)
{
  in>>mForsythe;
  in>>mBestMove;
  in>>mTitle;
};
void
TestPosition::printHeader() const
{
  std::cout<<std::endl
	   <<"--------------------------------------"<<std::endl;
  std::cout<<title()<<std::endl;
  std::cout<<"Target move: "<<bestMove()<<std::endl;
};
bool TestPosition::search(int depth, HashedAlphaBeta& algo)
{
  Game g;
  g.forsytheString(forsythe());
  if (colorToMove == "b")
    {
      g.doNullMove();
    };
  algo.setGame(g);
  algo.search(depth);
  _bestMove = algo.bestMove();
  std::ostringstream out;
  algo.printPV(out);
  
  mPrincipalVariation = out.str();
  SanNotation san(_bestMove, g);
  //std::cout<<"san: "<<san.getString()<<std::endl;
  if (san.getString() == bestMove())
    return true;
  return _bestMove->fitsDescription(bestMove());
};

std::string
TestPosition::forsythe() const
{
  return mForsythe;
};

std::string
TestPosition::bestMove() const
{
  return mBestMove;
};

std::string
TestPosition::title() const
{
  return mTitle;
};

void
TestPosition::write( std::ostream& out ) const
{
  out << forsythe() << " " << bestMove() << " " << title() << std::endl;
};

const Move&
TestPosition::solution() const
{
  return *_bestMove;
};

std::string
TestPosition::principalVariation() const
{
  return mPrincipalVariation;
};

std::string
TestPosition::getColorToMove() const
{
  return colorToMove;
};

std::string
TestPosition::getCastlingRights() const
{
  return castlingRights;
};

std::string
TestPosition::getEnPassantSquare() const
{
  return enPassantSquare;
};

std::string
TestPosition::getOperand(const std::string& op) const
{
  std::map<std::string, std::string>::const_iterator entry 
    = operations.find(op);
  if (entry == operations.end())
    return "";
  return entry->second;
};

void
TestPosition::readEPDOperation(std::istream& in )
{

  std::string op;
  in >> op;
  char c;
  in >> c;
  if (! in )
    return;
  in.putback(c);
  std::string operand;
  while (in)
    {
      in.get(c);
      if (c == ';') break;
      operand += c;
    }
  operations[op] = operand;
  if (op == "bm")
    mBestMove = operand;
  if (op == "id")
    mTitle = operand;
}

void
TestPosition::readEPD( std::istream& in )
{
  in >> mForsythe;
  in >> colorToMove;
  in >> castlingRights;
  in >> enPassantSquare;
  char restOfLine[1024];
  in.getline(restOfLine, 1024);
  std::istringstream line(restOfLine);
  while ( line )
    readEPDOperation( line );
};

void
TestPosition::writeEPD( std::ostream& out ) const
{
  out << mForsythe << " ";
  out << colorToMove << " ";
  out << castlingRights << " ";
  out << enPassantSquare;
  for (std::map< std::string, std::string >::const_iterator it = operations.begin();
       it != operations.end(); ++ it)
    out << " " << it->first<<" "<<it->second<<";";
  out<<std::endl;
};

void
TestPosition::setOperand( const std::string& pre,
			  const std::string& img )
{
  operations[pre] = img;
};
