/**********************************************************************
 *
 *   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 "playfield.h"
#include "gtk_gui.h"
#include "table.h"
#include "party_settings.h"
#include "reservation.h"
#include "gametype.h"
#include "genscher.h"
#include "genscher.info.h"
#include "game_finished.h"

#include "../../player/player.h"

namespace GTK_DOKO {

  /**
   **
   ** constructor
   **
   ** @param	gui	the gui
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  Playfield::Playfield(GTK_GUI* const gui) :
    gui_(gui), // the gui
  table_(new Table(this)),
  party_settings_(new PartySettings(this)),
  reservation_(new Reservation(this)),
  gametype_(new Gametype(this)),
  genscher_(new Genscher(this)),
  genscher_info_(new GenscherInfo(this)),
  game_finished_(new GameFinished(this))
  {
    DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_INIT,
		  "Playfield::Playfield()");

    this->table().init();
    this->party_settings().init();
    this->reservation().init();
    this->gametype().init();
    this->game_finished().init();

    DEBUG_RETURNING(VOID,
		    INFO_GTK_PLAYFIELD && INFO_GTK_INIT,
		    "Playfield::Playfield()");
  } // Playfield::Playfield(GTK_GUI* gui)

  /**
   **
   ** destructor
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  Playfield::~Playfield()
  {
    DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_INIT,
		  "Playfield::~Playfield()");

    DEBUG_RETURNING(VOID,
		    INFO_GTK_PLAYFIELD && INFO_GTK_INIT,
		    "Playfield::~Playfield()");
  } // Playfield::~Playfield()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the gui
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  GTK_GUI&
    Playfield::gui()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		    "Playfield::gui()");

      DEBUG_ASSERTION((this->gui_ != NULL),
		      "GTK_GUI& Playfield::gui():\n"
		      "  'this->gui_' == NULL");

      DEBUG_RETURNING(*(this->gui_),
		      INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		      "Playfield::gui()");
    } // GTK_GUI& Playfield::gui()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the table
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  Table&
    Playfield::table()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		    "Playfield::table()");

      DEBUG_RETURNING(*(this->table_),
		      INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		      "Playfield::table()");
    } // Table& Playfield::table()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the party settings window
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  PartySettings&
    Playfield::party_settings()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		    "Playfield::party_settings()");

      DEBUG_RETURNING(*(this->party_settings_),
		      INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		      "Playfield::party_settings()");
    } // PartySettings& Playfield::party_settings()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the reservation window
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  Reservation&
    Playfield::reservation()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		    "Playfield::reservation()");

      DEBUG_RETURNING(*(this->reservation_),
		      INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		      "Playfield::reservation()");
    } // Reservation& Playfield::reservation()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the gametype window
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  Gametype&
    Playfield::gametype()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		    "Playfield::gametype()");

      DEBUG_RETURNING(*(this->gametype_),
		      INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		      "Playfield::gametype()");
    } // Gametype& Playfield::gametype()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the genscher window
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  Genscher&
    Playfield::genscher()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		    "Playfield::genscher()");

      DEBUG_RETURNING(*(this->genscher_),
		      INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		      "Playfield::genscher()");
    } // Genscher& Playfield::genscher()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the genscher information window
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  GenscherInfo&
    Playfield::genscher_info()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		    "Playfield::genscher_info()");

      DEBUG_RETURNING(*(this->genscher_info_),
		      INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		      "Playfield::genscher_info()");
    } // GenscherInfo& Playfield::genscher_info()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the game finished window
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  GameFinished&
    Playfield::game_finished()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		    "Playfield::game_finished()");

      DEBUG_RETURNING(*(this->game_finished_),
		      INFO_GTK_PLAYFIELD && INFO_GTK_VALUE,
		      "Playfield::game_finished()");
    } // GameFinished& Playfield::game_finished()

  /**
   **
   ** gameplay: a party is opened
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::party_open()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		    "Playfield::party_open()");

      this->table().party_open();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		      "Playfield::party_open()");
    } // void Playfield::party_open()

  /**
   **
   ** gameplay: a party is started
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::party_start()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		    "Playfield::party_start()");

      this->table().party_start();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		      "Playfield::party_start()");
    } // void Playfield::party_start()

  /**
   **
   ** gameplay: a game is opened
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::game_open()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		    "Playfield::game_open()");

      this->table().game_open();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		      "Playfield::game_open()");
    } // void Playfield::game_open()

  /**
   **
   ** gameplay: a game is started
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::game_start()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		    "Playfield::game_start()");

      this->table().game_start();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		      "Playfield::game_start()");
    } // void Playfield::game_start()

  /**
   **
   ** gameplay: a game is finished
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::game_finish()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		    "Playfield::game_finish()");

      this->table().game_finish();

      if (::game_status == GAMESTATUS::GAME_FINISHED)
	this->game_finished().show();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		      "Playfield::game_finish()");
    } // void Playfield::game_finish()

  /**
   **
   ** gameplay: a game is closed
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::game_close()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		    "Playfield::game_close()");

      this->table().game_close();
      this->genscher_info().close();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		      "Playfield::game_close()");
    } // void Playfield::game_close()

  /**
   **
   ** gameplay: a party is finished
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::party_finish()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		    "Playfield::party_finish()");

      this->table().party_finish();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		      "Playfield::party_finish()");
    } // void Playfield::party_finish()

  /**
   **
   **
   ** gameplay: a party is closed
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::party_close()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		    "Playfield::party_close()");

      this->table().party_close();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_GAMEPLAY,
		      "Playfield::party_close()");
    } // void Playfield::party_close()

  /**
   **
   ** the cards are updated
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::cards_update()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_UPDATE,
		    "Playfield::cards_update()");

      this->table().cards_update();
      this->gametype().icons_update();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_UPDATE,
		      "Playfield::cards_update()");
    } // void Playfield::cards_update()

  /**
   **
   ** the player is to be updated
   **
   ** @param	player	player to update
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::player_update(Player const& player)
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_UPDATE,
		    "Playfield::player_update(player)");

      this->party_settings().player_update(player);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_UPDATE,
		      "Playfield::player_update(player)");
    } // void Playfield::player_update(Player const& player)

  /**
   **
   ** the name of the player is to be updated
   **
   ** @param	player	player to update
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::name_update(Player const& player)
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_UPDATE,
		    "Playfield::name_update(player)");

      if (::game_status & GAMESTATUS::GAME)
	this->table().name(player).set();
      this->table().party_points().names_update();
      this->party_settings().name_update(player);
      this->genscher().name_update(player);
      this->genscher_info().name_update(player);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_UPDATE,
		      "Playfield::name_update(player)");
    } // void Playfield::name_update(Player const& player)

  /**
   **
   ** the language is updated
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::language_update()
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_UPDATE,
		    "Playfield::language_update()");

      this->table().language_update();

      this->party_settings().language_update();
      this->reservation().language_update();
      this->gametype().language_update();
      this->genscher().language_update();
      this->genscher_info().language_update();
      this->game_finished().language_update();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_UPDATE,
		      "Playfield::language_update()");
    } // void Playfield::language_update()

  /**
   **
   ** event: a key is pressed
   **
   ** @param	widget		widget in which the key is pressed
   ** @param	key		pressed key
   ** @param	playfield	the playfield
   **
   ** @return	whether the key is evaluated
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  gboolean
    Playfield::key_event(GtkWidget* widget,
			 GdkEventKey* key,
			 gpointer playfield)
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_KEY && INFO_GTK_EVENT,
		    "Playfield::key_event()");

      DEBUG_ASSERTION((playfield != NULL),
		      "Playfield::key_event():\n"
		      "  'playfield' == NULL");

      static_cast<Playfield*>(playfield)->key(key);

      DEBUG_RETURNING(FALSE,
		      INFO_GTK_PLAYFIELD && INFO_GTK_KEY && INFO_GTK_EVENT,
		      "Playfield::key_event()");
    } // static gboolean Playfield::key_event(GtkWidget* widget, GdkEventKey* key, gpointer playfield)

  /**
   **
   ** event: a key is pressed
   **
   ** @param	key		pressed key
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    Playfield::key(GdkEventKey* key)
    {
      DEBUG_CALLING(INFO_GTK_PLAYFIELD && INFO_GTK_KEY,
		    "Playfield::key()");

#include <gdk/gdkkeysyms.h>

      switch (key->keyval) {
	// Playing cards
      case GDK_1:
	this->gui().select_card_all(0);
	break;
      case GDK_2:
	this->gui().select_card_all(1);
	break;
      case GDK_3:
	this->gui().select_card_all(2);
	break;
      case GDK_4:
	this->gui().select_card_all(3);
	break;
      case GDK_5:
	this->gui().select_card_all(4);
	break;
      case GDK_6:
	this->gui().select_card_all(5);
	break;
      case GDK_7:
	this->gui().select_card_all(6);
	break;
      case GDK_8:
	this->gui().select_card_all(7);
	break;
      case GDK_9:
	this->gui().select_card_all(8);
	break;
      case GDK_0:
	this->gui().select_card_all(9);
	break;
      case GDK_a:
	this->gui().select_card_all(10);
	break;
      case GDK_b:
	this->gui().select_card_all(11);
	break;

      default: // pass the key to the gui
	this->gui().key(key);
	break;
      } // switch (key->keyval)

      DEBUG_RETURNING(VOID,
		      INFO_GTK_PLAYFIELD && INFO_GTK_KEY,
		      "Playfield::key()");
    } // void Playfield::key(GdkKeyEvent* key);

} // namespace GTK_DOKO
#endif // #ifdef USE_UI_GTK
