/**********************************************************************
 *
 *   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 "basistypes.h"


////////////////
// GAMESTATUS //
////////////////
// status of the current game
GameStatus game_status = GAMESTATUS::PROGRAMSTART;


/**********************************************************************
 *
 ** string name(GameStatus const& game_status)
 *
 ** Parameters:  game_status - the game_status
 *
 ** Result:  name of the game_status
 *
 ** Version: 0.4.1
 *
 ** Description: -> result
 *
 **********************************************************************/
string
name(GameStatus const& game_status)
{
  DEBUG_CALLING(INFO_GAMESTATUS && INFO_NAME,
		"string name(game_status)");

  using namespace GAMESTATUS;

  string name;

  switch(game_status) {
  case PROGRAMSTART:
    name = "program start";
    break;
  case QUIT:
    name = "quit";
    break;
  case PARTY_NEW:
    name = "party new";
    break;
  case PARTY_INIT:
    name = "party init";
    break;
  case PARTY_PLAY:
    name = "party play";
    break;
  case PARTY_FINISHED:
    name = "party finished";
    break;
  case GAME_NEW:
    name = "game new";
    break;
  case GAME_INIT:
    name = "game init";
    break;
  case GAME_RESERVATION:
    name = "game reservation";
    break;
  case GAME_REDISTRIBUTE:
    name = "game redistribute";
    break;
  case GAME_POVERTY_SHIFT:
    name = "game poverty shift";
    break;
  case GAME_PLAY:
    name = "game play";
    break;
  case GAME_FULL_TRICK:
    name = "game full trick";
    break;
  case GAME_FINISHED:
    name = "game finished";
    break;
  } // switch(game_status)

  DEBUG_RETURNING(name,
		  INFO_GAMESTATUS && INFO_NAME,
		  "string name(game_status)");
} // string name(GameStatus const& game_status)

/**********************************************************************
 *
 ** ostream& operator<<(ostream& ostr, GameStatus const& game_status)
 *
 ** Parameters:  ostr - output stream
 **      game_status - game status
 *
 ** Result:  output stream
 *
 ** Version: 0.4.1
 *
 ** Description: output of the game status
 *
 **********************************************************************/
ostream&
operator<<(ostream& ostr, GameStatus const& game_status)
{
  DEBUG_CALLING(INFO_GAMESTATUS && INFO_IO,
		"ostream& operator<<(ostream&, game_status)");

  ostr << name(game_status);

  DEBUG_RETURNING(ostr,
		  INFO_GAMESTATUS && INFO_IO,
		  "ostream& operator<<(ostream&, game_status)");
} // ostream operator<<(ostream, game_status);


//////////
// Team //
//////////

/**********************************************************************
 *
 **    Team maybe_to_team(Team const t)
 *
 **    Parameters:  Team of which type should be known
 *
 **    Result: RE for t==RE or t==MAYBE_RE
 **            CONTRA for t==CONTRA or t==MAYBE_CONTRA
 **            UNKNOWN Otherwise
 *
 **    Version: Alpha
 *
 **    Description: 
 **      
 *
 **********************************************************************/
Team
maybe_to_team(Team const& t)
{
  DEBUG_CALLING(INFO_TEAM && INFO_TEAM,
		"Team maybe_to_team(Team t)");  

  using namespace TEAM;

  if ((t==RE)
      || (t==MAYBE_RE))
    DEBUG_RETURNING(RE,
		    INFO_TEAM && INFO_TEAM,
		    "Team maybe_to_team(Team t) = re"); 
  if ((t==CONTRA)
      || (t==MAYBE_CONTRA))
    DEBUG_RETURNING(CONTRA,
		    INFO_BASISTYPES && INFO_TEAM,
		    "Team maybe_to_team(Team t) = contra"); 

  DEBUG_RETURNING(UNKNOWN,
		  INFO_BASISTYPES && INFO_TEAM,
		  "Team maybe_to_team(Team t) = unknown"); 
} // Team maybe_to_team(Team const& t)


/**********************************************************************
 *
 **    Team team_to_maybe(Team const& t)
 *
 **    Parameters:  Team of which type should be known
 *
 **    Result: MAYBE_RE for t==RE 
 **            MAYBE_CONTRA for t==CONTRA 
 **            UNKNOWN Otherwise
 *
 **    Version: Alpha
 *
 **    Description: 
 **      used for comparison with on team
 *
 **********************************************************************/
Team
team_to_maybe(Team const& t)
{
  DEBUG_CALLING(INFO_BASISTYPES && INFO_TEAM,
		"Team team_to_maybe(Team t)");

  using namespace TEAM;

  if (t==RE)
    DEBUG_RETURNING(MAYBE_RE,
		    INFO_BASISTYPES && INFO_TEAM,
		    "Team team_to_maybe(Team t) = maybe re"); 

  if ((t==CONTRA))
    DEBUG_RETURNING(MAYBE_CONTRA,
		    INFO_BASISTYPES && INFO_TEAM,
		    "Team team_to_maybe(Team t) = maybe contra"); 

  DEBUG_RETURNING(UNKNOWN,
		  INFO_BASISTYPES && INFO_TEAM,
		  "Team team_to_maybe(Team t) = unknown"); 
} // Team team_to_maybe(Team const& t)

/**********************************************************************
 *
 **    Team opposite(Team const& t)
 *
 **    Parameters:  Team of which type should be known
 *
 **    Result: CONTRA for t==RE 
 **            RE for t==CONTRA 
 **            UNKNOWN Otherwise
 *
 **    Version: Alpha
 *
 **    Description: 
 **      
 **********************************************************************/
Team
opposite(Team const& t)
{
  DEBUG_CALLING(INFO_BASISTYPES && INFO_TEAM,
		"Team opposite(Team t)");

  using namespace TEAM;

  if (t==RE)
    DEBUG_RETURNING(CONTRA,
		    INFO_BASISTYPES && INFO_TEAM,
		    "Team opposite(Team t) = re");

  if (t==CONTRA)
    DEBUG_RETURNING(RE,
		    INFO_BASISTYPES && INFO_TEAM,
		    "Team opposite(Team t) = contra");;

  DEBUG_RETURNING(UNKNOWN,
		  INFO_BASISTYPES && INFO_TEAM,
		  "Team opposite(Team t) = unknown");
} // Team opposite(Team const& t)

/**********************************************************************
 *
 ** string name(Team const& team)
 *
 ** Parameters:  team - the team
 *
 ** Result:  name of the team
 *
 ** Version: 0.4.1
 *
 ** Description: -> result
 *
 **********************************************************************/
string
name(Team const& team)
{
  DEBUG_CALLING(INFO_TEAM && INFO_NAME,
		"string name(Team const& team)");

  using namespace TEAM;

  string name;

  switch(team) {
  case RE:
    name = "re";
    break;
  case CONTRA:
    name = "contra";
    break;
  case MAYBE_RE:
    name = "maybe re";
    break;
  case MAYBE_CONTRA:
    name = "maybe contra";
    break;
  case UNKNOWN:
    name = "unknown team";
    break;
  case NOTEAM:
    name = "no team";
    break;
  } // switch(team)

  DEBUG_RETURNING(name,
		  INFO_TEAM && INFO_NAME,
		  "string name(Team const& team)");
} // string name(Team const& team)

/**********************************************************************
 *
 ** ostream& operator<<(ostream& ostr, Team const& team)
 *
 ** Parameters:  ostr - output stream
 **      team - team
 *
 ** Result:  output stream
 *
 ** Version: 0.4.1
 *
 ** Description: output of the team
 *
 **********************************************************************/
ostream&
operator<<(ostream& ostr, Team const& team)
{
  DEBUG_CALLING(INFO_TEAM && INFO_IO,
		"ostream& operator<<(ostream&, team)");

  ostr << name(team);

  DEBUG_RETURNING(ostr,
		  INFO_TEAM && INFO_IO,
		  "ostream& operator<<(ostream&, team)");
} // ostream operator<<(ostream, team);



//////////////
// GAMETYPE //
//////////////

/**********************************************************************
 *
 ** string name(GameType const& gametype)
 *
 ** Parameters:  gametype - the GameType
 *
 ** Result:  name of the GameType
 *
 ** Version: 0.4.1
 *
 ** Description: -> result
 *
 **********************************************************************/
string
name(GameType const& gametype)
{
  DEBUG_CALLING(INFO_GAMETYPE && INFO_NAME,
		"string name(GameType const& gametype)");

  using namespace GAMETYPE;

  string name;

  switch(gametype) {
  case NORMAL:
    name = "normal";
    break; 
  case FIVE_NINES:
    name = "five nines";
    break;
  case SIX_KINGS:
    name = "six kings";
    break;
  case FOX_HIGHEST_TRUMP:
    name = "fox highest trump";
    break;
  case POVERTY:
    name = "poverty";
    break;
  case GENSCHER:
    name = "genscher";
    break;
  case MARRIAGE:
    name = "marriage";
    break;
  case MARRIAGE_SOLO:
    name = "marriage solo";
    break;
  case MARRIAGE_SILENT:
    name = "marriage silent";
    break;
  case SOLO_JACK:
    name = "solo jack";
    break;
  case SOLO_QUEEN:
    name = "solo queen";
    break;
  case SOLO_KING:
    name = "solo king";
    break;
  case SOLO_QUEEN_JACK:
    name = "solo queen-jack";
    break;
  case SOLO_KING_JACK:
    name = "solo king-jack";
    break;
  case SOLO_KING_QUEEN:
    name = "solo king-queen";
    break;
  case SOLO_KOEHLER:
    name = "solo koehler";
    break;
  case SOLO_CLUB:
    name = "solo club";
    break; 
  case SOLO_SPADE:
    name = "solo spade";
    break;
  case SOLO_HEART:
    name = "solo heart";
    break;
  case SOLO_DIAMOND:
    name = "solo diamond";
    break; 
  case SOLO_MEATLESS:
    name = "solo meatless";
    break;
  } // switch(gametype)

  DEBUG_RETURNING(name,
		  INFO_GAMETYPE && INFO_NAME,
		  "string name(GameType const& gametype)");
} // string name(GameType const& gametype)

/**
 **
 ** -> result
 **
 ** @param	-
 **
 ** @result	whether the status is in a running game
 **
 ** @author	Borg Enders
 ** @author	Diether Knof
 **
 ** @version	0.6.4
 **
 **/
bool
in_running_game()
{
  return ((::game_status == GAMESTATUS::GAME_PLAY)
	  || (::game_status == GAMESTATUS::GAME_FULL_TRICK));
} // bool in_running_game()

/**********************************************************************
 *
 ** ostream& operator<<(ostream& ostr, GameType const& game_type)
 *
 ** Parameters:  ostr - output stream
 **      game_type - game type
 *
 ** Result:  output stream
 *
 ** Version: 0.4.1
 *
 ** Description: output of the game type
 *
 **********************************************************************/
ostream&
operator<<(ostream& ostr, GameType const& game_type)
{
  DEBUG_CALLING(INFO_GAMETYPE && INFO_IO,
		"ostream& operator<<(ostream&, game_type)");

  ostr << name(game_type);

  DEBUG_RETURNING(ostr,
		  INFO_GAMETYPE && INFO_IO,
		  "ostream& operator<<(ostream&, game_type)");
} // ostream operator<<(ostream, game_type);

/**
 **
 ** -> return
 **
 ** @param	game_type	the game type
 **
 ** @return	whether 'game_type' is a 'normal' game
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.6
 **
 **/
bool
GAMETYPE::is_normal(GameType const game_type)
{
  switch (game_type) {
  case GAMETYPE::NORMAL:
  case GAMETYPE::POVERTY:
  case GAMETYPE::MARRIAGE:
  case GAMETYPE::GENSCHER:
    return true;
    break;
  default:
    return false;
    break;
  }; // switch(game_type)
} // bool GAMETYPE::is_normal(GameType const game_type)

/**
 **
 ** -> return
 **
 ** @param	game_type	the game type
 **
 ** @return	whether 'game_type' is a marriage
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.6
 **
 **/
bool
GAMETYPE::is_marriage(GameType const game_type)
{
  if (GAMETYPE::is_color_solo(game_type)
      || GAMETYPE::is_picture_solo(game_type))
    return true;

  switch (game_type) {
  case GAMETYPE::MARRIAGE:
  case GAMETYPE::MARRIAGE_SOLO:
  case GAMETYPE::MARRIAGE_SILENT:
    return true;
    break;
  default:
    return false;
    break;
  }; // switch(game_type)
} // bool GAMETYPE::is_marriage(GameType const game_type)

/**
 **
 ** -> return
 **
 ** @param	game_type	the game type
 **
 ** @return	whether 'game_type' is a poverty
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.6
 **
 **/
bool
GAMETYPE::is_poverty(GameType const game_type)
{
  switch (game_type) {
  case FIVE_NINES:
  case SIX_KINGS:
  case FOX_HIGHEST_TRUMP:
  case POVERTY:
    return true;
    break;
  default:
    return false;
    break;
  }; // switch(game_type)
} // bool GAMETYPE::is_poverty(GameType const game_type)

/**
 **
 ** -> return
 **
 ** @param	game_type	the game type
 **
 ** @return	whether 'game_type' is a solo
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.6
 **
 **/
bool
GAMETYPE::is_solo(GameType const game_type)
{
  if (GAMETYPE::is_color_solo(game_type)
      || GAMETYPE::is_picture_solo(game_type))
    return true;

  switch (game_type) {
  case GAMETYPE::SOLO_MEATLESS:
  case GAMETYPE::MARRIAGE_SOLO:
  case GAMETYPE::MARRIAGE_SILENT:
    return true;
    break;
  default:
    return false;
    break;
  }; // switch(game_type)
} // bool GAMETYPE::is_solo(GameType const game_type)

/**
 **
 ** -> return
 **
 ** @param	game_type	the game type
 **
 ** @return	whether 'game_type' is a color solo
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.6
 **
 **/
bool
GAMETYPE::is_color_solo(GameType const game_type)
{
  switch (game_type) {
  case GAMETYPE::SOLO_CLUB:
  case GAMETYPE::SOLO_SPADE:
  case GAMETYPE::SOLO_HEART:
  case GAMETYPE::SOLO_DIAMOND:
    return true;
    break;
  default:
    return false;
    break;
  }; // switch(game_type)
} // bool GAMETYPE::is_color_solo(GameType const game_type)

/**
 **
 ** -> return
 **
 ** @param	game_type	the game type
 **
 ** @return	whether 'game_type' is a picture solo
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.6
 **
 **/
bool
GAMETYPE::is_picture_solo(GameType const game_type)
{
  return ( GAMETYPE::is_single_picture_solo(game_type)
	   || GAMETYPE::is_double_picture_solo(game_type)
	   || (game_type == GAMETYPE::SOLO_KOEHLER));
} // bool GAMETYPE::is_picture_solo(GameType const game_type)

/**
 **
 ** -> return
 **
 ** @param	game_type	the game type
 **
 ** @return	whether 'game_type' is a single picture solo
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.6
 **
 **/
bool
GAMETYPE::is_single_picture_solo(GameType const game_type)
{
  switch (game_type) {
  case GAMETYPE::SOLO_JACK:
  case GAMETYPE::SOLO_QUEEN:
  case GAMETYPE::SOLO_KING:
    return true;
    break;
  default:
    return false;
    break;
  }; // switch(game_type)
} // bool GAMETYPE::is_single_picture_solo(GameType const game_type)

/**
 **
 ** -> return
 **
 ** @param	game_type	the game type
 **
 ** @return	whether 'game_type' is a double picture solo
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.6
 **
 **/
bool
GAMETYPE::is_double_picture_solo(GameType const game_type)
{
  switch (game_type) {
  case GAMETYPE::SOLO_QUEEN_JACK:
  case GAMETYPE::SOLO_KING_JACK:
  case GAMETYPE::SOLO_KING_QUEEN:
    return true;
    break;
  default:
    return false;
    break;
  }; // switch(game_type)
} // bool GAMETYPE::is_double_picture_solo(GameType const game_type)



//////////////////
// ANNOUNCEMENT //
//////////////////

/**
 **
 ** -> result
 **
 ** @param	announcement	announcement
 **
 ** @result	name of the announcement
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.4
 **
 **/
string
name(Announcement const& announcement)
{
  DEBUG_CALLING(INFO_ANNOUNCEMENT && INFO_NAME,
		"string name(Announcement const& announcement)");

  using namespace ANNOUNCEMENT;

  string name;

  switch(announcement) {
  case NOANNOUNCEMENT:
    name = "no announcement";
    break;
  case NO120:
    name = "no 120";
    break;
  case NO90:
    name = "no 90";
    break;
  case NO60:
    name = "no 60";
    break;
  case NO30:
    name = "no 30";
    break;
  case NO0:
    name = "no 0";
    break;
  case REPLY:
    name = "announcement reply";
    break;
  case NO120_REPLY:
    name = "no 120 reply";
    break;
  case NO90_REPLY:
    name = "no 90 reply";
    break;
  case NO60_REPLY:
    name = "no 60 reply";
    break;
  case NO30_REPLY:
    name = "no 30 reply";
    break;
  case NO0_REPLY:
    name = "no 0 reply";
    break;
  } // switch(announcement)

  DEBUG_RETURNING(name,
		  INFO_ANNOUNCEMENT && INFO_NAME,
		  "string name(Announcement const& announcement)");
} // string name(Announcement const& announcement)

/**********************************************************************
 *
 ** ostream& operator<<(ostream& ostr, Announcement const& announcement)
 *
 ** Parameters:  ostr - output stream
 **      announcement - announcement
 *
 ** Result:  output streamoutput stream
 *
 ** Version: 0.4.1
 *
 ** Description: output of the announcement
 *
 **********************************************************************/
ostream&
operator<<(ostream& ostr, Announcement const& announcement)
{
  DEBUG_CALLING(INFO_ANNOUNCEMENT && INFO_IO,
		"ostream& operator<<(ostream&, announcement)");

  ostr << name(announcement);

  DEBUG_RETURNING(ostr,
		  INFO_ANNOUNCEMENT && INFO_IO,
		  "ostream& operator<<(ostream&, announcement)");
} // ostream& operator<<(ostr, announcement)

/**
 **
 ** -> result
 **
 ** @param	announcement	announcement
 **
 ** @return	whether the announcement is a real announcement (no reply)
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.4
 **
 **/
bool
ANNOUNCEMENT::is_real(Announcement const& announcement)
{
  DEBUG_CALLING(INFO_ANNOUNCEMENT && INFO_VALUE,
		"ANNOUNCEMENT::is_real(announcement)");

  using namespace ANNOUNCEMENT;

  bool value = false;

  switch(announcement) {
  case NOANNOUNCEMENT:
    value = false;
    break;
  case NO120:
  case NO90:
  case NO60:
  case NO30:
  case NO0:
    value = true;
    break;
  case REPLY:
  case NO120_REPLY:
  case NO90_REPLY:
  case NO60_REPLY:
  case NO30_REPLY:
  case NO0_REPLY:
    value = false;
    break;
  } // switch(announcement)

  DEBUG_RETURNING(value,
		  INFO_ANNOUNCEMENT && INFO_VALUE,
		  "ANNOUNCEMENT::is_real(announcement)");
} // bool ANNOUNCEMENT::is_real(Announcement const& announcement)
/**
 **
 ** -> result
 **
 ** @param	announcement	announcement
 **
 ** @return	whether the announcement is a reply
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.4
 **
 **/
bool
ANNOUNCEMENT::is_reply(Announcement const& announcement)
{
  DEBUG_CALLING(INFO_ANNOUNCEMENT && INFO_VALUE,
		"ANNOUNCEMENT::is_reply(announcement)");

  using namespace ANNOUNCEMENT;

  bool value = false;

  switch(announcement) {
  case NOANNOUNCEMENT:
    value = false;
    break;
  case NO120:
  case NO90:
  case NO60:
  case NO30:
  case NO0:
    value = false;
    break;
  case REPLY:
  case NO120_REPLY:
  case NO90_REPLY:
  case NO60_REPLY:
  case NO30_REPLY:
  case NO0_REPLY:
    value = true;
    break;
  } // switch(announcement)

  DEBUG_RETURNING(value,
		  INFO_ANNOUNCEMENT && INFO_VALUE,
		  "ANNOUNCEMENT::is_reply(announcement)");
} // bool ANNOUNCEMENT::is_reply(Announcement const& announcement)

/**
 **
 ** -> result
 **
 ** @param	announcement	announcement
 **
 ** @return	reply version of 'announcement'
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.4
 **
 **/
Announcement
ANNOUNCEMENT::to_reply(Announcement const& announcement)
{
  DEBUG_CALLING(INFO_ANNOUNCEMENT && INFO_VALUE,
		"ANNOUNCEMENT::to_reply(announcement)");

  using namespace ANNOUNCEMENT;

  Announcement a = NOANNOUNCEMENT;

  switch(announcement) {
  case NOANNOUNCEMENT:
    DEBUG_ASSERTION(false,
		    "ANNOUNCEMENT::to_reply(announcement):\n"
		    "  announcement '" << ::name(announcement) << "' not valid.");
    break;
  case NO120:
    a = NO120_REPLY;
    break;
  case NO90:
    a = NO90_REPLY;
    break;
  case NO60:
    a = NO60_REPLY;
    break;
  case NO30:
    a = NO30_REPLY;
    break;
  case NO0:
    a = NO0_REPLY;
    break;
  case REPLY:
  case NO120_REPLY:
  case NO90_REPLY:
  case NO60_REPLY:
  case NO30_REPLY:
  case NO0_REPLY:
    DEBUG_ASSERTION(false,
		    "ANNOUNCEMENT::to_reply(announcement):\n"
		    "  announcement '" << ::name(announcement) << "' not valid.");
    break;
  } // switch(announcement)

  DEBUG_RETURNING(a,
		  INFO_ANNOUNCEMENT && INFO_VALUE,
		  "ANNOUNCEMENT::to_reply(announcement)");
} // Announcement ANNOUNCEMENT::to_reply(Announcement const& announcement)

/**
 **
 ** -> result
 **
 ** @param	announcement	announcement
 **
 ** @return	reply version of 'announcement'
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.4
 **
 **/
Announcement
ANNOUNCEMENT::from_reply(Announcement const& announcement)
{
  DEBUG_CALLING(INFO_ANNOUNCEMENT && INFO_VALUE,
		"ANNOUNCEMENT::from_reply(announcement)");

  using namespace ANNOUNCEMENT;

  Announcement a = NOANNOUNCEMENT;

  switch(announcement) {
  case NOANNOUNCEMENT:
  case NO120:
  case NO90:
  case NO60:
  case NO30:
  case NO0:
  case REPLY:
    DEBUG_ASSERTION(false,
		    "ANNOUNCEMENT::from_reply(announcement):\n"
		    "  announcement '" << ::name(announcement) << "' not valid.");
    break;
  case NO120_REPLY:
    a = NO120;
    break;
  case NO90_REPLY:
    a = NO90;
    break;
  case NO60_REPLY:
    a = NO60;
    break;
  case NO30_REPLY:
    a = NO30;
    break;
  case NO0_REPLY:
    a = NO0;
    break;
  } // switch(announcement)

  DEBUG_RETURNING(a,
		  INFO_ANNOUNCEMENT && INFO_VALUE,
		  "ANNOUNCEMENT::from_reply(announcement)");
} // Announcement ANNOUNCEMENT::from_reply(Announcement const& announcement)

/**
 **
 ** -> result
 **
 ** @param	name	name of the announcemnet
 **
 ** @return	announcement 'name'
 **
 ** @author	Diether Knof
 **
 ** @version	0.5.4
 **
 **/
Announcement
ANNOUNCEMENT::from_name(string const& name)
{
  DEBUG_CALLING(INFO_ANNOUNCEMENT && INFO_INIT,
		"ANNOUNCEMENT::from_name(string)");

  if (name == ::name(ANNOUNCEMENT::NOANNOUNCEMENT))
    DEBUG_RETURNING(ANNOUNCEMENT::NOANNOUNCEMENT,
		    INFO_ANNOUNCEMENT && INFO_INIT,
		    "ANNOUNCEMENT::from_name(string) = no announcement");
  else if (name == ::name(ANNOUNCEMENT::NO120))
    DEBUG_RETURNING(ANNOUNCEMENT::NO120,
		    INFO_ANNOUNCEMENT && INFO_INIT,
		    "ANNOUNCEMENT::from_name(string) = no 120");
  else if (name == ::name(ANNOUNCEMENT::NO90))
    DEBUG_RETURNING(ANNOUNCEMENT::NO90,
		    INFO_ANNOUNCEMENT && INFO_INIT,
		    "ANNOUNCEMENT::from_name(string) = no 90");
  else if (name == ::name(ANNOUNCEMENT::NO60))
    DEBUG_RETURNING(ANNOUNCEMENT::NO60,
		    INFO_ANNOUNCEMENT && INFO_INIT,
		    "ANNOUNCEMENT::from_name(string) = no 60");
  else if (name == ::name(ANNOUNCEMENT::NO30))
    DEBUG_RETURNING(ANNOUNCEMENT::NO30,
		    INFO_ANNOUNCEMENT && INFO_INIT,
		    "ANNOUNCEMENT::from_name(string) = no 30");
  else if (name == ::name(ANNOUNCEMENT::NO0))
    DEBUG_RETURNING(ANNOUNCEMENT::NO0,
		    INFO_ANNOUNCEMENT && INFO_INIT,
		    "ANNOUNCEMENT::from_name(string) = no 0");

  DEBUG_RETURNING(ANNOUNCEMENT::NOANNOUNCEMENT,
		  INFO_ANNOUNCEMENT && INFO_INIT,
		  "ANNOUNCEMENT::from_name(string)");
} // Announcement ANNOUNCEMENT::from_name(string const& name)



///////////////////////
// MARRIAGE_SELECTOR //
///////////////////////

/**********************************************************************
 *
 ** string name(MarriageSelector const& marriage_selector)
 *
 ** Parameters:  marriage_selector - the MarriageSelector
 *
 ** Result:  name of the MarriageSelector
 *
 ** Version: 0.4.1
 *
 ** Description: -> result
 *
 **********************************************************************/
string
name(MarriageSelector const& marriage_selector)
{
  DEBUG_CALLING(INFO_MARRIAGE_SELECTOR && INFO_NAME,
		"string name(MarriageSelector const& marriage_selector)");

  using namespace MARRIAGE_SELECTOR;

  string name;

  switch(marriage_selector) {
  case TEAM_SET:
    name = "team set";
    break;
  case FIRST_FOREIGN:
    name = "first foreign";
    break;
  case FIRST_TRUMP:
    name = "first trump";
    break;
  case FIRST_COLOR:
    name = "first color";
    break;
  case FIRST_CLUB:
    name = "first club";
    break;
  case FIRST_SPADE:
    name = "first spade";
    break;
  case FIRST_HEART:
    name = "first heart";
    break;
  } // switch(marriage_selector)

  DEBUG_RETURNING(name,
		  INFO_MARRIAGE_SELECTOR && INFO_NAME,
		  "string name(MarriageSelector const& marriage_selector)");
} // string name(MarriageSelector const& marriage_selector)

/**********************************************************************
 *
 ** ostream& operator<<(ostream& ostr, MarriageSelector const& marriage_selector)
 *
 ** Parameters:  ostr - output stream
 **      marriage_selector - marriage selector
 *
 ** Result:  output streamoutput stream
 *
 ** Version: 0.4.1
 *
 ** Description: output of the marriage selector
 **      
 *
 **********************************************************************/
ostream&
operator<<(ostream& ostr, MarriageSelector const& marriage_selector)
{
  DEBUG_CALLING(INFO_MARRIAGE_SELECTOR && INFO_IO,
		"ostream& operator<<(ostream&, marriage_selector)");

  ostr << name(marriage_selector);

  DEBUG_RETURNING(ostr,
		  INFO_MARRIAGE_SELECTOR && INFO_IO,
		  "ostream& operator<<(ostream&, marriage_selector)");
} // ostream& operator<<(ostr, marriage_selector)

/**
 **
 ** -> result
 **
 ** @param	rotation	rotation
 **
 ** @return	'rotation' clockwise rotated
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.7
 **
 **/
Rotation
ROTATION::clockwise(Rotation const rotation)
{
  switch (rotation) {
  case UP:
    return LEFT;
  case DOWN:
    return RIGHT;
  case RIGHT:
    return UP;
  case LEFT:
    return DOWN;
  } // switch(rotation)

  DEBUG_ASSERTION(false,
		  "ROTATION::conterclockwise(rotation):\n"
		  "  behind 'switch(rotation)'");

  return UP;
} // Rotation ROTATION::clockwise(Rotation const rotation)

/**
 **
 ** -> result
 **
 ** @param	rotation	rotation
 **
 ** @return	'rotation' counterclockwise rotated
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.7
 **
 **/
Rotation
ROTATION::counterclockwise(Rotation const rotation)
{
  switch (rotation) {
  case UP:
    return RIGHT;
  case DOWN:
    return LEFT;
  case RIGHT:
    return DOWN;
  case LEFT:
    return UP;
  } // switch(rotation)

  DEBUG_ASSERTION(false,
		  "ROTATION::conterclockwise(rotation):\n"
		  "  behind 'switch(rotation)'");

  return UP;
} // Rotation ROTATION::counterclockwise(Rotation const rotation)
