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

#include "table.h"
#include "poverty.h"
#include "trick.h"
#include "hand.h"
#include "trickpile.h"
#include "icongroup.h"
#include "name.h"

#include "ui.h"
#include "cards.h"

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

#include <gtkmm/drawingarea.h>

namespace UI_GTKMM_NS {

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the poverty
   **
   ** @version	0.6.2
   **
   ** @author	Diether Knof
   **
   **/
  Poverty&
    Table::poverty()
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::poverty()");

      DEBUG_RETURNING(*(this->poverty_),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::poverty()");
    } //Poverty& Table::poverty()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the trick
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Trick&
    Table::trick()
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::trick()");

      DEBUG_RETURNING(*(this->trick_),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::trick()");
    } // Trick& Table::trick()

  /**
   **
   ** -> result
   **
   ** @param	player	the player
   **
   ** @return	the hand object of 'player'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Hand&
    Table::hand(Player const& player)
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::hand(player)");

      DEBUG_ASSERTION((this->hand_.size() > player.no()),
		      "Table::hand(player):\n"
		      "  player.no() = " << player.no() 
		      << " > " << this->hand_.size()
		      << " = this->hand_.size()");

      DEBUG_RETURNING(*(this->hand_[player.no()]),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::hand(player)");
    } // Hand& Table::hand(Player const& player)

  /**
   **
   ** -> result
   **
   ** @param	player	the player
   **
   ** @return	the hand object of 'player'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Hand const&
    Table::hand(Player const& player) const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::hand(player)");

      DEBUG_ASSERTION((this->hand_.size() > player.no()),
		      "Table::hand(player):\n"
		      "  player.no() = " << player.no() 
		      << " > " << this->hand_.size()
		      << " = this->hand_.size()");

      DEBUG_RETURNING(*(this->hand_[player.no()]),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::hand(player)");
    } // Hand const& Table::hand(Player const& player) const

  /**
   **
   ** -> result
   **
   ** @param	position	the position
   **
   ** @return	the hand object at 'position'
   **
   ** @version	0.6.3
   **
   ** @author	Diether Knof
   **
   **/
  Hand&
    Table::hand(Position const position)
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::hand(position)");

      DEBUG_RETURNING(this->hand(this->player(position)),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::hand(position)");
    } // Hand& Table::hand(Position const position)

  /**
   **
   ** -> result
   **
   ** @param	player	the player
   **
   ** @return	the trickpile object of 'player'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  TrickPile&
    Table::trickpile(Player const& player)
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::trickpile(player)");

      DEBUG_ASSERTION((this->trickpile_.size() > player.no()),
		      "Table::trickpile(player):\n"
		      "  player.no() = " << player.no() 
		      << " > " << this->trickpile_.size()
		      << " = this->trickpile_.size()");

      DEBUG_RETURNING(*(this->trickpile_[player.no()]),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::trickpile(player)");
    } // TrickPile& Table::trickpile(Player const& player)

  /**
   **
   ** -> result
   **
   ** @param	player	the player
   **
   ** @return	the trickpile object of 'player'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  TrickPile const&
    Table::trickpile(Player const& player) const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::trickpile(player)");

      DEBUG_ASSERTION((this->trickpile_.size() > player.no()),
		      "Table::trickpile(player):\n"
		      "  player.no() = " << player.no() 
		      << " > " << this->trickpile_.size()
		      << " = this->trickpile_.size()");

      DEBUG_RETURNING(*(this->trickpile_[player.no()]),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::trickpile(player)");
    } // TrickPile const& Table::trickpile(Player const& player) const

  /**
   **
   ** -> result
   **
   ** @param	position	the position
   **
   ** @return	the hand object at 'position'
   **
   ** @version	0.6.3
   **
   ** @author	Diether Knof
   **
   **/
  TrickPile&
    Table::trickpile(Position const position)
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::trickpile(position)");

      DEBUG_RETURNING(this->trickpile(this->player(position)),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::trickpile(position)");
    } // TrickPile& Table::trickpile(Position const position)

  /**
   **
   ** -> result
   **
   ** @param	player	the player
   **
   ** @return	the icongroup object of 'player'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Icongroup&
    Table::icongroup(Player const& player)
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::icongroup(player)");

      DEBUG_ASSERTION((this->icongroup_.size() > player.no()),
		      "Table::icongroup(player):\n"
		      "  player.no() = " << player.no() 
		      << " > " << this->icongroup_.size()
		      << " = this->icongroup_.size()");

      DEBUG_RETURNING(*(this->icongroup_[player.no()]),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::icongroup(player)");
    } // Icongroup& Table::icongroup(Player const& player)

  /**
   **
   ** -> result
   **
   ** @param	player	the player
   **
   ** @return	the icongroup object of 'player'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Icongroup const&
    Table::icongroup(Player const& player) const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::icongroup(player)");

      DEBUG_ASSERTION((this->icongroup_.size() > player.no()),
		      "Table::icongroup(player):\n"
		      "  player.no() = " << player.no() 
		      << " > " << this->icongroup_.size()
		      << " = this->icongroup_.size()");

      DEBUG_RETURNING(*(this->icongroup_[player.no()]),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::icongroup(player)");
    } // Icongroup const& Table::icongroup(Player const& player) const

  /**
   **
   ** -> result
   **
   ** @param	position	the position
   **
   ** @return	the hand object at 'position'
   **
   ** @version	0.6.3
   **
   ** @author	Diether Knof
   **
   **/
  Icongroup&
    Table::icongroup(Position const position)
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::icongroup(position)");

      DEBUG_RETURNING(this->icongroup(this->player(position)),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::icongroup(position)");
    } // Icongroup& Table::icongroup(Position const position)

  /**
   **
   ** -> result
   **
   ** @param	player	the player
   **
   ** @return	the name object of 'player'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Name&
    Table::name(Player const& player)
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::name(player)");

      DEBUG_ASSERTION((this->name_.size() > player.no()),
		      "Table::name(player):\n"
		      "  player.no() = " << player.no() 
		      << " > " << this->name_.size()
		      << " = this->name_.size()");

      DEBUG_RETURNING(*(this->name_[player.no()]),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::name(player)");
    } // Name& Table::name(Player const& player)

  /**
   **
   ** -> result
   **
   ** @param	player	the player
   **
   ** @return	the name object of 'player'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Name const&
    Table::name(Player const& player) const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::name(player)");

      DEBUG_ASSERTION((this->name_.size() > player.no()),
		      "Table::name(player):\n"
		      "  player.no() = " << player.no() 
		      << " > " << this->name_.size()
		      << " = this->name_.size()");

      DEBUG_RETURNING(*(this->name_[player.no()]),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::name(player)");
    } // Name const& Table::name(Player const& player) const

  /**
   **
   ** -> result
   **
   ** @param	position	the position
   **
   ** @return	the name object at 'position'
   **
   ** @version	0.6.3
   **
   ** @author	Diether Knof
   **
   **/
  Name&
    Table::name(Position const position)
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::name(position)");

      DEBUG_RETURNING(this->name(this->player(position)),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::name(position)");
    } // Name& Table::name(Position const position)
  
  /**
   **
   ** -> result
   **
   ** @param	player	the player
   **
   ** @return	the position of 'player'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Position
    Table::position(Player const& player) const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::position(player)");

      Position pos = NORTH;

      switch (player.no()) {
      case 0:
	pos = SOUTH;
	break;
      case 1:
	pos = WEST;
	break;
      case 2:
	pos = NORTH;
	break;
      case 3:
	pos = EAST;
	break;
      default:
	DEBUG_ASSERTION(false,
			"Table::position(player):\n"
			"  player number " << player.no()
			<< " invalid.");
      } // switch(player.no())

      DEBUG_RETURNING(pos,
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::position(player)");
    } // Position Table::position(Player const& player) const
  
  /**
   **
   ** -> result
   **
   ** @param	player	the player
   **
   ** @return	the position of 'player'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Player const&
    Table::player(Position const position) const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::player(position)");

      Player const* player = NULL;

      switch (position) {
      case SOUTH:
	player = &(::party.game().player(0));
	break;
      case WEST:
	player = &(::party.game().player(1));
	break;
      case NORTH:
	player = &(::party.game().player(2));
	break;
      case EAST:
	player = &(::party.game().player(3));
	break;
      } // switch(player.no())

      DEBUG_RETURNING(*player,
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::player(position)");
    } // Player const& Table::player(Position const position) const

  /**
   **
   ** -> result
   **
   ** @param	player	the player
   **
   ** @return	the rotation of 'player'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Rotation
    Table::rotation(Player const& player) const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::rotation(player)");

      DEBUG_RETURNING(this->rotation(this->position(player)),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::rotation(player)");
    } // Rotation Table::rotation(Player const& player) const

  /**
   **
   ** -> result
   **
   ** @param	position	the position
   **
   ** @return	the rotation of the player at 'position'
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Rotation
    Table::rotation(Position const position) const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::rotation(position)");

      Rotation rot = UP;

      switch (position) {
      case NORTH:
	rot = DOWN;
	break;
      case SOUTH:
	rot = UP;
	break;
      case WEST:
	rot = RIGHT;
	break;
      case EAST:
	rot = LEFT;
	break;
      } // switch(this->position())

      DEBUG_RETURNING(rot,
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::rotation(position)");
    } // Rotation Table::rotation(Position const position) const

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the width of the table
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  unsigned
    Table::width() const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::width()");

      DEBUG_RETURNING(this->get_width(),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::width()");
    } // unsigned Table::width() const

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the height of the table
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  unsigned
    Table::height() const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::height()");

      DEBUG_RETURNING(this->get_height(),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::height()");
    } // unsigned Table::height() const

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the depth of the table
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  unsigned
    Table::depth() const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::depth()");

      DEBUG_RETURNING(this->get_window()->get_depth(),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::depth()");
    } // unsigned Table::depth() const

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	border on the left and right
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  unsigned
    Table::border_x() const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::border_x()");

      DEBUG_RETURNING((this->ui->cards->height() / 10),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::border_x()");
    } // unsigned Table::border_x() const

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	border on the top and bottom
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  unsigned
    Table::border_y() const
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "Table::border_y()");

      DEBUG_RETURNING((this->ui->cards->height() / 10),
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "Table::border_y()");
    } // unsigned Table::border_y() const

} // namespace UI_GTKMM_NS

#endif // #ifdef USE_UI_GTKMM
