/**********************************************************************
 *
 *   FreeDoko a Doppelkopf-Game
 *    
 *   Copyright (C) 2001-2005  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 "hand_card.h"

#include "../player/player.h"
#include "../game/game.h"
#include "../party/rule.h"

/**
 ** cosntructr
 **
 ** @param	hand	hand this card belongs to
 ** @param	card	card
 **
 ** @return	-
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.8
 **
 **/
HandCard::HandCard(Hand const& hand, Card const& card) :
  Card(card),
  hand_(&hand)
{
  return ;
} // HandCard::HandCard(Hand const& hand, Card const& card)

/**
 ** destructor
 **
 ** @param	-
 **
 ** @return	-
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.8
 **
 **/
HandCard::~HandCard()
{
  return ;
} // HandCard::~HandCard()

/**
 ** -> result
 **
 ** @param	-
 **
 ** @return	the player this card belongs to
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.8
 **
 **/
Player const&
HandCard::player() const
{
  return this->hand().player();
} // Player HandCard::player() const

/**
 ** -> result
 **
 ** @param	-
 **
 ** @return	the corresponding game
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.8
 **
 **/
Game const&
HandCard::game() const
{
  return this->player().game();
} // Game HandCard::game() const

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	true if card is trump
 **
 ** @version	0.6.8
 **
 ** @author	Diether Knof
 **
 **/
bool
HandCard::istrump() const
{
  if (this->isdolle())
    return true;

  switch(this->game().type()) {
  case GAMETYPE::FIVE_NINES:
    if (this->value() == NINE)
      return true;
    break;
  case GAMETYPE::SIX_KINGS:
    if (this->value() == KING)
      return true;
    break;
  case GAMETYPE::NORMAL:
  case GAMETYPE::POVERTY:
  case GAMETYPE::FOX_HIGHEST_TRUMP:
  case GAMETYPE::GENSCHER:
  case GAMETYPE::MARRIAGE:
  case GAMETYPE::MARRIAGE_SOLO:
  case GAMETYPE::MARRIAGE_SILENT:
  case GAMETYPE::SOLO_DIAMOND:
    if (this->color() == DIAMOND)
      return true;
    if ((this->value() == JACK)
	|| (this->value() == QUEEN))
      return true;
    break;
  case GAMETYPE::SOLO_JACK:
    if (this->value() == JACK)
      return true;
    break;
  case GAMETYPE::SOLO_QUEEN:
    if (this->value() == QUEEN)
      return true;
    break;
  case GAMETYPE::SOLO_KING:
    if (this->value() == KING)
      return true;
    break;
  case GAMETYPE::SOLO_QUEEN_JACK:
    if ((this->value() == JACK)
	|| (this->value() == QUEEN))
      return true;
    break;
  case GAMETYPE::SOLO_KING_JACK:
    if ((this->value() == JACK)
	|| (this->value() == KING))
      return true;
    break;
  case GAMETYPE::SOLO_KING_QUEEN:
    if ((this->value() == QUEEN)
	|| (this->value() == KING))
      return true;
    break;
  case GAMETYPE::SOLO_KOEHLER:
    if ((this->value() == JACK)
	|| (this->value() == QUEEN)
	|| (this->value() == KING))
      return true;
    break;
  case GAMETYPE::SOLO_CLUB:
    if (this->color() == CLUB)
      return true;
    if ((this->value() == JACK)
	|| (this->value() == QUEEN))
      return true;
    break;
  case GAMETYPE::SOLO_HEART:
    if (this->color() == HEART)
      return true;
    if ((this->value() == JACK)
	|| (this->value() == QUEEN))
      return true;
    break;
  case GAMETYPE::SOLO_SPADE:
    if (this->color() == SPADE)
      return true;
    if ((this->value() == JACK)
	|| (this->value() == QUEEN))
      return true;
    break;
  case GAMETYPE::SOLO_MEATLESS:
    break;
  } // switch(this->game().type())

  return false;
} // bool HandCard::istrump() const

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	true if card is a dolle
 **
 ** @version	0.6.8
 **
 ** @author	Diether Knof
 **
 **/
bool
HandCard::isdolle() const
{
  if (this->game().rule()(Rule::DOLLEN))
    return false;

  if (*this != Card::DOLLE)
    return false;

  bool value = false;

  switch (this->game().type()) {
  case GAMETYPE::NORMAL:
  case GAMETYPE::POVERTY:
  case GAMETYPE::GENSCHER:
  case GAMETYPE::MARRIAGE:
  case GAMETYPE::MARRIAGE_SOLO:
  case GAMETYPE::MARRIAGE_SILENT:
  case GAMETYPE::SOLO_CLUB:
  case GAMETYPE::SOLO_HEART:
  case GAMETYPE::SOLO_SPADE:
  case GAMETYPE::SOLO_DIAMOND:
    value = true;
    break;
  case GAMETYPE::SIX_KINGS:
  case GAMETYPE::FOX_HIGHEST_TRUMP:
  case GAMETYPE::SOLO_MEATLESS:
  case GAMETYPE::SOLO_JACK:
  case GAMETYPE::SOLO_QUEEN:
  case GAMETYPE::SOLO_KING:
  case GAMETYPE::SOLO_QUEEN_JACK:
  case GAMETYPE::SOLO_KING_JACK:
  case GAMETYPE::SOLO_KING_QUEEN:
  case GAMETYPE::SOLO_KOEHLER:
  case GAMETYPE::FIVE_NINES:
    value = false;
    break;
  } // switch (this->game().type())

  return value;
} // bool HandCard::isdolle() const

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	true if card is a swine
 **
 ** @version	0.6.8
 **
 ** @author	Diether Knof
 **
 **/
bool
HandCard::isswine() const
{
  return ((this->istrumpace()
	   && (this->game().swines_announced())));
} // bool HandCard::isswine()

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	true if card is a hyperswine
 **
 ** @version	0.6.8
 **
 ** @author	Diether Knof
 **
 ** @bug	not independent of the game
 **
 **/
bool
HandCard::ishyperswine() const
{
  return ((this->istrumpnine()
	   && (this->game().hyperswines_announced())));
} // bool HandCard::ishyperswine()

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	true if card is a fox
 **
 ** @version	0.6.8
 **
 ** @author	Diether Knof
 **
 **/
bool
HandCard::isfox() const
{
  return (GAMETYPE::is_normal(this->game().type())
	  && this->istrumpace()
	  && !this->isswine());
} // bool HandCard::isfox()

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	true if card is a trump ace
 **
 ** @version	0.6.8
 **
 ** @author	Diether Knof
 **
 **/
bool
HandCard::istrumpace() const
{
  return ((this->istrump()
	   && (this->value() == ACE)));
} // bool HandCard::istrumpace()

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	true if card is a trump nine
 **
 ** @version	0.6.8
 **
 ** @author	Diether Knof
 **
 **/
bool
HandCard::istrumpnine() const
{
  return ((this->istrump()
	   && (this->value() == NINE)));
} // bool HandCard::istrumpnine()

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @return	true if card is a trump king
 **
 ** @version	0.6.8
 **
 ** @author	Diether Knof
 **
 **/
bool
HandCard::istrumpking() const
{
  return ((this->istrump()
	   && this->value() == KING));
} // bool HandCard::istrumpking() const
