/**********************************************************************
 *
 *   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 "card.h"
#include "gtk_gui.h"
#include "splash.h"
#include "playfield.h"
#include "table.h"

#include "../../utils/file.h"
#include "../../misc/setting.h"
#include "../../misc/language.h"
#include "../../basistypes.h"

namespace GTK_DOKO {

  // one background  and 6 * 4 cards to load
  // that makes 1 + 6 * 4 + 1
#define PROGRESS_STEP_CARD (1.0 / (1 + 6 * 4))

#define progress_set_text(text) \
  ( (game_status == GAMESTATUS::PROGRAMSTART) \
    ? this->gui().splash().set_text(text) \
    : (void) 0)
#define progress(progress) \
    ( (game_status == GAMESTATUS::PROGRAMSTART) \
      ? this->gui().splash().progress_add(progress) \
      : (void) 0)

    /*****************************************************************************
     *
     * Cards::Cards(GTK_GUI* gui_a)
     *
     * Parameters:	gui_a - pointer to the gui
     *
     * Result:	none
     * 
     * Version:	0.3.7
     *
     * Description:	Constructor
     *
     ****************************************************************************/
    Cards::Cards(GTK_GUI* gui_a) :
    gui_p(gui_a), // the gui
  card_p(Card::NUMBER_OF_COLORS,
	 vector<vector<Pixmap> >(Card::NUMBER_OF_VALUES,
				 vector<Pixmap>(ROTATION_NUMBER))),
  back_p(ROTATION_NUMBER)
  {
    DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_INIT,
		  "Cards::Cards()");

    DEBUG_RETURNING(VOID,
		    INFO_GTK_CARD && INFO_GTK_INIT,
		    "Cards::Cards()");
  } // Cards::Cards(GTK_GUI* gui_a)

  /*****************************************************************************
   *
   * void Cards::init()
   *
   * Parameters:	none
   *
   * Result:	none
   * 
   * Version:	0.3.6
   *
   * Description:	inits the cards -- loads the cards and the background
   *
   ****************************************************************************/
  void
    Cards::init()
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_INIT,
		    "Cards::init()");

      // loads the pixmaps
      this->back_load();
      this->load();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_CARD && INFO_GTK_INIT,
		      "Cards::init()");
    } // void Cards::init()

  /*****************************************************************************
   *
   * GTK_GUI& Cards::gui()
   *
   * Parameters:	none
   *
   * Result:	the gui
   *
   * Version:	0.3.7
   *
   * Description:	Result
   *
   ****************************************************************************/
  GTK_GUI&
    Cards::gui()
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::gui()");

      DEBUG_ASSERTION((gui_p != NULL),
		      "GTK_GUI& Cards::gui():\n"
		      "  'gui_p' == NULL");

      DEBUG_RETURNING(*gui_p,
		      INFO_GTK_CARD && INFO_GTK_VALUE,
		      "Cards::gui()");
    } // GTK_GUI& Cards::gui()

  /**
   **
   ** loads a new cardset.
   ** If the size of the cards back does not match, it searches a back in the 
   ** new style.
   ** It is *not* testet, whether the size of the new back matches,
   ** because it is in the 'right' directory.
   **
   ** @param	-
   **
   ** @return	whethere new cards were loaded
   ** 
   ** @version	0.4.5
   **
   ** @author	Diether Knof
   **
   **/
  bool
    Cards::load()
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_INIT,
		    "Cards::load()");

      vector<string> directory;

      directory.push_back(::setting(Setting::PRIVATE_DATA_DIRECTORY) + "/"
			  + ::setting(Setting::CARDS_DIRECTORY));
      directory.push_back(::setting(Setting::PUBLIC_DATA_DIRECTORY) + "/"
			  + ::setting(Setting::CARDS_DIRECTORY));
      directory.push_back("./" + ::setting(Setting::CARDS_DIRECTORY));
      if (!this->card(Card::CLUB_QUEEN)) {
	directory.push_back(::setting_default(Setting::PUBLIC_DATA_DIRECTORY) + "/"
			    + ::setting(Setting::CARDS_DIRECTORY));
	directory.push_back(::setting_default(Setting::PUBLIC_DATA_DIRECTORY) + "/"
			    + ::setting_default(Setting::CARDS_DIRECTORY));
      }

      vector<string>::iterator d;
      for (d = directory.begin(); d != directory.end(); d++)
	if (this->load(*d))
	  break;

      if (d == directory.end()) {
	progress(4 * 6);
	if (!this->card(Card::CLUB_QUEEN)) {
	  cerr << "Could not load cards `" << ::setting(Setting::CARDS_DIRECTORY)
	    << "`.\n"
	    << "Exiting."
	    << endl;
	  exit(1);
	}
      } else { // if !(d != directory.end())
#if 0
	// test, whether the card back has the same size as the cards
	if ((this->card(Card::DOLLE).width() != this->back().width())
	    || (this->card(Card::DOLLE).height() != this->back().height())) {
	  if (!::isfile(::setting(Setting::PRIVATE_DATA_DIRECTORY)
			+ ::setting(Setting::CARDSET)
			+ ::setting(Setting::CARDS_BACK)
			+ "."
			+ ::setting(Setting::GRAPHIC_EXTENSION))
	      && !::isfile(::setting(Setting::PUBLIC_DATA_DIRECTORY)
			   + ::setting(Setting::CARDSET)
			   + ::setting(Setting::CARDS_BACK)
			   + "."
			   + ::setting(Setting::GRAPHIC_EXTENSION))) {
	    // search a back in the directory
	    DIR *dir = opendir((::setting(Setting::PRIVATE_DATA_DIRECTORY)
				+ "/"
				+ ::setting(Setting::CARDS_BACK_DIRECTORY)
			       ).c_str());
	    string directory = (::setting(Setting::PRIVATE_DATA_DIRECTORY)
				+ "/"
				+ ::setting(Setting::CARDS_BACK_DIRECTORY));

	    if (dir == NULL) {
	      dir = opendir((::setting(Setting::PUBLIC_DATA_DIRECTORY)
			     + "/"
			     + ::setting(Setting::CARDS_BACK_DIRECTORY)
			    ).c_str());
	      directory = (::setting(Setting::PUBLIC_DATA_DIRECTORY)
			   + "/"
			   + ::setting(Setting::CARDS_BACK_DIRECTORY));

	    } // if (dir == NULL)

	    if (dir != NULL) {
	      struct dirent *entry;

	      // search all entries in the directory
	      while ((entry = readdir(dir)) != NULL) {
		if ((strcmp(entry->d_name, ".") == 0)
		    || (strcmp(entry->d_name, "..") == 0))
		  continue;
		if (::isfile(directory + "/" + entry->d_name)) {
		  string const basename = string(entry->d_name).basename();
		  if ((basename.size()
		       > ::setting(Setting::GRAPHIC_EXTENSION + 1).size())
		      && (string(basename,
				 basename.size()
				 - 1
				 - ::setting(Setting::GRAPHIC_EXTENSION).size(),
				 1
				 + ::setting(Setting::GRAPHIC_EXTENSION).size())
			  == "." + ::setting(Setting::GRAPHIC_EXTENSION))
		     ) {
		    ::setting.set(Setting::CARDS_BACK,
				  string(basename,
					 0,
					 basename.size()
					 - 1
					 - ::setting(Setting::GRAPHIC_EXTENSION).size()));
		    break;
		  } // if (extension is right)
		} // if (isfile(entry->d_name))
	      } // while (entry != NULL) ;
	      closedir(dir);
	    } // if (dir != NULL)
	  } // if (file of the back of the cards exists)
	} // if (back has not the same size as the cards)
#endif
      } // if !(d != directory.end())

      DEBUG_RETURNING((d != directory.end()),
		      INFO_GTK_CARD && INFO_GTK_INIT,
		      "Cards::load()");
    } // bool Cards::load()

  /**
   **
   ** loads the cards from the given directory
   **
   ** @param	directory	the directory with the cards
   **
   ** @return	whether the cards could be loaded and are used
   ** 
   ** @version	0.5.1
   **
   ** @author	Diether Knof
   **
   **/
  bool
    Cards::load(string const directory)
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_INIT,
		    "Cards::load()");

      progress_set_text(language("Loading the cards"));

      // backup the setting
      string const cards_directory = ::setting(Setting::CARDS_DIRECTORY);

      vector<vector<vector<Pixmap> > > cards
	= vector<vector<vector<Pixmap> > >(Card::NUMBER_OF_COLORS,
					   vector<vector<Pixmap> >(Card::NUMBER_OF_VALUES,
								   vector<Pixmap>(ROTATION_NUMBER)));

      // first test, whether the directory exists
      DIR* dir = opendir(directory.c_str());

      if (dir == NULL)
	DEBUG_RETURNING(false,
			INFO_GTK_CARD && INFO_GTK_INIT,
			"Cards::load()");

      closedir(dir);

      // load the cards

      if ( // load all cards
	   //club
	   !card_load_and_rotate(cards[0][0], directory + "/club/nine")
	   || !card_load_and_rotate(cards[0][1], directory + "/club/jack")
	   || !card_load_and_rotate(cards[0][2], directory + "/club/queen")
	   || !card_load_and_rotate(cards[0][3], directory + "/club/king")
	   || !card_load_and_rotate(cards[0][4], directory + "/club/ten")
	   || !card_load_and_rotate(cards[0][5], directory + "/club/ace")
	   // spade
	   || !card_load_and_rotate(cards[1][0], directory + "/spade/nine")
	   || !card_load_and_rotate(cards[1][1], directory + "/spade/jack")
	   || !card_load_and_rotate(cards[1][2], directory + "/spade/queen")
	   || !card_load_and_rotate(cards[1][3], directory + "/spade/king")
	   || !card_load_and_rotate(cards[1][4], directory + "/spade/ten")
	   || !card_load_and_rotate(cards[1][5], directory + "/spade/ace")
	   // heart
	   || !card_load_and_rotate(cards[2][0], directory + "/heart/nine")
	   || !card_load_and_rotate(cards[2][1], directory + "/heart/jack")
	   || !card_load_and_rotate(cards[2][2], directory + "/heart/queen")
	   || !card_load_and_rotate(cards[2][3], directory + "/heart/king")
	   || !card_load_and_rotate(cards[2][4], directory + "/heart/ten")
	   || !card_load_and_rotate(cards[2][5], directory + "/heart/ace")
	   // diamond
	   || !card_load_and_rotate(cards[3][0], directory + "/diamond/nine")
	   || !card_load_and_rotate(cards[3][1], directory + "/diamond/jack")
	   || !card_load_and_rotate(cards[3][2], directory + "/diamond/queen")
	   || !card_load_and_rotate(cards[3][3], directory + "/diamond/king")
	   || !card_load_and_rotate(cards[3][4], directory + "/diamond/ten")
	   || !card_load_and_rotate(cards[3][5], directory + "/diamond/ace")) {
	     DEBUG_RETURNING(false,
			     INFO_GTK_CARD && INFO_GTK_INIT,
			     "Cards::load()");
	   } // if (one card could not be loaded)

      // validate, that the settings did not change
      if (cards_directory != ::setting(Setting::CARDS_DIRECTORY))
	DEBUG_RETURNING(false,
			INFO_GTK_CARD && INFO_GTK_INIT,
			"Cards::load()");

      this->card_p = cards;

      DEBUG_RETURNING(true,
		      INFO_GTK_CARD && INFO_GTK_INIT,
		      "Cards::load()");
    } // bool Cards::load(string const& directory)

  /**
   **
   ** loads the pixmap from the file and rotates it;
   ** tests, whether the size is correct;
   ** updates the progressbar
   **
   ** @param	card		vector, in which the cards are to be written
   ** @param	filename	name of the file with the graphic
   **
   ** @return	whether the cards could be loaded
   ** 
   ** @version	0.5.1
   ** 
   ** @autor	Diether Knof
   **
   **/
  bool
    Cards::card_load_and_rotate(vector<Pixmap>& card, string const& filename)
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_INIT,
		    "Cards::card_load_and_rotate()");

      // load the card
      Pixmap::load_and_rotate(card, filename);
      this->gui().update();

      if (!card[0]) {
	cerr << "Could not load card `" << filename << "`.\n"
	  << endl;
	DEBUG_RETURNING(false,
			INFO_GTK_CARD && INFO_GTK_INIT,
			"Cards::card_load_and_rotate()");
#ifdef TEST
      } else {
	// test the size
	for (unsigned r = 0; r < ROTATION_NUMBER; r++) {
	  if ((card[r].width() != this->back_p[r].width())
	      || (card[r].height() != this->back_p[r].height())) {
	    cerr << "The size of the card " << filename << ", "
	      << "rotation " << r << ", "
	      << "(" << card[r].width()
	      << "x" << card[r].height() << ")"
	      << " does not match with the back of the card "
	      << "(" << this->back_p[r].width()
	      << "x" << this->back_p[r].height() << ")"
	      << "." << endl;
	  }
	}
#endif 
      } // if (!card[0])

      // update the progess
      progress(PROGRESS_STEP_CARD);

      DEBUG_RETURNING(true,
		      INFO_GTK_CARD && INFO_GTK_INIT,
		      "Cards::card_load_and_rotate()");
    } // bool Cards::card_load_and_rotate(card, filename)


  /**
   **
   ** loads a new back for the cards
   **
   ** @param	-
   **
   ** @return	whethere a new back was loaded
   ** 
   ** @version	0.4.5
   **
   ** @author	Diether Knof
   **
   **/
  bool
    Cards::back_load()
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_INIT,
		    "Cards::back_load()");

      vector<string> file;

      file.push_back(::setting(Setting::PRIVATE_DATA_DIRECTORY) + "/"
		     + ::setting(Setting::CARDS_BACK));
      file.push_back(::setting(Setting::PUBLIC_DATA_DIRECTORY) + "/"
		     + ::setting(Setting::CARDS_BACK));
      file.push_back("./" + ::setting(Setting::CARDS_BACK));
      if (!this->back()) {
	file.push_back(::setting_default(Setting::PUBLIC_DATA_DIRECTORY) + "/"
		       + ::setting(Setting::CARDS_BACK));
	file.push_back(::setting_default(Setting::PUBLIC_DATA_DIRECTORY) + "/"
		       + ::setting_default(Setting::CARDS_BACK));
      }

      vector<string>::iterator f;
      for (f = file.begin(); f != file.end(); f++)
	if (this->back_load(*f))
	  break;

      if (!this->back()) {
	cerr << "Error at loading the back '" << ::setting(Setting::CARDS_BACK)
	  << "' of the cards.\n"
	  << "Exiting." << endl;
	exit(1);
      } // if (!this->back(0))

      DEBUG_RETURNING((f != file.end()),
		      INFO_GTK_CARD && INFO_GTK_INIT,
		      "Cards::back_load()");
    } // bool Cards::back_load()

  /*****************************************************************************
   *
   * bool Cards::back_load(string filename)
   *
   * Parameters:	filename - filename of the card back
   *
   * Result:	whether the background could be loaded
   * 
   * Version:	0.4.2
   *
   * Description:	loads the cards back
   *
   ****************************************************************************/
  bool
    Cards::back_load(string filename)
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_INIT,
		    "Cards::back_load(\"" << filename << "\")");

      progress_set_text(language("Loading back of the cards"));

      Pixmap new_back;

      // load the back of the cards (manually)

      // loads the mask
      // use card_back_pm_p, so that if there is an error loading the
      // background-file, this pixmap can be used
      new_back = Pixmap(filename + "." +
			setting(Setting::GRAPHIC_EXTENSION), false);
      if (!new_back) {
	if (back_p[0])
	  DEBUG_RETURNING(false,
			  INFO_GTK_CARD && INFO_GTK_INIT,
			  "Cards::back_load(filename)");

	filename = DK::Utils::File::dirname(filename) + "/default";

	new_back = Pixmap(filename + "." + setting(Setting::GRAPHIC_EXTENSION), false);
	if (!new_back) {
	  DEBUG_RETURNING(false,
			  INFO_GTK_CARD && INFO_GTK_INIT,
			  "Cards::back_load(filename)");
	}
	back_p[0] = new_back;
	Pixmap::load_and_rotate(back_p, filename);
      } else {
	back_p[0] = new_back;
	Pixmap::load_and_rotate(back_p, filename);
      }

      // set the minimum size of the drawing_area

      if (game_status != GAMESTATUS::PROGRAMSTART)
	this->gui().playfield().table().min_size_set();

      // update the progess
      progress(PROGRESS_STEP_CARD);

      DEBUG_RETURNING(true,
		      INFO_GTK_CARD && INFO_GTK_INIT,
		      "Cards::back_load(filename)");
    } // bool Cards::back_load(string directory)

  /*****************************************************************************
   *
   * Pixmap const& Cards::back() const
   *
   * Parameters:	-
   *
   * Result:	the (Pimxap) back of the cards
   * 
   * Version:	0.4.4
   *
   * Description:	-> result
   *
   ****************************************************************************/
  Pixmap const&
    Cards::back() const
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::back()");

      DEBUG_RETURNING(back_p[0],
		      INFO_GTK_CARD && INFO_GTK_VALUE,
		      "Cards::back()");
    } // Pixmap const& Cards::back() const

  /*****************************************************************************
   *
   * Pixmap const& Cards::back(Player const& player) const
   *
   * Parameters:	player - the player
   *
   * Result:	the back of the cards of the given player
   * 
   * Version:	0.4.4
   *
   * Description:	result
   *
   ****************************************************************************/
  Pixmap const&
    Cards::back(Player const& player) const
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::back(player)");

      DEBUG_ASSERTION((player.no() < this->back_p.size()),
		      "Cards::back(player):\n"
		      "  'player.no()' (" << player.no() << "is too great: "
		      "should be less than " << this->back_p.size());

      DEBUG_RETURNING(this->back_p[player.no()],
		      INFO_GTK_CARD && INFO_GTK_VALUE,
		      "Cards::back(player)");
    } // Pixmap const& Cards::back(Player const& player) const

  /*****************************************************************************
   *
   * Pixmap& Cards::back()
   *
   * Parameters:	-
   *
   * Result:	the (Pimxap) back of the cards
   * 
   * Version:	0.4.4
   *
   * Description:	-> result
   *
   ****************************************************************************/
  Pixmap&
    Cards::back()
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::back()");

      DEBUG_RETURNING(back_p[0],
		      INFO_GTK_CARD && INFO_GTK_VALUE,
		      "Cards::back()");
    } // Pixmap& Cards::back()


  /*****************************************************************************
   *
   * Pixmap& Cards::back(Player const& player)
   *
   * Parameters:	player - the player
   *
   * Result:	the back of the cards of the given player
   * 
   * Version:	0.4.4
   *
   * Description:	result
   *
   ****************************************************************************/
  Pixmap&
    Cards::back(Player const& player)
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::back(player)");

      DEBUG_ASSERTION((player.no() < this->back_p.size()),
		      "Cards::back(player):\n"
		      "  'player.no()' (" << player.no() << "is too great: "
		      "should be less than " << this->back_p.size());

      DEBUG_RETURNING(this->back_p[player.no()],
		      INFO_GTK_CARD && INFO_GTK_VALUE,
		      "Cards::back(player)");
    } // Pixmap& Cards::back(Player const& player)

  /*****************************************************************************
   *
   * Pixmap const& Cards::card(Card const& card_a) const
   *
   * Parameters:	card   - the card
   *
   * Result:	the (Pixmap) card
   * 
   * Version:	0.3.6
   *
   * Description:	result
   *
   ****************************************************************************/
  Pixmap const&
    Cards::card(Card const& card) const
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::card()");

      // Number of the color and value of the card
      int color_i = -1, value_i = -1;

      switch (card.color()) {
      case Card::CLUB:
	color_i = 0;
	break;
      case Card::SPADE:
	color_i = 1;
	break;
      case Card::HEART:
	color_i = 2;
	break;
      case Card::DIAMOND:
	color_i = 3;
	break;
      case Card::TRUMP:
      case Card::NOCARDCOLOR:
	color_i = -1;
	break;
      } // switch(color)

      switch(card.value()){
      case Card::NINE:
	value_i = 0;
	break;
      case Card::JACK:
	value_i = 1;
	break;
      case Card::QUEEN:
	value_i = 2;
	break;
      case Card::KING:
	value_i = 3;
	break;
      case Card::TEN:
	value_i = 4;
	break;
      case Card::ACE:
	value_i = 5;
	break;
      case Card::NOCARDVALUE:
	value_i = -1;
	break;
      } // switch(value)


      if ((color_i == -1) || (value_i == -1)) // show the back of the card
	DEBUG_RETURNING(this->back_p[0],
			INFO_GTK_CARD && INFO_GTK_VALUE,
			"Cards::card()");
      else
	DEBUG_RETURNING(this->card_p[color_i][value_i][0],
			INFO_GTK_CARD && INFO_GTK_VALUE,
			"Cards::card()");
    } // Pixmap& Cards::card(card_a, playerno)

  /*****************************************************************************
   *
   * Pixmap& Cards::card(Card const& card, Player const& player)
   *
   * Parameters:	card	- the card
   *		player	- the pllayer
   *
   * Result:	the (Pixmap) card of the given player
   * 
   * Version:	0.4.4
   *
   * Description:	result
   *
   ****************************************************************************/
  Pixmap&
    Cards::card(Card const& card, Player const& player)
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::card(card, player)");

      // Number of the color and value of the card
      int color_i = -1, value_i = -1;

      switch (card.color()) {
      case Card::CLUB:
	color_i = 0;
	break;
      case Card::SPADE:
	color_i = 1;
	break;
      case Card::HEART:
	color_i = 2;
	break;
      case Card::DIAMOND:
	color_i = 3;
	break;
      case Card::TRUMP:
      case Card::NOCARDCOLOR:
	color_i = -1;
	break;
      } // switch(color)

      switch(card.value()){
      case Card::NINE:
	value_i = 0;
	break;
      case Card::JACK:
	value_i = 1;
	break;
      case Card::QUEEN:
	value_i = 2;
	break;
      case Card::KING:
	value_i = 3;
	break;
      case Card::TEN:
	value_i = 4;
	break;
      case Card::ACE:
	value_i = 5;
	break;
      case Card::NOCARDVALUE:
	value_i = -1;
	break;
      } // switch(value)


      if ((color_i == -1) || (value_i == -1)) // show the back of the card
	DEBUG_RETURNING(back_p[player.no()],
			INFO_GTK_CARD && INFO_GTK_VALUE,
			"Cards::card(card, player)");
      else
	DEBUG_RETURNING(card_p[color_i][value_i][player.no()],
			INFO_GTK_CARD && INFO_GTK_VALUE,
			"Cards::card(card, player)");
    } // Pixmap& Cards::card(card, player)

  /*****************************************************************************
   *
   * Pixmap& Cards::card(Card const& card)
   *
   * Parameters:	card_a   - the card
   *
   * Result:	the (Pixmap) card of the given player
   * 
   * Version:	0.4.4
   *
   * Description:	result
   *
   ****************************************************************************/
  Pixmap&
    Cards::card(Card const& card)
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::card()");

      // Number of the color and value of the card
      int color_i = -1, value_i = -1;

      switch (card.color()) {
      case Card::CLUB:
	color_i = 0;
	break;
      case Card::SPADE:
	color_i = 1;
	break;
      case Card::HEART:
	color_i = 2;
	break;
      case Card::DIAMOND:
	color_i = 3;
	break;
      case Card::TRUMP:
      case Card::NOCARDCOLOR:
	color_i = -1;
	break;
      } // switch(color)

      switch(card.value()){
      case Card::NINE:
	value_i = 0;
	break;
      case Card::JACK:
	value_i = 1;
	break;
      case Card::QUEEN:
	value_i = 2;
	break;
      case Card::KING:
	value_i = 3;
	break;
      case Card::TEN:
	value_i = 4;
	break;
      case Card::ACE:
	value_i = 5;
	break;
      case Card::NOCARDVALUE:
	value_i = -1;
	break;
      } // switch(value)


      if ((color_i == -1) || (value_i == -1)) // show the back of the card
	DEBUG_RETURNING(back_p[0],
			INFO_GTK_CARD && INFO_GTK_VALUE,
			"Cards::card()");
      else
	DEBUG_RETURNING(card_p[color_i][value_i][0],
			INFO_GTK_CARD && INFO_GTK_VALUE,
			"Cards::card()");
    } // Pixmap& Cards::card(card)

  /*****************************************************************************
   *
   * unsigned Cards::width() const
   *
   * Parameters:	-
   *
   * Result:	the width of the cards
   * 
   * Version:	0.4.4
   *
   * Description:	result
   *
   ****************************************************************************/
  unsigned
    Cards::width() const
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::width()");

      DEBUG_RETURNING(this->back().width(),
		      INFO_GTK_CARD && INFO_GTK_VALUE,
		      "Cards::width()");
    } // unsigned Cards::width()

  /*****************************************************************************
   *
   * unsigned Cards::width(Player const& player) const
   *
   * Parameters:	player - the player
   *
   * Result:	the width of the cards of the given player
   * 
   * Version:	0.4.4
   *
   * Description:	result
   *
   ****************************************************************************/
  unsigned
    Cards::width(Player const& player) const
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::width(player)");


      DEBUG_RETURNING(this->back(player).width(),
		      INFO_GTK_CARD && INFO_GTK_VALUE,
		      "Cards::width(player)");
    } // unsigned Cards::width(Player const& player)

  /*****************************************************************************
   *
   * unsigned Cards::height() const
   *
   * Parameters:	-
   *
   * Result:	the height of the cards
   * 
   * Version:	0.4.4
   *
   * Description:	result
   *
   ****************************************************************************/
  unsigned
    Cards::height() const
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::height()");

      DEBUG_RETURNING(this->back().height(),
		      INFO_GTK_CARD && INFO_GTK_VALUE,
		      "Cards::height()");
    } // unsigned Cards::height()

  /*****************************************************************************
   *
   * unsigned Cards::height(Player const& player) const
   *
   * Parameters:	player - the player
   *
   * Result:	the height of the cards of the given player
   * 
   * Version:	0.4.4
   *
   * Description:	result
   *
   ****************************************************************************/
  unsigned
    Cards::height(Player const& player) const
    {
      DEBUG_CALLING(INFO_GTK_CARD && INFO_GTK_VALUE,
		    "Cards::height(player)");


      DEBUG_RETURNING(this->back(player).height(),
		      INFO_GTK_CARD && INFO_GTK_VALUE,
		      "Cards::height(player)");
    } // unsigned Cards::height(Player const& player)

} // namespace GTK_DOKO
#endif // #ifdef USE_UI_GTK_DOKO
