/***************************************************************************
                          Move.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 "Moves/Move.h"
# include "Game/Game.h"
# include "Moves/SanNotation.h"
# include "Moves/PromotingMove.h"
# include <iostream>
using namespace Alice;

Move::Move(const Square& from, const Square& to):
  mSource(from),
  mDestination(to)
{
	//instances ++;
	//constructions ++;
};

Move::~Move()
{
	//instances --;
	//destructions ++;
};
/*
const  Square&
Move::source() const
{
return mSource;
  };

const Square&
Move::destination() const
{
  return mDestination;
};
*/
void
Move::makeOn(GameObserver& b)
{
  b.basicDoMove(*this);
};
void
Move::takeBackOn(GameObserver& b)
{
  b.basicTakeBack(*this);
};

void
Move::printOn(std::ostream& out) const
{
  
  out<<char('a'+source().file())<<char('1'+source().rank());
  //out<<'-';
  out<<char('a'+destination().file())<<char('1'+destination().rank());
};

bool 
Move::fitsDescription(const std::string description) const
{
  unsigned int i = 0;
  char c;
  do 
    c = description[i++];
  while (i < description.size() &&(c < 'a' || c > 'h'));
 
  if (c != 'a' + source().file())
    return false;
  if (i == description.size())
    return false;
  c = description[i++];
 
  if (c != '1'+source().rank())
    return false;
  do 

    c = description[i++];
  while (i < description.size() &&(c < 'a' || c > 'h'));
 
  if (c != 'a' + destination().file())
    return false;
  c = description[i++];
 
  if (c != '1'+destination().rank())
    return false;
  return true;
};
/** simple sanity check */
bool Move::isLegal(const Game& game) const{
	//return false;
	const Piece* movingPiece = game.board().at(source());
	if (movingPiece->isNull())
		return false;
	if (movingPiece->color() != game.colorToMove())
		return false;
	return true;
};

void
Move::modifySan(SanNotation& san) const
{};

void
Move::destroy()
{
	delete this;
}
bool
Move::fitsDescription(const SanNotation& san) const
{
  if (this->destination() != san.getMove()->destination())
    return false;
  if (san.hasSourceFile())
    if (this->source().file() != san.getSourceFile())
      return false;
  if (san.hasSourceRank())
    if (this->source().rank() != san.getSourceRank())
      return false;
  
  return true;
}

bool
Move::operator==(const Move& move) const
{
  return (this->source() == move.source()) &&
    (this->destination() == move.destination());
};

bool
Move::equalsPromotingMove(const PromotingMove& move) const
{
  return false;
};
