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

#include "../../player/player.h"
#include "../../misc/setting.h"

#include "widgets/stock_button.h"
#include <gtkmm/stock.h>
#include <gtkmm/box.h>
#include <gtkmm/image.h>
#include <gtkmm/label.h>

namespace UI_GTKMM_NS {

  // position of the window
  int AnnouncementInfo::position_x = INT_MAX;
  int AnnouncementInfo::position_y = INT_MAX;

  /**
   **
   ** Constructor
   **
   ** @param	table	the table
   ** @param	player	the player who has swines
   **
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **
   **/
  AnnouncementInfo::AnnouncementInfo(Table* const table, Player const& player) :
    GameinfoDialog(table),
  icon(NULL),
  text(NULL),
  reply(NULL),
  player(&player)
  {
    DEBUG_CALLING(INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_INIT,
		  "AnnouncementInfo::AnnouncementInfo(table, player)");

    DEBUG_RETURNING(VOID,
		    INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_INIT,
		    "AnnouncementInfo::AnnouncementInfo(table, player)");
  } // AnnouncementInfo::AnnouncementInfo(Table* const table, Player const& player)

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

    DEBUG_RETURNING(VOID,
		    INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_INIT,
		    "AnnouncementInfo::~AnnouncementInfo()");
  } // AnnouncementInfo::~AnnouncementInfo()

  /**
   **
   ** init the dialog
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **
   **/
  void
    AnnouncementInfo::init()
    {
      DEBUG_CALLING(INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_INIT,
		    "AnnouncementInfo::init()");

      this->GameinfoDialog::init();

      if (this->player->announcement() == ANNOUNCEMENT::NO120)
	this->ui->add_for_translation(*this,
				      ::translator(this->player->team()));

      else
	this->ui->add_for_translation(*this,
				      ::translator(this->player->announcement()
						  ));


      this->icon
	= Gtk::manage(new Gtk::Image( (this->player->announcement()
				       == ANNOUNCEMENT::NO120)
				      ? this->ui->icons->icon(this->player->team())
				      : this->ui->icons->icon(this->player->announcement())));
      this->text = Gtk::manage(new Gtk::Label("Player announces 'announcement'."));
      if (this->player->announcement() == ANNOUNCEMENT::NO120) {
	this->ui->add_for_translation(*(this->text),
				      ::translator("%splayer% announces '%tannouncement%'.",
						   this->player->name(),
						   ::translator(this->player->team())
						  ));

      } else {
	this->ui->add_for_translation(*(this->text),
				      ::translator("%splayer% announces '%tannouncement%'.",
						   this->player->name(),
						   ::translator(this->player->announcement())
						  ));
      }
      this->close_button->show_all();

      Gtk::VBox* vbox = Gtk::manage(new Gtk::VBox(false, 20));
      vbox->set_border_width(20);

      vbox->add(*(this->icon));
      vbox->add(*(this->text));

      this->get_vbox()->add(*vbox);

      { // show 'announcement reply' button
	Game const& game = this->player->game();
	// and human can announce 
	if (game.rule()(Rule::ANNOUNCEMENT_REPLY)
	    && (game.humanno() == 1)
	    && game.announcement_valid(ANNOUNCEMENT::REPLY,
				       *(game.human_player()))) {
	  this->reply = Gtk::manage(new Gtk::StockButton(Gtk::Stock::OK,
							 "announcement reply"));
	  this->ui->add_for_translation(*(this->reply),
					::translator(ANNOUNCEMENT::to_reply(this->player->announcement())
						    ));

	  this->add_action_widget(*(this->reply), Gtk::RESPONSE_ACCEPT);
	  this->get_action_area()->reorder_child(*(this->close_button), -1);

	  this->reply->show_all();

	  this->reply->signal_clicked().connect(SigC::slot(*this, &GameinfoDialog::close));
	  this->reply->signal_clicked().connect(SigC::slot(*this, &AnnouncementInfo::reply_event));
	} // if (show announcement reply button)
      } // show 'announcement reply' button

      this->show_all_children();

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_INIT,
		      "AnnouncementInfo::init()");
    } // void AnnouncementInfo::init()

  /**
   **
   ** event: make a reply
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.6.4
   **
   **/
  void
    AnnouncementInfo::reply_event()
    {
      DEBUG_CALLING(INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_EVENT,
		    "AnnouncementInfo::reply_event()");

      DEBUG_ASSERTION((this->player->game().human_player() != NULL),
		      "UI_GTKMM_NS::AnnouncementInfo::reply_event():\n"
		      "  Found no human player.");

      const_cast<Game&>(this->player->game()
		       ).announcement_make(ANNOUNCEMENT::to_reply(this->player->announcement()),
					   *(this->player->game().human_player()));


      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_EVENT,
		      "AnnouncementInfo::reply_event()");
    } // void AnnouncementInfo::reply_event()

  /**
   **
   ** show the window
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **
   **/
  void
    AnnouncementInfo::show_information()
    {
      DEBUG_CALLING(INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_GAMEPLAY,
		    "AnnouncementInfo::show_information()");

      this->GameinfoDialog::show_information(::setting(Setting::SHOW_ANNOUNCEMENT_WINDOW),
					     ::setting(Setting::CLOSE_ANNOUNCEMENT_WINDOW_AUTOMATICALLY),
					     ::setting(Setting::ANNOUNCEMENT_WINDOW_CLOSE_DELAY));

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_GAMEPLAY,
		      "AnnouncementInfo::show_information()");
    } // void AnnouncementInfo::show_information()

  /**
   **
   ** 'player' has made an announcement
   **
   ** @param	player	the player who has made the announcement
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.6.4
   **
   **/
  void
    AnnouncementInfo::announcement_made(Player const& player)
    {
      DEBUG_CALLING(INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_UPDATE,
		    "AnnouncementInfo::announcement_made(player)");

      if (this->reply
	  && this->reply->get_parent()) {
	dynamic_cast<Gtk::Container*>(this->reply->get_parent())->remove(*(this->reply));
	this->reply = NULL;
      }

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_UPDATE,
		      "AnnouncementInfo::announcement_made(player)");
    } // void AnnouncementInfo::announcement_made(Player const& player)

  /**
   **
   ** the name of 'player' has changed
   **
   ** @param	player	the player whose name has changed
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **
   **/
  void
    AnnouncementInfo::name_changed(Player const& player)
    {
      DEBUG_CALLING(INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_UPDATE,
		    "AnnouncementInfo::name_changed(player)");

      if (player == *(this->player)) {
	if (this->player->announcement() == ANNOUNCEMENT::NO120) {
	  this->ui->change_translation(*(this->text),
				       ::translator("%splayer% announces '%tannouncement%'.",
						    this->player->name(),
						    ::translator(::name(this->player->team()))
						   ));

	} else {
	  this->ui->change_translation(*(this->text),
				       ::translator("%splayer% announces '%tannouncement%'.",
						    this->player->name(),
						    ::translator(::name(this->player->announcement()))
						   ));
	}
      } // if (player == *(this->player))

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_UPDATE,
		      "AnnouncementInfo::name_changed(player)");
    } // void AnnouncementInfo::name_changed(Player const& player)

  /**
   **
   ** update the icons
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.6.1
   **
   **/
  void
    AnnouncementInfo::icons_update()
    {
      DEBUG_CALLING(INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_UPDATE,
		    "AnnouncementInfo::icons_update()");

      if (this->player->announcement() == ANNOUNCEMENT::NO120)
	this->icon->set(this->ui->icons->icon(this->player->team()));
      else
	this->icon->set(this->ui->icons->icon(this->player->announcement()));

      DEBUG_RETURNING(VOID,
		      INFO_GTKMM_ANNOUNCEMENT_INFO && INFO_GTKMM_UPDATE,
		      "AnnouncementInfo::icons_update()");
    } // void AnnouncementInfo::icons_update()

  /**
   **
   ** save the position of the window
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @version	0.6.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    AnnouncementInfo::save_position()
    {
      // Note: 'Gtk::Window::get_position()' does not give the actual position
      this->get_window()->get_root_origin(this->position_x, this->position_y);

      return ;
    } // void AnnouncementInfo::save_position()

  /**
   **
   ** move the window to the last position
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @version	0.6.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    AnnouncementInfo::move_to_last_position()
    {
      if (this->position_x != INT_MAX)
	this->move(this->position_x, this->position_y);

      return ;
    } // void AnnouncementInfo::move_to_last_position()

} // namespace UI_GTKMM_NS

#endif // #ifdef USE_UI_GTKMM
