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

#include "../../party/party.h"
#include "../../game/game.h"
#include "../../card/trick.h"
#include "../../misc/setting.h"
#include "../../misc/language.h"

namespace GTK_DOKO {
#include <gtk/gtkmain.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkclist.h>
#include <gtk/gtkpixmap.h>

  /*****************************************************************************
   *
   * FullTrick::FullTrick(Table* table_a)
   *
   * Parameters:	table_a - the table
   *
   * Result:	none
   * 
   * Version:	0.3.7
   *
   * Description:	Constructor
   *
   ****************************************************************************/
  FullTrick::FullTrick(Table* table_a) :
    TableDialog(table_a, "Full trick"), // the base class
  winnercard(table_a->gui().cards().card(Card()).widget()), // the winnercard
  text(gtk_label_new("")), // the text
  extrapoints(NULL), // the table with the extrapoints
  timeout_id(0) // timeout id for closing the window
  {
    DEBUG_CALLING(INFO_GTK_FULL_TRICK && INFO_GTK_INIT,
		  "FullTrick::FullTrick()");


    {
      char* titles[1];
      titles[0] = new char[1];
      titles[0][0] = '\0';
      extrapoints = gtk_clist_new_with_titles(1, titles);
      gtk_clist_column_titles_show(GTK_CLIST(extrapoints));
      gtk_clist_set_column_justification(GTK_CLIST(extrapoints), 0,
					 GTK_JUSTIFY_CENTER);
    }

    // the winnercard
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window())->vbox), winnercard);
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window())->vbox), text);
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window())->vbox), extrapoints);

    // the 'close' button
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window())->action_area),
		      button_close);


    DEBUG_RETURNING(VOID,
		    INFO_GTK_FULL_TRICK && INFO_GTK_INIT,
		    "FullTrick::FullTrick()");
  } // FullTrick::FullTrick(Table* table_a)

  /*****************************************************************************
   *
   * void FullTrick::init()
   *
   * Parameters:	none
   *
   * Result:	none
   * 
   * Version:	0.3.6
   *
   * Description:	inits the 'full trick' window
   *
   ****************************************************************************/
  void
    FullTrick::init()
    {
      DEBUG_CALLING(INFO_GTK_FULL_TRICK && INFO_GTK_INIT,
		    "FullTrick::init()");

      this->TableDialog::init();

      gtk_window_set_transient_for(GTK_WINDOW(this->window()),
				   GTK_WINDOW(gui().main_window().window()));
      { // center the window
	int x, y, width, height, wwidth, wheight;

	gdk_window_get_geometry(gui().main_window().window()->window,
				&x, &y, &width, &height, NULL);
	gdk_window_get_size(this->window()->window, &wwidth, &wheight);
	gdk_window_move(this->window()->window,
			x + width / 2 - wwidth / 2, y + height / 2 - wheight / 2);
      } // center the window

      DEBUG_RETURNING(VOID,
		      INFO_GTK_FULL_TRICK && INFO_GTK_INIT,
		      "FullTrick::init()");
    } // void FullTrick::init()

  /*****************************************************************************
   *
   * static gint FullTrick::close_timeout_event(gpointer full_trick)
   *
   * Parameters:	full_trick - full trick of the event
   *
   * Result:	none
   *
   * Version:	0.3.7
   *
   * Description:	the full trick is to be closed (timeout event)
   *
   ****************************************************************************/
  gint
    FullTrick::close_timeout_event(gpointer full_trick)
    {
      DEBUG_CALLING(INFO_GTK_FULL_TRICK && INFO_GTK_EVENT,
		    "FullTrick::close_timeout_event()");

      ((FullTrick*)full_trick)->close();
      DEBUG_RETURNING(FALSE,
		      INFO_GTK_FULL_TRICK && INFO_GTK_EVENT,
		      "FullTrick::close_timeout_event()");
    } // static gint FullTrick::close_timeout_event(gpointer full_trick)

  /*****************************************************************************
   *
   * void FullTrick::show()
   *
   * Parameters:	none
   *
   * Result:	none
   *
   * Version:	0.3.6
   *
   * Description:	shows the window
   *
   ****************************************************************************/
  void
    FullTrick::show()
    {
      DEBUG_CALLING(INFO_GTK_FULL_TRICK && INFO_GTK_EVENT,
		    "FullTrick::show()");

      if (game_status == GAMESTATUS::GAME_SHOW_FULL_TRICK)
	DEBUG_RETURNING(VOID,
			INFO_GTK_FULL_TRICK && INFO_GTK_EVENT,
			"FullTrick::show()");

      DEBUG_ASSERTION(game_status == GAMESTATUS::GAME_PLAY,
		      "FullTrick::show()\n"
		      "  'game_status' != GAME_PLAY");

      if (!FAST_PLAY) {
	// wait some time
	::game_status = GAMESTATUS::GAME_SHOW_FULL_TRICK;
	if (::setting(Setting::SHOW_FULL_TRICK_WINDOW))
	  this->gui().sleep(setting(Setting::CARD_PLAY_DELAY));


	// the full trick status can be exit now (because of the update call)
	if (::game_status == GAMESTATUS::GAME_SHOW_FULL_TRICK) {
	  if (::setting(Setting::SHOW_FULL_TRICK_WINDOW)) {

	    // update the card and the text
	    this->cards_update();
	    this->language_update();

	    // show the window
	    if (::setting(Setting::SHOW_FULL_TRICK_WINDOW)) {
	      this->TableDialog::show();
	    }
	  } // if (setting(Setting::SHOW_FULL_TRICK_WINDOW))

	  // wait until the window is closed
	  if (::setting(Setting::CLOSE_FULL_TRICK_AUTOMATICALLY))
	    this->timeout_id
	      = gtk_timeout_add(::setting(Setting::FULL_TRICK_CLOSE_DELAY),
				FullTrick::close_timeout_event,
				gpointer(this));

	  while (::game_status == GAMESTATUS::GAME_SHOW_FULL_TRICK)
	    gtk_main();

	  if (this->timeout_id != 0)
	    gtk_timeout_remove(this->timeout_id);

	  // close the window
	  this->close();

	} // if (game_status == GAMESTATUS::GAME_SHOW_FULL_TRICK)
      } // if (!FAST_PLAY)

      DEBUG_RETURNING(VOID,
		      INFO_GTK_FULL_TRICK && INFO_GTK_EVENT,
		      "FullTrick::show()");
    } // void FullTrick::show()

  /*****************************************************************************
   *
   * void FullTrick::close()
   *
   * Parameters:	none
   *
   * Result:	none
   *
   * Version:	0.3.6
   *
   * Description:	closes the window
   *
   ****************************************************************************/
  void
    FullTrick::close()
    {
      DEBUG_CALLING(INFO_GTK_FULL_TRICK && INFO_GTK_EVENT,
		    "FullTrick::close()");

      if (!(::game_status & GAMESTATUS::GAME)
	  || (::game_status == GAMESTATUS::GAME_SHOW_FULL_TRICK)) {
	// hide the window

	this->TableDialog::close();

	if (::game_status == GAMESTATUS::GAME_SHOW_FULL_TRICK)
	  ::game_status = GAMESTATUS::GAME_PLAY;

	this->gui().main_quit();
      }

      DEBUG_RETURNING(VOID,
		      INFO_GTK_FULL_TRICK && INFO_GTK_EVENT,
		      "FullTrick::close()");
    } // void FullTrick::close()


  /*****************************************************************************
   *
   * void FullTrick::cards_update()
   *
   * Parameters:	none
   *
   * Result:	none
   * 
   * Version:	0.3.6
   *
   * Description:	updates the cards in the full trick window
   *
   ****************************************************************************/
  void
    FullTrick::cards_update()
    {
      DEBUG_CALLING(INFO_GTK_FULL_TRICK && INFO_GTK_UPDATE,
		    "FullTrick::cards_update()");

      if (game_status == GAMESTATUS::GAME_SHOW_FULL_TRICK) {
	// redraw the winnercard
	gtk_pixmap_set(GTK_PIXMAP(winnercard),
		       gui().cards().card(party.game().trick_current().winnercard()
					 ).pixmap(),
		       gui().cards().card(party.game().trick_current().winnercard()
					 ).mask());
      } // if (game_status == GAMESTATUS::GAME_SHOW_FULL_TRICK)

      DEBUG_RETURNING(VOID,
		      INFO_GTK_FULL_TRICK && INFO_GTK_UPDATE,
		      "FullTrick::cards_update()");
    } // void FullTrick::cards_update()


  /*****************************************************************************
   *
   * void FullTrick::language_update()
   *
   * Parameters:	none
   *
   * Result:	none
   * 
   * Version:	0.3.6
   *
   * Description:	updates the language in the full trick window
   *
   ****************************************************************************/
  void
    FullTrick::language_update()
    {
      DEBUG_CALLING(INFO_GTK_FULL_TRICK && INFO_GTK_UPDATE,
		    "FullTrick::language_update()");

      this->TableDialog::language_update();

      if ((::game_status >= GAMESTATUS::GAME_PLAY)
	  && (::game_status < GAMESTATUS::GAME_FINISHED)) {
	::Trick const& trick = ::party.game().trick_current();
	if (game_status == GAMESTATUS::GAME_SHOW_FULL_TRICK) {
	  gtk_label_set_text(GTK_LABEL(text),
			     (("\n        " +
			       language("The trick goes to %swinner%.",
					trick.winnerplayer().name().c_str())
			       + "        \n")).c_str());

	} // if (game_status == GAME::SHOW_FULL_TRICK)

	{ // add the extra points
	  // create team vector
	  vector<Team> team;
	  for (vector<Player*>::const_iterator 
	       p = ::party.game().player_begin();
	       p != ::party.game().player_end();
	       p++) {
	    team.push_back((*p)->game().teaminfo(**p));
	    for (vector<Player*>::const_iterator 
		 h = ::party.game().player_begin();
		 h != ::party.game().player_end();
		 h++) {
	      if ((*h)->type() == Player::HUMAN)
		if (((*h)->teaminfo(**p) == TEAM::RE)
		    || ((*h)->teaminfo(**p) == TEAM::CONTRA))
		  team.back() = (*h)->teaminfo(**p);
	    } // for (h \in ::party.game().player)
	  } // for (p \in ::party.game().player)

	  Specialpointsvector special_points_of_trick = trick.specialpoints();
	  Specialpointsvector special_points;
	  for (Specialpointsvector::const_iterator
	       sp = special_points_of_trick.begin();
	       sp != special_points_of_trick.end();
	       sp++) {
	    if (sp->is_valid(team)) {
	      special_points.push_back(*sp);
	    }
	  }

	  gtk_clist_freeze(GTK_CLIST(extrapoints));

	  gtk_clist_set_column_title(GTK_CLIST(extrapoints), 0,
				     language("Extrapoints").c_str());

	  // first remove all old elements of the list
	  gtk_clist_clear(GTK_CLIST(extrapoints));
	  if (!special_points.empty()) {
	    for (Specialpointsvector::const_iterator sp = special_points.begin();
		 sp != special_points.end();
		 sp++) {
	      char const** row = const_cast<char const**>(new char*[1]);
	      row[0] = ::language(sp->type).c_str();
	      gtk_clist_append(GTK_CLIST(extrapoints),
			       static_cast<gchar**>(const_cast<char**>(row)));
	    } // for (sp \in special_points)

	    gtk_widget_show(extrapoints);
	  } else { // if !(!special_points.empty())
	    gtk_widget_hide(extrapoints);
	  } // if !(!special_points.empty())

	  gtk_clist_thaw(GTK_CLIST(extrapoints));
	} // add the extra points
      } // if (::game_status & GAMESTATUS::GAME)

      DEBUG_RETURNING(VOID,
		      INFO_GTK_FULL_TRICK && INFO_GTK_UPDATE,
		      "FullTrick::language_update()");
    } // void FullTrick::language_update()

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