/***************************************************************************
                          SimpleMove.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/SimpleMove.h"
# include "Board.h"
# include "Pieces/Piece.h"
# include "Game/GameObserver.h"
# include <Game/Game.h>
# include <stdlib.h>
# include <iostream>

namespace Alice
{

SimpleMove::Link*
SimpleMove::simplePool = 0;

SimpleMove::Link*
SimpleMove::doublePool = 0;

SimpleMove::Initializer
SimpleMove::initializer;

SmartPointer<Move> 
SimpleMove::instances[64][64];

void
SimpleMove::initializeClass()
{
  for (int i = 0; i < 64; i++)
    for (int j = 0; j < 64; j++)
      instances[i][j] = new SimpleMove(i, j);
};

void
SimpleMove::cleanUpClass()
{
  for (int i = 0; i < 64; i++)
    for (int j = 0; j < 64; j++)
      instances[i][j] = 0;
};

SimpleMove::SimpleMove(const Square& from, const Square& to):
  Move(from, to)
{};

SimpleMove::~SimpleMove()
{};

void
SimpleMove::makeOn(Board& b)
{
  assert(b.at(destination())->isNull());
  b.put(b.at(source()), destination());
  b.clear(source());
};

void
SimpleMove::takeBackOn(Board& b)
{
  b.put(b.at(destination()), source());
  b.clear(destination());
};

void
SimpleMove::makeOn(GameObserver& b)
{
  b.doSimpleMove(*this);
};

void
SimpleMove::takeBackOn(GameObserver& b)
{
  b.takeBackSimpleMove(*this);
};

bool 
SimpleMove::isLegal(const Game& game) const
{
  if (! Move::isLegal(game))
    return false;
  return game.board().at(destination())->isNull();
};

void
SimpleMove::operator delete (void* p, size_t s)
{
  assert(s == sizeof(SimpleMove));
  Link* l = reinterpret_cast<Link*>(p);
  l->next = simplePool;
  simplePool = l;
};

int SimpleMove::createdNew = 0;
int SimpleMove::reuse = 0;

void
SimpleMove::printInfo()
{
  std::cout<<"SimpleMove: ";
  std::cout<<createdNew<<" created new, ";
  std::cout<<reuse<<" reused, ";
  int i = 0;
  Link* l = simplePool;
  while(l) {
    l = l->next;
    i++;
  }
  std::cout<<"pool size: "<<i<<std::endl;
};

SmartPointer<Move>
SimpleMove::createInstance(const Square& from, const Square& to)
{
  if (simplePool != 0) {
    SimpleMove* p = reinterpret_cast<SimpleMove*>(simplePool);
    simplePool = simplePool->next;
    reuse ++;
    return new(p) SimpleMove(from, to);
  }
  createdNew ++;
  assert(sizeof(SimpleMove) >= sizeof(void*));
  SimpleMove* p = reinterpret_cast<SimpleMove*> (malloc(sizeof(SimpleMove)));
  return new(p) SimpleMove(from, to);
};

}; // namespace Alice
