/**********************************************************************
 *
 *   FreeDoko a Doppelkopf-Game
 *    
 *   Copyright (C) 2001-2006  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 "game_summary.h"

#include "ui.h"
#include "translations.h"
#include "bug_report.h"

#include "../../party/party.h"
#include "../../game/game_summary.h"
#include "../../utils/string.h"

#include <gtkmm/button.h>
#include <gtkmm/alignment.h>
#include <gtkmm/separator.h>
#include <gtkmm/label.h>
#include <gtkmm/main.h>
#include <gtkmm/treeview.h>
#include <gtkmm/scrolledwindow.h>

namespace UI_GTKMM_NS {

  /**
   ** Constructor
   **
   ** @param	parent	parent object
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **/
  GameSummary::GameSummary(Base* const parent) :
    Base(parent),
    VBox(),
    gameno(UINT_MAX),
    gamenumber(NULL),
    type(NULL),
    winner(NULL),
    trickpoints_model(),
    trickpoints_list(NULL),
    trickpoints_treeview(NULL),
    points_description_model(),
    points_description_list(NULL),
    points_description_treeview(NULL)
  {
    this->signal_realize().connect(sigc::mem_fun(*this,
					      &GameSummary::init));

    return ;
  } // GameSummary::GameSummary(Base* const parent)

  /**
   ** Destruktor
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **/
  GameSummary::~GameSummary()
  {
    return ;
  } // GameSummary::~GameSummary()

  /**
   ** create all subelements
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **/
  void
    GameSummary::init()
    {
      this->set_border_width(1 ex);
      this->set_spacing(1 ex);

      this->gamenumber = Gtk::manage(new Gtk::Label("Game:"));
      this->ui->translations->add(*(this->gamenumber),
				  ::translation("Game %ugameno%",
					       0u));
      this->pack_start(*(this->gamenumber), false, true);

      this->winner = Gtk::manage(new Gtk::Label("Winner:"));
      this->ui->translations->add(*(this->winner),
				  ::translation("Winner: no team"));
      this->pack_start(*(this->winner), false, true);


      { // trickpoints
	this->trickpoints_list
	  = Gtk::ListStore::create(this->trickpoints_model);
	this->trickpoints_treeview
	  = Gtk::manage(new Gtk::TreeView(this->trickpoints_list));
	this->trickpoints_treeview->get_selection()->set_mode(Gtk::SELECTION_NONE);

	this->trickpoints_treeview->append_column("Name",
						  this->trickpoints_model.name);
	this->trickpoints_treeview->append_column("Trick points",
						  this->trickpoints_model.points);
	this->trickpoints_treeview->get_column_cell_renderer(1)->property_xalign() = 0.5;
	this->trickpoints_treeview->append_column("Team",
						  this->trickpoints_model.team);
	this->trickpoints_treeview->append_column("game poinst",
						  this->trickpoints_model.game_points);
	this->trickpoints_treeview->get_column_cell_renderer(3)->property_xalign() = 0.5;
	this->trickpoints_treeview->append_column("party points",
						  this->trickpoints_model.party_points);
	this->trickpoints_treeview->get_column_cell_renderer(4)->property_xalign() = 0.5;

	Gtk::Alignment* alignment
	  = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_CENTER,
					   Gtk::ALIGN_CENTER,
					   0, 0));
	alignment->add(*(this->trickpoints_treeview));
	this->pack_start(*alignment, false, true);
      } // trickpoints

      this->type = Gtk::manage(new Gtk::Label("Game type:"));
      this->ui->translations->add(*(this->type),
				  ::translation("gametype: %ttype%",
					       ::translation(GAMETYPE::NORMAL)));

      this->pack_start(*(this->type), false, true);


      { // points description
	this->points_description_list
	  = Gtk::ListStore::create(this->points_description_model);
	this->points_description_treeview
	  = Gtk::manage(new Gtk::TreeView(this->points_description_list));

#ifndef OUTDATED
	// ToDo: selecting a special point shows the corresponding trick
	// in the game review
	this->points_description_treeview->get_selection()->set_mode(Gtk::SELECTION_NONE);
#endif
	this->points_description_treeview->append_column("Team",
							 this->points_description_model.team);
	// ToDo: right-align the sign
	this->points_description_treeview->append_column("Player",
							 this->points_description_model.player);
#ifdef OUTDATED
	this->points_description_treeview->append_column("Sign",
							 this->points_description_model.sign);
	this->points_description_treeview->get_column_cell_renderer(2)->property_xalign() = 1;
#endif
	this->points_description_treeview->append_column("Points",
							 this->points_description_model.points);
	this->points_description_treeview->get_column_cell_renderer(2)->property_xalign() = 0.5;
	this->points_description_treeview->append_column("Description",
							 this->points_description_model.description);

#ifdef POSTPHONED
	// ToDo: make the scrolled window show the first four lines of the table
	Gtk::ScrolledWindow* scrolled_window
	  = Gtk::manage(new Gtk::ScrolledWindow);
	scrolled_window->set_policy(Gtk::POLICY_NEVER,
				    Gtk::POLICY_AUTOMATIC);
	scrolled_window->add(*(this->points_description_treeview));
	this->pack_start(*scrolled_window, true, true);
#else
	Gtk::Alignment* alignment
	  = Gtk::manage(new Gtk::Alignment(Gtk::ALIGN_CENTER,
					   Gtk::ALIGN_CENTER,
					   0, 1));
	alignment->add(*(this->points_description_treeview));
	this->pack_start(*alignment, true, true);
	//this->pack_start(*(this->points_description_treeview), true, true);
#endif
      } // trickpoints
      //this->pack_start(*(this->points_description));

      this->language_update();
      this->show_all_children();
      if (this->gameno != UINT_MAX)
	this->show();

      this->update();
      this->language_update();

      return ;
    } // void GameSummary::init()

  /**
   ** set the gameno
   **
   ** @param	gameno	the new gameno
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **/
  void
    GameSummary::set_gameno(unsigned const gameno)
    {
      this->gameno = gameno;
      this->update();

      return ;
    } // void GameSummary::set_gameno(unsigned const gameno)

  /**
   ** update (rewrite) all information
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **
   ** @todo	mark the winner gray
   ** @todo	if there is no 'player_of' don't show the column
   **/
  void
    GameSummary::update()
    {
      if (!this->is_realized())
	return ;

      if (::game_status < GAMESTATUS::PARTY_PLAY)
	return ;

      if (this->gameno == UINT_MAX) {
	this->hide();
	return ;
      }
      this->show();

      Party const& party = this->ui->party();
      ::GameSummary const& game_summary
	= party.game_summary(this->gameno);
      //= (static_cast<Party const&>(::party)).gamepointstable().gamepoints(this->gameno);

      this->ui->translations->change(*(this->gamenumber),
				     ::translation("Game %ugameno%",
						  this->gameno + 1));
      this->ui->translations->change(*(this->type),
				     ::translation("gametype: %ttype%",
						  ::translation(game_summary.game_type())));

      if (game_summary.winnerteam() == TEAM::NOTEAM)
	this->ui->translations->change(*this->winner,
				       ::translation("Winner: no team"));
      else
	this->ui->translations->change(*this->winner,
				       ::translation("Winner: team %twinnerteam% with %uwinnerpoints% points (%tlooserteam%: %ulooserpoints% points)",

						    ::translation(game_summary.winnerteam()),
						    game_summary.trick_points(game_summary.winnerteam()),
						    ::translation(::opposite(game_summary.winnerteam())),
						    game_summary.trick_points(::opposite(game_summary.winnerteam()))
						   )
				      );

      { // trickpoints
	this->trickpoints_list->clear();

	for (unsigned p = 0;
	     p < game_summary.rule()(Rule::NUMBER_OF_PLAYERS_IN_GAME);
	     p++) {
	  Gtk::TreeModel::Row row = *(this->trickpoints_list->append());
	  row[this->trickpoints_model.name] = this->ui->game().player(p).name();
	  row[this->trickpoints_model.points] = game_summary.trick_points(p);
	  row[this->trickpoints_model.team]
	    = ::translation(game_summary.team(p)).translation();
	  if (game_summary.player_get_points(p))
	    if (game_summary.points(p) > 0)
	      row[this->trickpoints_model.game_points]
		= "+" + DK::Utils::String::to_string(game_summary.points(p));
	    else
	      row[this->trickpoints_model.game_points]
		= DK::Utils::String::to_string(game_summary.points(p));
	  else
	    row[this->trickpoints_model.game_points]
	      = "";

	  row[this->trickpoints_model.party_points]
	    = party.pointsum_till_game(this->gameno, p);
	  // ToDo: Mark the winner gray
	} // for (p < game_summary.rule(Rule::NUMBER_OF_PLAYERS_IN_GAME)
      } // trickpoints

      { // points description
	if (game_summary.specialpoints().empty()) {
	  this->points_description_treeview->hide();
	} else { // if !(game_summary.specialpoints().empty())
	  this->points_description_treeview->show();

	  this->points_description_list->clear();

	  for (unsigned i = 0; i < game_summary.specialpoints().size(); i++) {
	    Gtk::TreeModel::Row row = *(this->points_description_list->append());
	    row[this->points_description_model.team]
	      = ::translation(game_summary.specialpoints()[i].team).translation();

	    if (game_summary.specialpoints()[i].player_get_no == UINT_MAX) {
	      if (game_summary.specialpoints()[i].player_of_no == UINT_MAX)
		row[this->points_description_model.player] = string();
	      else
		row[this->points_description_model.player]
		  = this->ui->game().player(game_summary.specialpoints()[i].player_of_no).name();
	    } else {
	      row[this->points_description_model.player]
		= this->ui->game().player(game_summary.specialpoints()[i].player_get_no).name();
	    }

	    row[this->points_description_model.description]
	      = ::translation(game_summary.specialpoints()[i].type).translation();

	    { // show whether the points are added or subtracted
	      bool add = true;
	    if ((game_summary.winnerteam() == TEAM::RE)
		|| (game_summary.winnerteam() == TEAM::CONTRA)) {
	      add = (game_summary.specialpoints()[i].counting_team
		     == game_summary.winnerteam());
	    } else { // if !(game_summary.winnerteam() == RE, CONTRA)
	      if (game_summary.specialpoints()[i].counting_team == TEAM::RE)
		add = true;
	      else if (game_summary.specialpoints()[i].counting_team == TEAM::CONTRA)
		add = false;
	    } // if !(game_summary.winnerteam() != RE, CONTRA)
	    if (add)
	      row[this->points_description_model.points] = "+";
	    else
	      row[this->points_description_model.points] = "-";
	    } // show whether the points are added or subtracted

	    if ( (game_summary.winnerteam() == TEAM::NOTEAM)
		 && (game_summary.specialpoints()[i].counting_team
		     == TEAM::NOTEAM))
	      row[this->points_description_model.points] = " ";
	    if ((game_summary.specialpoints()[i].type == SPECIALPOINT::NO120_SAID)
		&& (game_summary.rule()(Rule::ANNOUNCEMENT_RE_DOUBLES))) {
	      row[this->points_description_model.points] = "* 2";
	    } else if (game_summary.specialpoints()[i].type == SPECIALPOINT::SOLO) {
	      // a solo
	      row[this->points_description_model.points] = "* 3";
	    } else {
	      // all other special points
	      row[this->points_description_model.points]
		= (row[this->points_description_model.points]
		   + " " + DK::Utils::String::to_string(Value_of_Specialpoint(game_summary.specialpoints()[i].type))
		  );

	    }
	  } // for (i < game_summary.specialpoints().size())
	} // if !(game_summary.specialpoints().empty())

      } // points description

      return ;
    } // void GameSummary::update()

  /**
   ** the name of 'player' has changed
   **
   ** @param	player	the player with the changed name
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.6.4
   **/
  void
    GameSummary::name_changed(Player const& player)
    {
      if (!this->is_realized())
	return ;

      this->update();

      return ;
    } // void GameSummary::name_changed(Player const& player)

  /**
   ** updates all language elements
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **/
  void
    GameSummary::language_update()
    {
      if (!this->is_realized())
	return ;

      this->trickpoints_treeview->get_column(0)->set_title(::translation("Name").translation());
      this->trickpoints_treeview->get_column(1)->set_title(::translation("trick points").translation());
      this->trickpoints_treeview->get_column(2)->set_title(::translation("Team").translation());
      this->trickpoints_treeview->get_column(3)->set_title(::translation("game points").translation());
      this->trickpoints_treeview->get_column(4)->set_title(::translation("party points").translation());

      this->points_description_treeview->get_column(0)->set_title(::translation("Team").translation());
      this->points_description_treeview->get_column(1)->set_title(::translation("Player").translation());
#if 0
      this->points_description_treeview->get_column(2)->set_title(::translation("Sign").translation());
#endif
      this->points_description_treeview->get_column(2)->set_title(::translation("Point(s)").translation());
      this->points_description_treeview->get_column(3)->set_title(::translation("Description").translation());

      this->update();

      return ;
    } // void GameSummary::language_update()

} // namespace UI_GTKMM_NS

#endif // #ifdef USE_UI_GTKMM
