/**********************************************************************
 *
 *   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 "trick_drawing.h"
#include "ui.h"
#include "table.h"
#include "cards.h"

#include "../../card/trick.h"
#include "../../misc/setting.h"

namespace UI_GTKMM_NS {

  /**
   **
   ** Constructor
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **
   **/
  TrickDrawing::TrickDrawing(Base* const base) :
    Base(base),
  center(),
  trick(NULL)
    {
      DEBUG_CALLING(INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_INIT,
		    "TrickDrawing::TrickDrawing(base)");

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_INIT,
		      "TrickDrawing::TrickDrawing(base)");
    } // TrickDrawing::TrickDrawing(Base* const base)

  /**
   **
   ** Destruktor
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **
   **/
  TrickDrawing::~TrickDrawing()
  {
    DEBUG_CALLING(INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_INIT,
		  "TrickDrawing::~TrickDrawing()");

    DEBUG_RETURNING(VOID,
		    INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_INIT,
		    "TrickDrawing::~TrickDrawing()");
  } // TrickDrawing::~TrickDrawing()

  /**
   **
   ** sets the center of the trick in the drawable
   **
   ** @param	center	position of the center
   **
   ** @return	-
   **
   ** @version	0.6.2
   **
   ** @author	Diether Knof
   **
   **/
  void
    TrickDrawing::set_center(Gdk::Point const& center)
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "TrickDrawing::set_center(center)");

      this->center = center;

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "TrickDrawing::set_center(center)");
    } // void TrickDrawing::set_center(Gdk::Point const& center)

  /**
   **
   ** sets the trick
   **
   ** @param	trick	trick to draw
   **
   ** @return	-
   **
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  void
    TrickDrawing::set_trick(::Trick const& trick)
    {
      DEBUG_CALLING(INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		    "TrickDrawing::set_trick(trick)");

      this->trick = &trick;

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_TABLE && INFO_GTKMM_VALUE,
		      "TrickDrawing::set_trick(trick)");
    } // void TrickDrawing::set_trick(::Trick const& trick)

  /**
   **
   ** draws the trick
   **
   ** @param	update	whether to update the area
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **
   **/
  void
    TrickDrawing::draw(Glib::RefPtr<Gdk::Drawable> drawable)
    {
      DEBUG_CALLING(INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_DRAW,
		    "TrickDrawing::draw(drawable)");

      DEBUG_ASSERTION((this->trick != NULL),
		      "TrickDrawing::draw(drawable):\n"
		      "  this->trick == NULL");

      for (unsigned c = 0; c < this->trick->actcardno(); c++) {
	int pos_x = this->center.get_x();
	int pos_y = this->center.get_y();
	Player const& player = this->trick->player_of_card(c);

	switch (this->ui->table->position(player)) {
	case NORTH:
	  pos_x -= this->ui->cards->width() / 2;
	  pos_y -= this->ui->cards->height();

	  pos_x -= this->overlap_x();
	  pos_y += this->overlap_y();
	  break;
	case SOUTH:
	  pos_x -= this->ui->cards->width() / 2;

	  pos_x += this->overlap_x();
	  pos_y -= this->overlap_y();
	  break;
	case WEST:
	  if (::setting(Setting::ROTATE_TRICK_CARDS)) {
	    pos_x -= this->ui->cards->width(this->ui->table->rotation(player));
	    pos_y -= (this->ui->cards->height(this->ui->table->rotation(player))
		      / 2);
	  } else { // if (::setting(Setting::ROTATE_TRICK_CARDS))
	    pos_x -= this->ui->cards->width();
	    pos_y -= this->ui->cards->height() / 2;
	  } // if (::setting(Setting::ROTATE_TRICK_CARDS))
	  pos_x += this->overlap_x();
	  pos_y += this->overlap_y();
	  break;
	case EAST:
	  if (::setting(Setting::ROTATE_TRICK_CARDS)) {
	    pos_y -= (this->ui->cards->height(this->ui->table->rotation(player))
		      / 2);
	  } else { // if (::setting(Setting::ROTATE_TRICK_CARDS))
	    pos_y -= this->ui->cards->height() / 2;
	  } // if (::setting(Setting::ROTATE_TRICK_CARDS))
	  pos_x -= this->overlap_x();
	  pos_y -= this->overlap_y();
	  break;
	} // switch (this->position(this->trick->player_of_card(c)))
	drawable->draw_pixbuf(this->ui->table->gc,
			      (::setting(Setting::ROTATE_TRICK_CARDS)
			       ? this->ui->cards->card(this->trick->card(c),
						       this->ui->table->rotation(player))
			       : this->ui->cards->card(this->trick->card(c))
			      ),
			      0, 0,
			      pos_x, pos_y,
			      -1, -1,
			      Gdk::RGB_DITHER_NONE,
			      0, 0);
      } // for (c < this->trick->actcardno())

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_DRAW,
		      "TrickDrawing::draw(drawable)");
    } // void TrickDrawing::draw(Glib::RefPtr<Gdk::Drawable> drawable)

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	starting position of the trick
   ** 
   ** @version	0.6.2
   **
   ** @author	Diether Knof
   **
   **/
  Gdk::Point
    TrickDrawing::start() const
    {
      DEBUG_CALLING(INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		    "TrickDrawing::start()");

      DEBUG_RETURNING(Gdk::Point(this->center.get_x() - (this->width() / 2),
				 this->center.get_y() - (this->height() / 2)),
		      INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		      "TrickDrawing::start()");
    } // Gdk::Point TrickDrawing::start()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	starting y position of the trick
   ** 
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  Gdk::Rectangle
    TrickDrawing::outline() const
    {
      DEBUG_CALLING(INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		    "TrickDrawing::outline()");

      DEBUG_RETURNING(Gdk::Rectangle(this->start().get_x(),
				     this->start().get_y(),
				     this->width(),
				     this->height()),
		      INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		      "TrickDrawing::outline()");
    } // Gdk::Rectangle TrickDrawing::outline()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	width of the trick
   ** 
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  int
    TrickDrawing::width() const
    {
      DEBUG_CALLING(INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		    "TrickDrawing::width()");

      DEBUG_RETURNING(2 * ((::setting(Setting::ROTATE_TRICK_CARDS)
			    ? this->ui->cards->height()
			    : this->ui->cards->width()
			   ) - this->overlap_x()),
		      INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		      "TrickDrawing::width()");
    } // int TrickDrawing::width()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	height of the trick
   ** 
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  int
    TrickDrawing::height() const
    {
      DEBUG_CALLING(INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		    "TrickDrawing::height()");

      DEBUG_RETURNING(2 * (this->ui->cards->height() - this->overlap_y()),
		      INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		      "TrickDrawing::height()");
    } // int TrickDrawing::height()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the x overlapping over the center of the cards
   ** 
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  int
    TrickDrawing::overlap_x() const
    {
      DEBUG_CALLING(INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		    "TrickDrawing::overlap_x()");

      DEBUG_RETURNING((::setting(Setting::ROTATE_TRICK_CARDS)
		       ? this->ui->cards->height()
		       : this->ui->cards->width()
		      ) / 10,
		      INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		      "TrickDrawing::overlap_x()");
    } // int TrickDrawing::overlap_x()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the y overlapping over the center of the cards
   ** 
   ** @version	0.6.1
   **
   ** @author	Diether Knof
   **
   **/
  int
    TrickDrawing::overlap_y() const
    {
      DEBUG_CALLING(INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		    "TrickDrawing::overlap_y()");

      DEBUG_RETURNING(this->ui->cards->height() / 10,
		      INFO_GTKMM_TRICK_DRAWING && INFO_GTKMM_VALUE,
		      "TrickDrawing::overlap_y()");
    } // int TrickDrawing::overlap_y()

} // namespace UI_GTKMM_NS

#endif // #ifdef USE_UI_GTKMM
