/**********************************************************************
 *
 *   FreeDoko a Doppelkopf-Game
 *    
 *   Copyright (C) 2001-2004  by Diether Knof and Borg Enders
 *
 *   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.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details. 
 *   You can find this license in the file 'gpl.txt'.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
 *   MA  02111-1307  USA
 *
 *  Contact:
 *    Diether Knof dknof@gmx.de
 *    Borg Enders  borg@borgsoft.de
 *
 *********************************************************************/

#include "constants.h"

#include "game.h"

#include "../party/rule.h"
#include "../card/trick.h"

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	number of tricks in game
 **
 ** @version	0.4.4
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 **/
unsigned
Game::trickno() const
{
  DEBUG_CALLING(INFO_GAME && INFO_VALUE,
		"Game::trickno()");

  DEBUG_RETURNING(this->rule()(Rule::NUMBER_OF_TRICKS_IN_GAME),
		  INFO_GAME && INFO_VALUE,
		  "Game::trickno()");
} // unsigned Game::trickno() const

/**
 **
 ** -> result
 **
 ** @param	t	number of trick, which should be result of this method
 **
 ** @return	returns trick i, if i is legal
 **		otherwise initialized trick
 **
 ** @version	0.4.4
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 **/
Trick const&
Game::trick(unsigned const& t) const
{
  DEBUG_ASSERTION((t < this->trick_p.size()),
		  "Game::trick(t):\n"
		  "  t = " << t << " is too great"
		  " (>= " << this->trick_p.size() << ")");

  return *this->trick_p[t];
} // Trick const& Game::trick(unsigned const& t) const

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	the current trick
 **
 ** @version	0.4.5
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 **/
Trick const&
Game::trick_current() const
{
  DEBUG_ASSERTION(!this->trick_p.empty(),
		  "Game::trick_current():\n"
		  "  Game::trick_p is empty");

  return *this->trick_p.back();
} // Trick const& Game::trick_current() const

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	the current trick
 **
 ** @version	0.4.4
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 **/
Trick&
Game::trick_current()
{
  DEBUG_ASSERTION(!this->trick_p.empty(),
		  "Game::trick_current():\n"
		  "  Game::trick_p is empty");

  return *this->trick_p.back();
} // Trick& Game::trick_current()

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	the number of the current trick
 **
 ** @version	0.6.7
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 ** @todo	replace with 'real_trick_current_no'
 **
 **/
unsigned
Game::trick_current_no() const
{
  if (this->trick_p.empty())
    if (::game_status < GAMESTATUS::GAME_PLAY)
      return UINT_MAX;
    else
      return 0;

  if ((::game_status == GAMESTATUS::GAME_FINISHED)
      || (this->trick_current().isfull()))
    return this->trick_p.size();

  return (this->trick_p.size() - 1);
} // unsigned Game::trick_current_no() const

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	the number of the current trick
 **
 ** @version	0.6.7
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 **/
unsigned
Game::real_trick_current_no() const
{
  if (this->trick_p.empty())
    if (::game_status < GAMESTATUS::GAME_PLAY)
      return UINT_MAX;
    else
      return 0;

  if (::game_status == GAMESTATUS::GAME_FINISHED)
    return this->trick_p.size();

  return (this->trick_p.size() - 1);
} // unsigned Game::real_trick_current_no() const

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	the number of remaining tricks
 **
 ** @version	0.4.4
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 **/
unsigned
Game::tricks_remaining_no() const
{
  DEBUG_CALLING(INFO_GAME && INFO_VALUE,
		"Game::tricks_remaining_no()");

  DEBUG_ASSERTION((this->trick_current_no() != UINT_MAX),
		  "Game::tricks_remaining_no():\n"
		  "  this->trick_current_no() == -1");

  DEBUG_RETURNING((this->trickno() - this->trick_current_no()),
		  INFO_GAME && INFO_VALUE,
		  "Game::tricks_remaining_no()");
} // unsigned Game::tricks_remaining_no() const

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	whether this is the last trick
 **
 ** @version	0.6.6
 **
 ** @author	Diether Knof
 **
 **/
bool
Game::is_last_trick() const
{
  DEBUG_CALLING(INFO_GAME && INFO_VALUE,
		"Game::is_last_trick()");

  DEBUG_RETURNING((this->tricks_remaining_no() == 1),
		  INFO_GAME && INFO_VALUE,
		  "Game::is_last_trick()");
} // bool Game::is_last_trick() const


/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	begin-iterator of the trick-vector
 **
 ** @version	0.4.4
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 **/
vector<Trick*>::const_iterator
Game::trick_begin() const
{
  return this->trick_p.begin();
} // vector<Trick*>::const_iterator Game::trick_begin() const

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	end-iterator of the trick-vector
 **
 ** @version	0.4.4
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 **/
vector<Trick*>::const_iterator
Game::trick_end() const
{
  return this->trick_p.end();
} // vector<Trick*>::const_iterator Game::trick_end() const
