/**********************************************************************
 *
 *   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"

#ifdef USE_UI_GTK

#include "ui.h"

#include "gtk_gui.h"
#include "playfield.h"
#include "genscher.h"
#include "genscher.info.h"
#include "table.h"
#include "party_settings.h"
#include "party_points.h"
#include "game_finished.h"
#include "players.h"
#include "bug_report.h"
#include "main_window.h"
#include "card.h"
#include "icon.h"
#include "settings.h"
#include "settings.cards_order.h"
#include "help.h"
#include "license.cardset.h"

#include "../../party/party.h"
#include "../../game/game.h"
#include "../../card/hand.h"

GTK_DOKO::GTK_GUI* gui = NULL;

// extern GTK_DOKO::GTK_GUI* gui;

/*****************************************************************************
 *
 * UI_GTK::UI_GTK()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.6
 *
 * Description:	Construct an UI with the type 'GTK_DOKO'
 *
 ****************************************************************************/
UI_GTK::UI_GTK() :
UI(UI_TYPE::GTK_DOKO)
{
  DEBUG_CALLING(INFO_GTK_UI && GTK_DOKO::INFO_GTK_INIT,
		"UI_GTK::UI_GTK()");

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI && GTK_DOKO::INFO_GTK_INIT,
		  "UI_GTK::UI_GTK()");
} // UI_GTK::UI_GTK()

/*****************************************************************************
 *
 * UI_GTK::~UI_GTK()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.6
 *
 * Description:	Destructor
 *
 ****************************************************************************/
UI_GTK::~UI_GTK()
{
  DEBUG_CALLING(INFO_GTK_UI && GTK_DOKO::INFO_GTK_INIT,
		"UI_GTK::~UI_GTK()");

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI && GTK_DOKO::INFO_GTK_INIT,
		  "UI_GTK::~UI_GTK()");
} // UI_GTK::~UI_GTK()


/*****************************************************************************
 *
 * void UI_GTK::init(int& argc, char**& argv)
 *
 * Parameters:	argc - Number of Arguments
 *		argv Arguments
 *
 * Result:	none
 * 
 * Version:	0.3.6
 *
 * Description:	Initialises the UI with the command line arguments.
 *		GTK removes the arguments it understands from the list.
 *
 ****************************************************************************/
void
UI_GTK::init(int& argc, char**& argv)
{
  DEBUG_CALLING(INFO_GTK_UI && GTK_DOKO::INFO_GTK_INIT,
		"UI_GTK::init(int argc, char** argv)");

  // create the gui
  gui = new GTK_DOKO::GTK_GUI(argc, argv);
  // init the gui
  gui->init();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI && GTK_DOKO::INFO_GTK_INIT,
		  "UI_GTK::init(int argc, char** argv)");
} // UI_GTK::init(argc, argv)


/**
 **
 ** updates the UI
 **
 ** @param	-
 **
 ** @return	-
 **
 ** @version	0.4.5
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::update()
{
  DEBUG_CALLING(INFO_GTK_UI && GTK_DOKO::INFO_GTK_UPDATE,
		"UI_GTK::update()");

  gui->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI && GTK_DOKO::INFO_GTK_UPDATE,
		  "UI_GTK::update()");
} // void UI_GTK::update()

/**
 **
 ** sleeps the given time
 ** (in miliseconds, UINT_MAX for infinity)
 **
 ** @param	slee_usec	time to sleep
 **
 ** @return	-
 **
 ** @version	0.4.3
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::sleep(unsigned const sleep_usec)
{
  DEBUG_CALLING(INFO_GTK_UI && GTK_DOKO::INFO_GTK_UPDATE,
		"UI_GTK::sleep(usec)");

  gui->sleep(sleep_usec);

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI && GTK_DOKO::INFO_GTK_UPDATE,
		  "UI_GTK::sleep(usec)");
} // void UI_GTK::sleep(unsigned const sleep_usec)

/*****************************************************************************
 *
 * void UI_GTK::language_update()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.6
 *
 * Description:	All language elements of the UI should be updated
 *
 ****************************************************************************/
void
UI_GTK::language_update()
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::language_update()");

  gui->language_update();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::language_update()");
} // void UI_GTK::language_update()


/*****************************************************************************
 *
 * void UI_GTK::party_open()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.7
 *
 * Description:	call the function of 'gui'
 *
 ****************************************************************************/
void
UI_GTK::party_open()
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::party_open()");

  gui->party_open();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::party_open()");
} // void UI_GTK::party_open()

/*****************************************************************************
 *
 * void UI_GTK::party_get_settings()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.6
 *
 * Description:	Gets and sets the settings of the party:
 *		Names of the players,
 *		rules,
 *		starting seed,
 *		startplayer
 *
 ****************************************************************************/
void
UI_GTK::party_get_settings()
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::party_get_settings()");

  gui->playfield().table().names().set();
  if (!FAST_PLAY)
    gui->playfield().party_settings().get();

  // ***DK not so nice
  gui->playfield().table().party_points().names_update();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::party_get_settings()");
} // void UI_GTK::party_get_Settings()

/*****************************************************************************
 *
 * void UI_GTK::party_start()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.7
 *
 * Description:	call the function of 'gui'
 *
 ****************************************************************************/
void
UI_GTK::party_start()
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::party_start()");

  gui->party_start();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::party_start()");
} // void UI_GTK::party_start()

/*****************************************************************************
 *
 * void UI_GTK::party_finish()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.7
 *
 * Description:	call the function of 'gui'
 *
 ****************************************************************************/
void
UI_GTK::party_finish()
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::party_finish()");

  gui->party_finish();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::party_finish()");
} // void UI_GTK::party_end()

/*****************************************************************************
 *
 * void UI_GTK::party_close()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.6
 *
 * Description:	call the function of 'gui'
 *
 ****************************************************************************/
void
UI_GTK::party_close()
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::party_close()");

  gui->party_close();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::party_close()");
} // void UI_GTK::party_close()

/*****************************************************************************
 *
 * void UI_GTK::game_open()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.6
 *
 * Description:	open the game
 *
 ****************************************************************************/
void
UI_GTK::game_open()
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::game_open()");

  gui->game_open();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::game_open()");
} // void UI_GTK::game_open()


/*****************************************************************************
 *
 * Reservation UI_GTK::reservation_get(Player const& player)
 *
 * Parameters:	player - player, whose reservation should be get
 *
 * Result:	reservation of the player
 * 
 * Version:	0.3.6
 *
 * Description:	Gets the reservation of the given player:
 *		pops up a window.
 *		Also this is the first time, the hands can (should) be shown
 *
 ****************************************************************************/
Reservation
UI_GTK::reservation_get(Player const& player)
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::reservation_get(player)");

  gui->playfield().table().draw_all();

  gui->bug_report().language_update();
  Reservation const& reservation = (FAST_PLAY
				    ? Reservation()
				    : gui->reservation_get(player));

  this->update();

  DEBUG_RETURNING(reservation,
		  INFO_GTK_UI,
		  "UI_GTK::reservation_get(player)");
} // Reservation UI_GTK::reservation_get(player)


/*****************************************************************************
 *
 * void UI_GTK::game_start()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.6
 *
 * Description:	The game is started.
 *		The announcements of the other players are shown.
 *
 ****************************************************************************/
void
UI_GTK::game_start()
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::game_start()");

  gui->playfield().table().draw_all();

  gui->gametype_show();
  if ((::game_status == GAMESTATUS::GAME_SHOW_GAMETYPE)
  || (::game_status == GAMESTATUS::GAME_REDISTRIBUTE))
    gui->game_start();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::game_start()");
} // void UI_GTK::game_start()


/*****************************************************************************
 *
 * void UI_GTK::game_finish()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.6
 *
 * Description:	The game is ended.
 *		The winner and the points of the game are shown.
 *
 ****************************************************************************/
void
UI_GTK::game_finish()
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::game_finish()");

  gui->game_finish();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::game_finish()");
} // void UI_GTK::game_finish()

/*****************************************************************************
 *
 * void UI_GTK::game_close()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.6
 *
 * Description:	Removes the entry 'rules' of the menu.
 *
 ****************************************************************************/
void
UI_GTK::game_close()
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::game_close()");

  gui->game_close();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::game_close()");
} // void UI_GTK::game_close()


/**
 **
 ** a new trick is opened
 **
 ** @param	-
 **
 ** @return	-
 **
 ** @author	Diether Knof
 **
 ** @version	0.5.4
 **
 **/
void
UI_GTK::trick_open()
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::trick_open()");

  gui->playfield().table().trick().draw(::party.game().trick_current());
  gui->main_window().menu().trick_open();
  gui->playfield().party_settings().players->sensitivity_update();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::trick_open()");
} // void UI_GTK::trick_open()

/**
 **
 ** get a card from the player
 **
 ** @param	player	player who has to play a card
 **
 ** @return	selected card
 **
 ** @author	Diether Knof
 **
 ** @version	0.5.4
 **
 **/
Card
UI_GTK::card_get(Player const& player)
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::card_get(player)");

  // return the first valid card
  Card card = (FAST_PLAY
	       ? (player.hand().validcards(player.game().trick_current())).card(0)
	       : gui->card_get(player));

  DEBUG_RETURNING(card,
		  INFO_GTK_UI,
		  "UI_GTK::card_get(player)");
} // Card UI_GTK::card_get(Player const& player)

/**
 **
 ** 'player' has played 'card'
 **
 ** @param	player	player who has played 'card'
 ** @param	card	card that is played
 **
 ** @return	-
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.1
 **
 **/
void
UI_GTK::card_played(Card const& card, Player const& player)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::played_card(player, card)");

  this->update();

  gui->playfield().table().hand(player).play_card(card);
  gui->playfield().table().draw_all();
#if 0
  gui->playfield().table().trick().draw(party.game().trick_current());
  gui->playfield().table().hand(player).draw();
  gui->playfield().table().name(player).draw();
  gui->playfield().table().name(player.game().player_current()).draw();
#endif
  gui->playfield().party_settings().players->sensitivity_update();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::played_card(player, card)");
} // void UI_GTK::card_player(Card const& card, Player const& player)

/**
 **
 ** the announcement 'announcement' has been made by player 'player'
 **
 ** @param	announcement	the announcement
 ** @param	player		the player, who has made the announcement
 **
 ** @return	-
 **
 ** @version	0.5
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::announcement_made(Announcement const& announcement,
			  Player const& player)
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::announcement_made(announcement, player)");

  gui->main_window().menu().announcement_update(player);
  gui->playfield().table().draw_all();
  this->teaminfo_update(player);

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::announcement_made(card, player)");
} // void UI_GTK::announcement_made(Announcement const& announcement, Player const& player)

/**
 **
 ** the player has swines
 **
 ** @param	player		the player with the swines
 **
 ** @return	-
 **
 ** @version	0.5.4
 **
 ** @author	Diether Knof
 **
 ** @todo	all
 **
 **/
void
UI_GTK::swines_announced(Player const& player)
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::swines_announced(player)");

  gui->playfield().table().icongroup(player).swines_draw();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::swines_announced(player)");
} // void UI_GTK::swines_announced(Player const& player)

/**
 **
 ** the player has hyperswines
 **
 ** @param	player		the player with the swines
 **
 ** @return	-
 **
 ** @version	0.5.4
 **
 ** @author	Diether Knof
 **
 ** @todo	all
 **
 **/
void
UI_GTK::hyperswines_announced(Player const& player)
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::hyperswines_announced(player)");

  gui->playfield().table().icongroup(player).swines_draw();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::hyperswines_announced(player)");
} // void UI_GTK::hyperswines_announced(Player const& player)


/**
 **
 ** 'player' shifts 'cardno' cards
 **
 ** @param	player	the player who shifts the cards
 ** @param	cardno	the number of cards that are shifted
 **
 ** @return	-
 **
 ** @version	0.5
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::poverty_shift(Player const& player, unsigned const cardno)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::poverty_shift(player, cardno)");

  DEBUG_RETURNING(gui->playfield().table().poverty().shift(player, cardno),
		  INFO_GTK_UI,
		  "UI_GTK::poverty_shift(player, cardno)");
} // void UI_GTK::poverty_shift(Player const& player, unsigned const cardno)

/**
 **
 ** ask 'player' whether to accept the poverty
 **
 ** @param	player	the player who is asked
 ** @param	cardno	the number of cards that are shifted
 **
 ** @return	-
 **
 ** @version	0.5
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::poverty_ask(Player const& player, unsigned const cardno)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::poverty_ask(player, cardno)");

  DEBUG_RETURNING(gui->playfield().table().poverty().ask(player, cardno),
		  INFO_GTK_UI,
		  "UI_GTK::poverty_ask(player, cardno)");
} // void UI_GTK::poverty_ask(Player const& player, unsigned const cardno)

/**
 **
 ** 'player' denied to take the shifted cards
 **
 ** @param	player	the player who has denied to take the cards
 **
 ** @return	-
 **
 ** @version	0.5
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::poverty_take_denied(Player const& player)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::poverty_take_denied(player)");

  DEBUG_RETURNING(gui->playfield().table().poverty().take_denied(player),
		  INFO_GTK_UI,
		  "UI_GTK::poverty_take_denied(player)");
} // void UI_GTK::poverty_take_denied(Player const& player)

/**
 **
 ** all players have denied to take the cards
 **
 ** @param	-
 **
 ** @return	-
 **
 ** @version	0.5
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::poverty_take_denied_by_all()
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::poverty_take_denied_by_all()");

  DEBUG_RETURNING(gui->playfield().table().poverty().take_denied_by_all(),
		  INFO_GTK_UI,
		  "UI_GTK::poverty_take_denied_by_all()");
} // void UI_GTK::poverty_take_denied_by_all()

/**
 **
 ** 'player' accepts to take the shifted cards
 ** and returns 'cardno' cards with 'trumpno' trumps
 **
 ** @param	player	the player who has denied to take the cards
 ** @param	cardno	number of cards that are given back
 ** @param	trumpno	number of trumps of the cards
 **
 ** @return	-
 **
 ** @version	0.5
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::poverty_take_accepted(Player const& player,
			      unsigned const cardno, unsigned const trumpno)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::poverty_take_accepted(player, cardno, trumpno)");

  DEBUG_RETURNING(gui->playfield().table().poverty().take_accepted(player,
								   cardno,
								   trumpno),
		  INFO_GTK_UI,
		  "UI_GTK::poverty_take_accepted(player, cardno, trumpno)");
} // void UI_GTK::poverty_take_accepted(Player const& player, unsigned const cardno, unsigned const trumpno)

/**
 **
 ** returns which cards the player shifts
 **
 ** @param	player	the player who shifts the cards
 **
 ** @return	the cards that are to be shifted
 **
 ** @version	0.5
 **
 ** @author	Diether Knof
 **
 **/
Hand
UI_GTK::poverty_shift(Player& player)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::poverty_shift(player)");

  DEBUG_RETURNING(gui->playfield().table().poverty().shift(player),
		  INFO_GTK_UI,
		  "UI_GTK::poverty_shift(player)");
} // void UI_GTK::poverty_shift(Player& player)

/**
 **
 ** returns whether 'player' accepts the shifted cards
 **
 ** @param	player	the player who shifts the cards
 ** @param	cardno	the number of shifted cards
 **
 ** @return	whether to accept the cards
 **
 ** @version	0.5
 **
 ** @author	Diether Knof
 **
 **/
bool
UI_GTK::poverty_take_accept(Player& player, unsigned const cardno)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::poverty_take_accept(player, cardno)");

  DEBUG_RETURNING(gui->playfield().table().poverty().take_accept(player,
								 cardno),
		  INFO_GTK_UI,
		  "UI_GTK::poverty_take_accept(player, cardno)");
} // void UI_GTK::poverty_take_accept(Player& player, unsigned const cardno)

/**
 **
 ** changes the cards from the poverty-player
 **
 ** @param	player	the player who has accepted the cards
 ** @param	cards	the cards that are given to the player
 **
 ** @return	the cards that are returned to the poverty-player
 **
 ** @version	0.5
 **
 ** @author	Diether Knof
 **
 **/
Hand
UI_GTK::poverty_cards_change(Player& player, Hand const& cards)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::poverty_cards_change(player, cards)");

  DEBUG_RETURNING(gui->playfield().table().poverty().cards_change(player,
								  cards),
		  INFO_GTK_UI,
		  "UI_GTK::poverty_cards_change(player, cards)");
} // void UI_GTK::poverty_cards_change(Player& player, Hand const& cards)

/**
 **
 ** the poverty player 'player' gets 'cards'
 **
 ** @param	player	the player gets the cards
 ** @param	cards	the cards that are given to the player
 **
 ** @return	-
 **
 ** @version	0.5
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::poverty_cards_get_back(Player& player, Hand const& cards)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::poverty_cards_get_back(player, cards)");

  gui->playfield().table().poverty().cards_get_back(player, cards);

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::poverty_cards_get_back(player, cards)");
} // void UI_GTK::poverty_cards_get_back(Player& player, Hand const& cards)

/**
 **
 ** genscher: -> result
 **
 ** @param	-
 **
 ** @return	pointer to the new teammate,
 **		NULL if the genscher is not to be announced
 **
 ** @author	Diether Knof
 **
 ** @version	0.5.4
 **
 **/
Player const*
UI_GTK::genscher_partner()
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::genscher_partner()");

  DEBUG_RETURNING(gui->playfield().genscher().select_partner(),
		  INFO_GTK_UI,
		  "UI_GTK::genscher_partner()");
} // Player const* UI_GTK::genscher_partner()

/**
 **
 ** genscher: Information of the new team
 **
 ** @param	player	genscher player
 ** @param	partner	partner of the gensher player
 **
 ** @return	-
 **
 ** @author	Diether Knof
 **
 ** @version	0.6.1
 **
 **/
void
UI_GTK::genscher(Player const& player,
		 Player const& partner)
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::genscher(player, partner)");

  if (!FAST_PLAY)
    gui->playfield().genscher_info().genscher(player, partner);

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::genscher(player, partner)");
} // void UI_GTK::genscher(Player const& player, Player const& partner)


/**
 **
 ** the trick is full
 **
 ** @param	trick	the full trick
 **
 ** @return	-
 **
 ** @author	Diether Knof
 **
 ** @version	0.5.4
 **
 **/
void
UI_GTK::trick_full(::Trick const& trick)
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::trick_full(trick)");

  // update the valid announcements and show the full trick window

  gui->main_window().menu().trick_full();
  gui->playfield().table().full_trick().show();
  gui->playfield().table().name(trick.winnerplayer()).draw();
  gui->playfield().party_settings().players->sensitivity_update();
  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::trick_full(trick)");
} // void UI_GTK::trick_full(trick)

/**
 **
 ** move the trick in the pile
 **
 ** @param	trick	the trick
 **
 ** @return	-
 **
 ** @author	Diether Knof
 **
 ** @version	0.5.4
 **
 **/
void
UI_GTK::trick_move_in_pile(::Trick const& trick)
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::trick_move_in_pile(trick)");

  gui->playfield().party_settings().players->sensitivity_update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::trick_move_in_pile(trick)");
} // void UI_GTK::trick_move_in_pile(trick)

/*****************************************************************************
 *
 * void UI_GTK::trick_close()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.4
 *
 * Description:	The trick is closed
 *
 ****************************************************************************/
void
UI_GTK::trick_close()
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::trick_close()");

  gui->playfield().table().trick().draw(Trick(::party.game().trick_current()
					      .winnerplayer()));
  gui->playfield().table().trickpile(::party.game().trick_current().winnerplayer()
				    ).draw();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::trick_close()");
} // void UI_GTK::trick_close()

/*****************************************************************************
 *
 * void UI_GTK::redraw_all()
 *
 * Parameters:	none
 *
 * Result:	none
 * 
 * Version:	0.3.6
 *
 * Description:	redraw all (of the playfield)
 *
 ****************************************************************************/
void
UI_GTK::redraw_all()
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::redraw_all()");

  gui->playfield().table().draw_all();
  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::redraw_all()");
} // void UI_GTK::redraw_all()

/**
 **
 ** the player has changed
 **
 ** @param	player	the player
 **
 ** @return	-
 ** 
 ** @version	0.5.3
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::player_update(Player const& player)
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::player_update(player)");

  gui->playfield().player_update(player);
  this->name_update(player);

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::player_update(player)");
} // void UI_GTK::player_update(player)

/**
 **
 ** update the name of 'player'
 **
 ** @param	player	the player
 **
 ** @return	-
 ** 
 ** @version	0.5.3
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::name_update(Player const& player)
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::name_update(player)");

  gui->main_window().menu().name_update(player);
  gui->playfield().name_update(player);

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::name_update(player)");
} // void UI_GTK::name_update(player)

/**
 **
 ** update the hand of 'player'
 **
 ** @param	player	the player
 **
 ** @return	-
 ** 
 ** @version	0.5.3
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::hand_update(Player const& player)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::hand_update(player)");

  gui->playfield().table().hand(player).draw();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::hand_update(player)");
} // void UI_GTK::hand_update(player)

/**
 **
 ** update the trick
 **
 ** @param	-
 **
 ** @return	-
 ** 
 ** @version	0.5.3
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::trick_update()
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::trick_update()");

  // draw all, because, if the rotation has changed, the new trick
  // does not overwrite all of the old trick
  if (game_status & GAMESTATUS::GAME)
    gui->playfield().table().draw_all();
  //    gui->playfield().table().trick().draw(party.game().trick_current());

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::trick_update()");
} // void UI_GTK::trick_update()

/**
 **
 ** update the trickpile of 'player'
 **
 ** @param	player	the player
 **
 ** @return	-
 ** 
 ** @version	0.5.3
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::trick_pile_update(Player const& player)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::trick_pile_update(player)");

  // *** gui->playfield().table().trick_pile(player).draw();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::trick_pile_update(player)");
} // void UI_GTK::trick_pile_udpate(player)


/**
 **
 ** update the teaminfo of 'player'
 **
 ** @param	player	the player
 **
 ** @return	-
 ** 
 ** @version	0.5.3
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::teaminfo_update(Player const& player)
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::teaminfo_update(player)");

  gui->playfield().table().icongroup(player).team_draw();
  gui->main_window().menu().announcements_language_update();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::teaminfo_update(player)");
} // void UI_GTK::teaminfo_udpate(player)

/**
 **
 ** update the gametype
 **
 ** @param	-
 **
 ** @return	-
 ** 
 ** @version	0.5.3
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::gametype_update()
{ 
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::gametype_update()");

  // the whole table has to be drawn, because the size of the icons
  // can change
  gui->playfield().table().draw_all();
  // perhaps a player has changed from 'contra' to 're'
  gui->main_window().menu().language_update();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::gametype_update()");
} // void UI_GTK::gametype_udpate()

/**
 **
 ** the rule 'type' has changed
 **
 ** @param	type		the type that has changed
 ** @param	old_value	old value
 **
 ** @return	-
 **
 ** @version	0.5.3
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::rule_update(int const type, void const* const old_value)
{
  DEBUG_CALLING(INFO_GTK_UI && GTK_DOKO::INFO_GTK_UPDATE,
		"UI_GTK::rule_update(type = " << type << ", old_value)");

  switch(type) {
  case Rule::SHOW_ALL_HANDS:
    if (game_status & GAMESTATUS::GAME)
      for (vector<Player*>::const_iterator player = ::party.game().player_begin();
	   player != ::party.game().player_end();
	   player++)
	ui->hand_update(**player);
    break;
  case Rule::SHOW_TRICKPILES_POINTS:
    gui->playfield().table().draw_all();
    break;
  default:
    // nothing to do
    break;
  } // switch(type)

  if (gui->playfield().party_settings().rules != NULL)
    gui->playfield().party_settings().rules->update(type);

  gui->settings().sensitivity_update();

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI && GTK_DOKO::INFO_GTK_UPDATE,
		  "UI_GTK::rule_update(type, old_value)");
} // void UI_GTK::rule_update(int const type, void const* const old_value)

/**
 **
 ** the setting 'type' has changed
 **
 ** @param	type		the type that has changed
 ** @param	old_value	old value
 **
 ** @return	-
 **
 ** @version	0.5.3
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::setting_update(int const type, void const* const old_value)
{
  DEBUG_CALLING(INFO_GTK_UI && GTK_DOKO::INFO_GTK_UPDATE,
		"UI_GTK::setting_update(type, old_value)");

  switch(type) {
  case Setting::SHOW_BUG_REPORT_BUTTON_IN_GAME_FINISHED_WINDOW:
    gui->playfield().game_finished().update();
    break;
  case Setting::SAVE_BUG_REPORTS_ON_DESKTOP:
    gui->bug_report().save_on_desktop_update();
    break;
  case Setting::NAME:
    for (unsigned p = 0; p < ::party.playerno(); p++)
      if (::party.player(p).type() && Player::HUMAN)
	this->name_update(::party.player(p));

    break;

  case Setting::SHOW_ALL_HANDS:
    gui->main_window().menu().settings_show_all_hands_button_update();
    if (game_status & GAMESTATUS::GAME)
      for (vector<Player*>::const_iterator player = ::party.game().player_begin();
	   player != ::party.game().player_end();
	   player++)
	ui->hand_update(**player);
    if (::game_status == GAMESTATUS::GAME_POVERTY_SHIFT)
      gui->playfield().table().poverty().draw(::party.game().player_current());
    break;

  case Setting::ROTATE_TRICK_CARDS:
    gui->playfield().table().draw_all();

#ifdef OUTDATED
  case Setting::ROTATE_ICONS:
    gui->playfield().table().draw_all();
#endif

  case Setting::LANGUAGE:
    gui->language_update();
    break;

  case Setting::CARDSET:
    gui->license_cardset().license_update();
    {
#ifdef POSTPHONED
      gdk_window_set_cursor(this->playfield().table().widget()->window,
			    gdk_cursor_new(GDK_WATCH));
#endif

      bool changed = false;
      changed |= gui->cards().back_load();
      changed |= gui->cards().load();
      changed |= gui->icons().load();

      if (changed) {
	gui->playfield().cards_update();
	gui->settings().cards_order->cards_update();
#ifdef POSTPHONED
	gui->cursor_reset();
#endif
      } // if (changed)
    }
    break;

  case Setting::CARDS_BACK:
    if (gui->cards().back_load()) {
      gui->playfield().cards_update();
      gui->settings().cards_order->cards_update();
    }
    break;

  case Setting::BACKGROUND:
    if (gui->playfield().table().background_load())
      gui->playfield().table().draw_all();
    break;

  case Setting::NAME_FONT:
    gui->playfield().table().names().font_load();
    gui->playfield().table().draw_all();
    break;
  case Setting::NAME_FONT_COLOR:
    gui->playfield().table().names().font_color_set();
    gui->playfield().table().draw_all();
    break;
  case Setting::NAME_ACTIVE_FONT_COLOR:
    gui->playfield().table().names().active_font_color_set();
    gui->playfield().table().draw_all();
    break;

  case Setting::SHOW_TRICKPILES_POINTS:
    gui->playfield().table().trickpiles().draw();
    break;

  case Setting::SHOW_KNOWN_TEAMS_IN_GAME:
  case Setting::SHOW_SOLOPLAYER_IN_GAME:
    gui->playfield().table().draw_all();
    break;

  case Setting::TRICKPILE_POINTS_FONT:
    gui->playfield().table().trickpiles().font_load();
    gui->playfield().table().trickpiles().draw();
    break;
  case Setting::TRICKPILE_POINTS_FONT_COLOR:
    gui->playfield().table().trickpiles().font_color_set();
    gui->playfield().table().trickpiles().draw();
    break;

  case Setting::POVERTY_SHIFT_ARROW_COLOR:
    gui->playfield().table().poverty().arrow_color_set();
    // *** it should be sufficient to repaint the arrow
    gui->playfield().table().draw_all();
    break;

  case Setting::CARDS_ORDER:
    if (game_status & GAMESTATUS::GAME)
      for (vector<Player*>::const_iterator player = ::party.game().player_begin();
	   player != ::party.game().player_end();
	   player++)
	ui->hand_update(**player);
    gui->settings().cards_order->draw_all();
    break;

#ifdef OUTDATED
  case Setting::HELP_ICONS_STYLE:
    gui->help().icons_update();
    break;
#endif

  default:
    // nothing to do
    break;
  } // switch(type)

  if (::game_status > GAMESTATUS::PROGRAMSTART)
  gui->settings().update(type);

  this->update();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI && GTK_DOKO::INFO_GTK_UPDATE,
		  "UI_GTK::setting_update(type, old_value)");
} // void UI_GTK::setting_update(int const type, void const* const old_value)


/**
 **
 ** load the page with the help
 **
 ** @param	page	the page to be loaded
 **
 ** @return	-
 **
 ** @version	0.4.4
 **
 ** @author	Diether Knof
 **
 **/
void
UI_GTK::help_load(string const& page)
{
  DEBUG_CALLING(INFO_GTK_UI,
		"UI_GTK::help_load(page)");

  // look, whether the file exists
  string file = (::setting(Setting::HELP_DIRECTORY)
		 + "/" + ::setting(Setting::LANGUAGE)
		 + "/" + page);
  cout << "teste " << file << endl;
  // test, whether the file exists
  // else take the english page
  {
    ifstream istr(file.c_str(), ios::in);
    if (istr.fail())
      file = ::setting(Setting::HELP_DIRECTORY) + "/en/" + page;
    else
      istr.close();
  }

  gui->help().load(file);
  gui->help().show();

  DEBUG_RETURNING(VOID,
		  INFO_GTK_UI,
		  "UI_GTK::help_load(page)");
} // void UI_GTK::help_load(string const& page)

#endif // #ifdef USE_UI_GTK
