/**********************************************************************
 *
 *   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 "aiconfig.h"
#include "aiconfigs.h"
#include "players.h"
#include "player.h"
#include "gtk_gui.h"
#include "../../party/party.h"
#include "../../misc/setting.h"
#include "../../misc/language.h"
#include "../../utils/file.h"

namespace GTK_DOKO {

  /**
   **
   ** Constructor
   **
   ** @param	aiconfigs	all aiconfigs
   ** @param	player_config	the corresponding player configuration
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  PartySettings::Players::AiConfigs::AiConfig::AiConfig(PartySettings::Players::AiConfigs* const aiconfigs,
							PartySettings::Players::Player* const player_config) :
    aiconfigs_(aiconfigs),
  player_config_(player_config),
  container(gtk_vbox_new(FALSE, 0)),
  notebook_(gtk_notebook_new()),
  button_hardcoded(gtk_button_new_with_label("hardcoded aiconfig")),
  button_load(gtk_button_new_with_label("load aiconfig")),
  button_save(gtk_button_new_with_label("save aiconfig")),
  file_selection_save(gtk_file_selection_new("save aiconfig")),
  button_adopt(gtk_button_new_with_label("adopt aiconfig")),
  button_allot(gtk_button_new_with_label("allot aiconfig")),
  aitype_(),
  bool_(),
  unsigned_(),
  label_()
  {
    DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_INIT,
		  "PartySettings::Players::AiConfig::AiConfig()");

    gtk_file_selection_set_filename(GTK_FILE_SELECTION(this->file_selection_save),
				    (::setting(Setting::PRIVATE_DATA_DIRECTORY)
				     + "/"
				     + ::setting(Setting::AI_DIRECTORY)
				     + "/"
				    ).c_str());

    for (int t = AITYPE::AITYPE_FIRST; t <= AITYPE::AITYPE_LAST; t++) {
      if (this->aitype_.empty())
	this->aitype_.push_back(new XGtkRadioButton(::name(AiType(t))));
      else
	this->aitype_.push_back(new XGtkRadioButton(*(this->aitype_.front()),
						    ::name(AiType(t))));
      gtk_object_set_data(GTK_OBJECT(this->aitype_.back()->button()), "type",
			  new int(t));
    } // for (t \in Aiconfig::BOOL)
    for (int t = Aiconfig::BOOL_FIRST; t <= Aiconfig::BOOL_LAST; t++) {
      this->bool_.push_back(new XGtkCheckButton(::name(Aiconfig::TypeBool(t))));
      gtk_object_set_data(GTK_OBJECT(this->bool_.back()->button()), "type",
			  new int(t));
    } // for (t \in Aiconfig::BOOL)
    for (int t = Aiconfig::UNSIGNED_FIRST; t <= Aiconfig::UNSIGNED_LAST; t++) {
      this->unsigned_.push_back(new XGtkLabelSpinbutton(::name(Aiconfig::TypeUnsigned(t))));
      gtk_object_set_data(GTK_OBJECT(this->unsigned_.back()->adjustment_widget()), "type",
			  new int(t));
    } // for (t \in Aiconfig::UNSIGNED)

    { // the file buttons
      GtkWidget* container = gtk_table_new(3, 2, TRUE);

      gtk_table_attach_defaults(GTK_TABLE(container),
				this->button_hardcoded,
				0, 2, 0, 1);
      gtk_table_attach_defaults(GTK_TABLE(container),
				this->button_load,
				0, 1, 2, 3);
      gtk_table_attach_defaults(GTK_TABLE(container),
				this->button_save,
				1, 2, 2, 3);
      gtk_table_attach_defaults(GTK_TABLE(container),
				this->button_adopt,
				0, 1, 1, 2);
      gtk_table_attach_defaults(GTK_TABLE(container),
				this->button_allot,
				1, 2, 1, 2);

      gtk_box_pack_end(GTK_BOX(this->container),
		       container,
		       FALSE, TRUE, 0);
    } // the file buttons
    gtk_box_pack_start(GTK_BOX(this->container),
		       this->notebook_,
		       TRUE, TRUE, 0);

#ifndef POSTPHONED
    // ***ToDo DK
    // the entry of the spin button should be great enough to contain eight digits
    gtk_widget_set_usize(this->button(Aiconfig::FUTURE_LIMIT).adjustment_widget(),
			 100, 0);
#endif

    { // add pages of the notebook
      GtkWidget* alignment;
      GtkWidget* container;

      { // simple settings
	container = gtk_vbox_new(FALSE, 20);

	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::TRUSTING).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::FAIRPLAYHANDS).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::FAIRPLAYTEAMS).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::REMEMBERTRICKS).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::FUTURE_LIMIT).widget());

	gtk_container_set_border_width(GTK_CONTAINER(container), 20);

	alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
	gtk_container_add(GTK_CONTAINER(alignment), container);
	this->label_.push_back(new XGtkLabel("simple"));
	gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook_),
				 alignment,
				 this->label_.back()->label());
      } // simple settings

      { // aitype
	container = gtk_vbox_new(FALSE, 20);

	for (int t = AITYPE::AITYPE_FIRST + 1; t <= AITYPE::AITYPE_LAST; t++)
#ifdef RELEASE
	  if (t != AITYPE::GAMETREE_WITH_HEURISTICS)
#endif
	    gtk_container_add(GTK_CONTAINER(container),
			      this->aitype_[t]->widget());

	gtk_container_set_border_width(GTK_CONTAINER(container), 20);

	alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
	gtk_container_add(GTK_CONTAINER(alignment), container);
	this->label_.push_back(new XGtkLabel("aitype"));
	gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook_),
				 alignment,
				 this->label_.back()->label());
      } // aitype

      { // announcement
	container = gtk_vbox_new(FALSE, 20);

	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::ANNOUNCELIMIT).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::ANNOUNCELIMITDEC).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::ANNOUNCECONFIG).widget());

	gtk_container_set_border_width(GTK_CONTAINER(container), 20);

	alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
	gtk_container_add(GTK_CONTAINER(alignment), container);
	this->label_.push_back(new XGtkLabel("announcement"));
	gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook_),
				 alignment,
				 this->label_.back()->label());
      } // announcement

      { // trick decision
	container = gtk_vbox_new(FALSE, 20);

	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::LASTHEURISTICTRICK).widget());

	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::LIMITQUEEN).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::LIMITDOLLE).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::FEHLCREATIONONFIRSTCARD).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::LASTFEHLCREATION).widget());

	gtk_container_set_border_width(GTK_CONTAINER(container), 20);

	alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
	gtk_container_add(GTK_CONTAINER(alignment), container);
	this->label_.push_back(new XGtkLabel("trick decision"));
	gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook_),
				 alignment,
				 this->label_.back()->label());
      } // trick decision

      { // game decision
	container = gtk_vbox_new(FALSE, 20);

	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::TAKEPOVERTY).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::SINGLESOLO).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::DOUBLESOLO).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::TRIPLESOLO).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::COLORSOLO).widget());
	gtk_container_add(GTK_CONTAINER(container),
			  this->button(Aiconfig::MEATLESS).widget());

	gtk_container_set_border_width(GTK_CONTAINER(container), 20);

	alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
	gtk_container_add(GTK_CONTAINER(alignment), container);
	this->label_.push_back(new XGtkLabel("game decision"));
	gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook_),
				 alignment,
				 this->label_.back()->label());
      } // game decision

      { // the heuristics
	GtkWidget* notebook = gtk_notebook_new();

	{ // normal
	  container = gtk_vbox_new(FALSE, 0);

	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::CHOOSE_ACE).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::CHOOSE_FOR_COLOR_TRICK).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::CHOOSE_PFUND).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::JAB_FOR_ACE).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::CREATE_FEHL).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::BEST_WINNING).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::LOW_HIGH).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::PLAY_FOR_TEAM).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::JAB_FOX).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::DRAW_TRUMP).widget());

	  alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
	  gtk_container_add(GTK_CONTAINER(alignment), container);
	  this->label_.push_back(new XGtkLabel("normal game"));
	  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
				   alignment,
				   this->label_.back()->label());
	} // normal

	{ // color solo
	  container = gtk_vbox_new(FALSE, 0);

	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::COLOR_CHOOSE_ACE).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::COLOR_BEST_WINNING).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::COLOR_JAB_FOR_ACE).widget());
	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::COLOR_LOW_HIGH).widget());

	  alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
	  gtk_container_add(GTK_CONTAINER(alignment), container);
	  this->label_.push_back(new XGtkLabel("color solo"));
	  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
				   alignment,
				   this->label_.back()->label());
	} // color solo

	{ // picture solo
	  container = gtk_vbox_new(FALSE, 0);

	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::PICTURE_SECONDBESTTRUMP).widget());

	  alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
	  gtk_container_add(GTK_CONTAINER(alignment), container);
	  this->label_.push_back(new XGtkLabel("picture solo"));
	  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
				   alignment,
				   this->label_.back()->label());
	} // picture solo

	{ // meatless solo
	  container = gtk_vbox_new(FALSE, 0);

	  gtk_container_add(GTK_CONTAINER(container),
			    this->button(Aiconfig::MEATLESS_PLAYHIGHESTCOLOR).widget());

	  alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
	  gtk_container_add(GTK_CONTAINER(alignment), container);
	  this->label_.push_back(new XGtkLabel("meatless solo"));
	  gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
				   alignment,
				   this->label_.back()->label());
	} // meatless solo

	//      alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
	// gtk_container_add(GTK_CONTAINER(alignment), container);
	this->label_.push_back(new XGtkLabel("heuristics"));
	gtk_notebook_append_page(GTK_NOTEBOOK(this->notebook_),
				 notebook,
				 this->label_.back()->label());

      } // the heuristics

    } // add pages of the player-notebook

#ifndef RELEASE
#ifdef DKNOF
    { // test, whether all rules-buttons are packed in a container
      unsigned i;
      for (i = Aiconfig::BOOL_FIRST; i <= Aiconfig::BOOL_LAST; i++) {
	if (this->button(Aiconfig::TypeBool(i)).widget()->parent == NULL)
	  cerr << "GTK_DOKO::AiConfig::create():\n"
	    << "  configuration '" << name(Aiconfig::TypeBool(i))
	    << "' not packed\n";
      }
      for (i = Aiconfig::UNSIGNED_FIRST; i <= Aiconfig::UNSIGNED_LAST; i++) {
	if (this->button(Aiconfig::TypeUnsigned(i)).widget()->parent == NULL)
	  cerr << "GTK_DOKO::AiConfig::create():\n"
	    << "  configuration '" << name(Aiconfig::TypeUnsigned(i))
	    << "' not packed\n";
      }
    } // test, whether all rule-buttons are packed in a container
#endif // #ifdef DKNOF
#endif // #ifndef RELEASE

    gtk_signal_connect(GTK_OBJECT(this->button_hardcoded),
		       "clicked",
		       GTK_SIGNAL_FUNC(AiConfig::hardcoded_select_event),
		       gpointer(this));
    gtk_signal_connect(GTK_OBJECT(this->button_load),
		       "clicked",
		       GTK_SIGNAL_FUNC(AiConfig::load_select_event),
		       gpointer(this));
    gtk_signal_connect(GTK_OBJECT(this->button_save),
		       "clicked",
		       GTK_SIGNAL_FUNC(GTK_GUI::window_show),
		       gpointer(this->file_selection_save));
    gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(this->file_selection_save)->ok_button),
		       "clicked",
		       GTK_SIGNAL_FUNC(AiConfig::save_event),
		       gpointer(this));
    gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(this->file_selection_save)->ok_button),
		       "clicked",
		       GTK_SIGNAL_FUNC(GTK_GUI::window_hide),
		       gpointer(this->file_selection_save));
    gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(this->file_selection_save)->cancel_button),
		       "clicked",
		       GTK_SIGNAL_FUNC(GTK_GUI::window_hide),
		       gpointer(this->file_selection_save));

    gtk_signal_connect(GTK_OBJECT(this->button_adopt),
		       "clicked",
		       GTK_SIGNAL_FUNC(AiConfig::adopt_select_event),
		       gpointer(this));
    gtk_signal_connect(GTK_OBJECT(this->button_allot),
		       "clicked",
		       GTK_SIGNAL_FUNC(AiConfig::allot_event),
		       gpointer(this));

    // set the events for  the changing
    for (int t = AITYPE::AITYPE_FIRST; t <= AITYPE::AITYPE_LAST; t++)
      gtk_signal_connect(GTK_OBJECT(this->aitype_[t]->button()),
			 "toggled",
			 GTK_SIGNAL_FUNC(PartySettings::Players::AiConfigs::AiConfig::aitype_change_event),
			 gpointer(this));

    for (int t = Aiconfig::BOOL_FIRST; t <= Aiconfig::BOOL_LAST; t++)
      gtk_signal_connect(GTK_OBJECT(this->button(static_cast<Aiconfig::TypeBool>(t)).button()),
			 "toggled",
			 GTK_SIGNAL_FUNC(PartySettings::Players::AiConfigs::AiConfig::change_event),
			 gpointer(this));
    for (int t = Aiconfig::UNSIGNED_FIRST; t <= Aiconfig::UNSIGNED_LAST; t++)
      gtk_signal_connect(GTK_OBJECT(this->button(static_cast<Aiconfig::TypeUnsigned>(t)).adjustment_widget()),
			 "changed",
			 GTK_SIGNAL_FUNC(PartySettings::Players::AiConfigs::AiConfig::change_event),
			 gpointer(this));

    gtk_widget_show_all(this->widget());

    DEBUG_RETURNING(VOID,
		    INFO_GTK_AICONFIG && INFO_GTK_INIT,
		    "PartySettings::Players::AiConfig::AiConfig()");
  } // PartySettings::Players::AiConfigs::AiConfig::AiConfig(PartySettings::Players::Player* player)

  /**
   **
   ** Destruktor:
   ** nothing to do
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  PartySettings::Players::AiConfigs::AiConfig::~AiConfig()
  {
    DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_INIT,
		  "PartySettings::Players::AiConfig::~AiConfig()");

    gtk_widget_destroy(this->notebook_);
    this->notebook_ = NULL;

    this->aitype_.clear();
    this->bool_.clear();
    this->unsigned_.clear();
    this->label_.clear();

    DEBUG_RETURNING(VOID,
		    INFO_GTK_AICONFIG && INFO_GTK_INIT,
		    "PartySettings::Players::AiConfig::~AiConfig()");
  } // PartySettings::Players::AiConfigs::AiConfig::~AiConfig()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the aiconfig of all players
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.3
   **
   **/
  PartySettings::Players::AiConfigs&
    PartySettings::Players::AiConfigs::AiConfig::aiconfigs()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		    "PartySettings::Players::AiConfigs::AiConfig::aiconfigs()");

      DEBUG_RETURNING(*(this->aiconfigs_),
		      INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		      "PartySettings::Players::AiConfigs::AiConfig::aiconfigs()");
    } // PartySettings::Players::AiConfigs& PartySettings::Players::AiConfigs::AiConfig::aiconfigs()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the player configuration
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  PartySettings::Players::Player&
    PartySettings::Players::AiConfigs::AiConfig::player_config()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		    "PartySettings::Players::AiConfigs::AiConfig::player_config()");

      DEBUG_RETURNING(*(this->player_config_),
		      INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		      "PartySettings::Players::AiConfigs::AiConfig::player_config()");
    } // PartySettings::Players::Player& PartySettings::Players::AiConfigs::AiConfig::player_config()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the corresponding player
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  ::Player&
    PartySettings::Players::AiConfigs::AiConfig::player()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		    "PartySettings::Players::AiConfigs::AiConfig::player()");

      DEBUG_RETURNING(this->player_config().player(),
		      INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		      "PartySettings::Players::AiConfigs::AiConfig::player()");
    } // ::Player& PartySettings::Players::AiConfigs::AiConfig::player()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the player configuration
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  ::Aiconfig&
    PartySettings::Players::AiConfigs::AiConfig::aiconfig()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		    "PartySettings::Players::AiConfigs::AiConfig::aiconfig()");

      DEBUG_RETURNING(dynamic_cast<Aiconfig&>(this->player()),
		      INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		      "PartySettings::Players::AiConfigs::AiConfig::aiconfig()");
    } // ::Aiconfig& PartySettings::Players::AiConfigs::AiConfig::aiconfig()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the widget
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.3
   **
   **/
  GtkWidget*
    PartySettings::Players::AiConfigs::AiConfig::widget()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		    "PartySettings::Players::AiConfigs::AiConfig::widget()");

      DEBUG_RETURNING(this->container,
		      INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		      "PartySettings::Players::AiConfigs::AiConfig::widget()");
    } // GtkWidget* PartySettings::Players::AiConfigs::AiConfig::widget()

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the button for 'type'
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  XGtkCheckButton&
    PartySettings::Players::AiConfigs::AiConfig::button(Aiconfig::TypeBool const type)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		    "PartySettings::Players::AiConfigs::AiConfig::button(TypeBool)");

      DEBUG_RETURNING(*(this->bool_[type - Aiconfig::BOOL_FIRST]),
		      INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		      "PartySettings::Players::AiConfigs::AiConfig::button(TypeBool)");
    } // XGtkCheckButton& PartySettings::Players::AiConfigs::AiConfig::button(Aiconfig::TypeBool const type)

  /**
   **
   ** -> result
   **
   ** @param	-
   **
   ** @return	the button for 'type'
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  XGtkLabelAdjustment&
    PartySettings::Players::AiConfigs::AiConfig::button(Aiconfig::TypeUnsigned const type)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		    "PartySettings::Players::AiConfigs::AiConfig::button(TypeUnsigned)");

      DEBUG_RETURNING(*(this->unsigned_[type - Aiconfig::UNSIGNED_FIRST]),
		      INFO_GTK_AICONFIG && INFO_GTK_VALUE,
		      "PartySettings::Players::AiConfigs::AiConfig::button(TypeUnsigned)");
    } // XGtkLabelAdjustment& PartySettings::Players::AiConfigs::AiConfig::button(Aiconfig::TypeUnsigned const type)

  /**
   **
   ** the aitype has changed
   **
   ** @param	widget		the widget that has changed
   ** @param	aiconfig	the aiconfig
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::aitype_change_event(GtkWidget* widget,
								     gpointer aiconfig)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::change_event()");

      static_cast<PartySettings::Players::AiConfigs::AiConfig*>(aiconfig)->aitype_change(*(static_cast<int*>(gtk_object_get_data(GTK_OBJECT(widget), "type"))));

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::aitype_change_event()");
    } // static void PartySettings::Players::AiConfigs::AiConfig::aitype_change_event(GtkWidget* widget, gpointer aiconfig)

  /**
   **
   ** the widget has changed
   **
   ** @param	widget		the widget that has changed
   ** @param	aiconfig	the aiconfig
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::change_event(GtkWidget* widget,
							      gpointer aiconfig)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::change_event()");

      static_cast<PartySettings::Players::AiConfigs::AiConfig*>(aiconfig)->change(*(static_cast<int*>(gtk_object_get_data(GTK_OBJECT(widget), "type"))));

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::change_event()");
    } // static void PartySettings::Players::AiConfigs::AiConfig::change_event(GtkWidget* widget, gpointer aiconfig)

  /**
   **
   ** the aitype has changed
   **
   ** @param	type		the aitype, that has changed
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::aitype_change(int const type)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::aitype_change(type)");

      if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(this->aitype_[type]->button()))
	  == TRUE)
	this->aiconfig().aitype_set(AiType(type));

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::aitype_change(type)");
    } // void PartySettings::Players::AiConfigs::AiConfig::aitype_change(int const type)

  /**
   **
   ** a configuration has changed
   **
   ** @param	type		the config type, that has changed
   **
   ** @return	-
   ** 
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::change(int const type)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::change(type)");

      if ( (type >= Aiconfig::BOOL_FIRST)
	   && (type <= Aiconfig::BOOL_LAST) ) {
	this->aiconfig().set(static_cast<Aiconfig::TypeBool>(type),
			     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(this->button(static_cast<Aiconfig::TypeBool>(type)).button()))
			    );
      } else if ( (type >= Aiconfig::UNSIGNED_FIRST)
		  && (type <= Aiconfig::UNSIGNED_LAST) ) {
	this->aiconfig().set(static_cast<Aiconfig::TypeUnsigned>(type),
			     this->button(static_cast<Aiconfig::TypeUnsigned>(type)).value());
      } else { // if !(type == bool, unsigned)
	DEBUG_ASSERTION(false,
			"PartySettings::Players::AiConfigs::AiConfig::change(type):\n"
			"typenumber " << type << " not valid");
      } // if !(type == bool, unsigned)

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::change(type)");
    } // void PartySettings::Players::AiConfigs::AiConfig::change(int const type)

  /**
   **
   ** update the senisitivity
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @version	0.5.3
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::sensitivity_update()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_UPDATE,
		    "PartySettings::Players::AiConfigs::AiConfig::sensitivity_update()");

      bool sensitivity = (::game_status == GAMESTATUS::PARTY_INIT);

      // the user can always save the aiconfig
      gtk_widget_set_sensitive(this->button_hardcoded, sensitivity);
      gtk_widget_set_sensitive(this->button_load, sensitivity);
      gtk_widget_set_sensitive(this->button_adopt, sensitivity);
      gtk_widget_set_sensitive(this->button_allot, sensitivity);

      for (vector<XGtkRadioButton*>::iterator button = this->aitype_.begin();
	   button != this->aitype_.end();
	   button++)
	gtk_widget_set_sensitive((*button)->widget(), sensitivity);
      for (vector<XGtkCheckButton*>::iterator button = this->bool_.begin();
	   button != this->bool_.end();
	   button++)
	gtk_widget_set_sensitive((*button)->widget(), sensitivity);
      for (vector<XGtkLabelAdjustment*>::iterator
	   button = this->unsigned_.begin();
	   button != this->unsigned_.end();
	   button++)
	gtk_widget_set_sensitive((*button)->widget(), sensitivity);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_UPDATE,
		      "PartySettings::Players::AiConfigs::AiConfig::sensitivity_update()");
    } // void PartySettings::Players::sensitivity_update()

  /**
   **
   ** update the aiconfig
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.3
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::update()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_INIT,
		    "PartySettings::Players::AiConfig::update()");

      gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(this->aitype_[this->aiconfig().aitype()]->button()),
				   TRUE);

      for (int i = Aiconfig::BOOL_FIRST; i <= Aiconfig::BOOL_LAST; i++)
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(this->button(Aiconfig::TypeBool(i)).button()),
				     (this->aiconfig().value(Aiconfig::TypeBool(i))
				      ? TRUE
				      : FALSE));

      for (int i = Aiconfig::UNSIGNED_FIRST; i <= Aiconfig::UNSIGNED_LAST; i++) {
	this->button(Aiconfig::TypeUnsigned(i)).minmax_set(this->aiconfig().min(Aiconfig::TypeUnsigned(i)),
							   this->aiconfig().max(Aiconfig::TypeUnsigned(i)));
	this->button(Aiconfig::TypeUnsigned(i)).value_set(this->aiconfig().value(Aiconfig::TypeUnsigned(i)));
      } // for (i = Aiconfig::UNSIGNED)

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_INIT,
		      "PartySettings::Players::AiConfig::update()");
    } // PartySettings::Players::AiConfigs::AiConfig::update()

  /**
   **
   ** Event: the hardcoded aiconfig shall be used
   **
   ** @param	aiconfigs	the aiconfigs
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::hardcoded_select_event(GtkWidget*, gpointer aiconfig)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::hardcoded_select_event()");

      static_cast<AiConfig*>(aiconfig)->hardcoded_get();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::hardcoded_select_event()");
    } // void PartySettings::Players::AiConfigs::AiConfig::hardcoded_select_event(GtkWidget*, gpointer aiconfig)

  /**
   **
   ** the hardcoded aiconfig shall be used
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::hardcoded_get()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::hardcoded_get()");

      this->aiconfig().reset_to_hardcoded();
      this->update();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::hardcoded_get()");
    } // void PartySettings::Players::AiConfigs::AiConfig::hardcoded_get()

  /**
   **
   ** Event: aiconfigs shall be loaded.
   ** Create a menu with all aiconfigs in the public and private data
   ** directories (see settings).
   **
   ** @param	aiconfigs	the aiconfigs
   **
   ** @return	-
   **
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::load_select_event(GtkWidget*, gpointer aiconfig)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::load_select_event()");

      GtkWidget* menu = gtk_menu_new();
      gtk_menu_prepend(GTK_MENU(menu), gtk_tearoff_menu_item_new());
      gtk_signal_connect(GTK_OBJECT(menu), "deactivate",
			 GTK_SIGNAL_FUNC(PartySettings::Players::AiConfigs::AiConfig::menu_destroy), NULL);
      gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0);
      gtk_widget_show_all(menu);
      static_cast<AiConfig*>(aiconfig)->load_menu_create(menu);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::load_select_event()");
    } // void PartySettings::Players::AiConfigs::AiConfig::load_select_event(GtkWidget*, gpointer aiconfig)

  /**
   **
   ** creates the menu for the loading of the aiconfigs
   **
   ** @param	menu		the menu where the entries are created
   ** @param	directory	the directory which is searched
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   ** @todo	sorting the entries
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::load_menu_create(GtkWidget* menu)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_UPDATE,
		    "PartySettings::Players::AiConfigs::AiConfig::load_menu_create()");

#ifndef WINDOWS
      gdk_window_set_cursor(menu->window,
			    gdk_cursor_new(GDK_WATCH));
#endif // #ifndef WINDOWS

      // read the whole directory tree
      // first take the private and then the public styles
#if 0
      this->load_menu_add_subdir(menu,
				 ".",
				 "",
				 0,
				 type);
#endif
      this->load_menu_add_subdir(menu,
				 ::setting(Setting::PRIVATE_DATA_DIRECTORY)
				 + "/"
				 + ::setting(Setting::AI_DIRECTORY),
				 "",
				 0);
      // add a separator between the private and public elements
      GtkWidget* separator = gtk_menu_item_new();
      gtk_widget_show(separator);
      gtk_menu_append(GTK_MENU(menu), separator);

      this->load_menu_add_subdir(menu,
				 ::setting(Setting::PUBLIC_DATA_DIRECTORY)
				 + "/"
				 + ::setting(Setting::AI_DIRECTORY),
				 "",
				 0);

#ifndef WINDOWS
      gdk_window_set_cursor(menu->window, NULL);
#endif // #ifndef WINDOWS

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_UPDATE,
		      "PartySettings::Players::AiConfigs::AiConfig::load_menu_create()");
    } // void PartySettings::Players::AiConfigs::AiConfig::load_menu_create(GtkWidget* menu)

  /**
   **
   ** adds all subdirs from 'directory' with style information to 'menu'
   **
   ** @param	menu		the menu where the entries are added
   ** @param	main_directory	the main directory (public/private data)
   ** @param	directory	the subdirectory which is searched
   ** @param	depth		the depth in the directory structure
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   ** @todo	test, whether it is a valid rule file
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::load_menu_add_subdir(GtkWidget* menu,
								      string const& main_directory,
								      string const& directory,
								      unsigned const depth)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_UPDATE,
		    "PartySettings::Players::AiConfigs::AiConfig::load_menu_add_subdir(menu, main_directory, style, depth)");

#ifdef OUTDATED
      if (depth == ::setting(Setting::DIRECTORY_SEARCH_DEPTH))
#else
      if (depth == 5)
#endif
	DEBUG_RETURNING(VOID,
			INFO_GTK_AICONFIG && INFO_GTK_UPDATE,
			"PartySettings::Players::AiConfigs::AiConfig::load_menu_add_subdir(menu, main_directory, style, depth)");

      DIR *dir = opendir((main_directory + "/" + directory).c_str());
      if (dir == NULL) {
	DEBUG_RETURNING(VOID,
			INFO_GTK_AICONFIG && INFO_GTK_UPDATE,
			"PartySettings::Players::AiConfigs::AiConfig::load_menu_add_subdir():\n"
			"  can not open");
      }

      // number of entries
      unsigned n = g_list_length(gtk_container_children(GTK_CONTAINER(menu)));
      GtkWidget* creating_space
	= gtk_menu_item_new();
      GtkWidget* creating_label
	= gtk_menu_item_new_with_label(::language("creating").c_str());
      if (depth == 0) {
	// add the label to the menu
	gtk_widget_show(creating_space);
	gtk_widget_show(creating_label);
	gtk_widget_set_sensitive(creating_label, FALSE);
	gtk_menu_append(GTK_MENU(menu), creating_space);
	gtk_menu_append(GTK_MENU(menu), creating_label);
      }

      // search all entries in the directory
      struct dirent *entry;
      while ((entry = readdir(dir)) != NULL) {
	if ((strcmp(entry->d_name, ".") == 0) ||
	    (strcmp(entry->d_name, "..") == 0))
	  continue;
#ifdef LINUX
	if ((entry->d_type == DT_DIR)
	    || (entry->d_type == DT_LNK))
	  // the entry is a directory
#else // #ifdef LINUX
	  ;
	if (DK::Utils::File::isdirectory(main_directory
					 + "/" + directory
					 + "/" + entry->d_name))
#endif // #ifdef LINUX
	{
	  // search the subdirectory
	  GtkWidget* submenu = gtk_menu_new();
	  this->load_menu_add_subdir(submenu,
				     main_directory,
				     (directory.empty()
				      ? string()
				      : string(directory + "/"))
				     + entry->d_name,
				     depth + 1);

	  if (g_list_length(gtk_container_children(GTK_CONTAINER(submenu)))
	      > 0) {
	    // there are entries in the menu
	    gtk_menu_set_title(GTK_MENU(submenu),
			       (directory + "/" + entry->d_name).c_str());
	    gtk_menu_prepend(GTK_MENU(submenu), gtk_tearoff_menu_item_new());
	    GtkWidget* item = gtk_menu_item_new_with_label(entry->d_name);
	    gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);

	    if (depth == 0)
	      gtk_menu_insert(GTK_MENU(menu), item, n);
	    else
	      gtk_menu_append(GTK_MENU(menu), item);
	    n += 1;

	    gtk_widget_show_all(item);
	    this->aiconfigs().players().gui().update();
	  } // if (entries in the menu)
	} else if (DK::Utils::File::isfile(main_directory + "/" + directory
					   + "/" + entry->d_name)) {
	  // add the entry to the menu
	  GtkWidget* item = gtk_menu_item_new_with_label(entry->d_name);
	  gtk_object_set_data(GTK_OBJECT(item), "filename",
			      new string(main_directory
					 + "/" + directory
					 + "/" + entry->d_name));
	  gtk_signal_connect(GTK_OBJECT(item), "activate",
			     GTK_SIGNAL_FUNC(PartySettings::Players::AiConfigs::AiConfig::load_menu_select_event),
			     this);

	  if (depth == 0)
	    gtk_menu_insert(GTK_MENU(menu), item, n);
	  else
	    gtk_menu_append(GTK_MENU(menu), item);
	  n += 1;

	  gtk_widget_show(item);
	  this->aiconfigs().players().gui().update();
	} // if !(entry->d_type == DT_DIR)
      } // while ((entry = readdir(dir)) != NULL)

      closedir(dir);

      // remove the label to the menu
      gtk_widget_destroy(creating_space);
      gtk_widget_destroy(creating_label);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_UPDATE,
		      "PartySettings::Players::AiConfigs::AiConfig::load_menu_add_subdir(menu, main_directory, directory, depth)");
    } // void PartySettings::Players::AiConfigs::AiConfig::load_menu_add_subdir(GtkWidget* menu, string const& main_directory, string const& directory, unsigned const depth)

  /**
   **
   ** a file is selected
   **
   ** @param	menu_item	the menu item clicked
   ** @param	aiconfig		the aiconfigs
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::load_menu_select_event(GtkWidget* menu_item,
									gpointer aiconfig)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::aiconfigs_menu_select_event(menu_item, aiconfig)");

      static_cast<AiConfig*>(aiconfig)->load(*(static_cast<string*>(gtk_object_get_data(GTK_OBJECT(menu_item), "filename"))));

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::settings_menu_select_event(menu_item, aiconfig)");
    } // static void PartySettings::Players::AiConfigs::AiConfig::settings_menu_select_event(GtkWidget* menu_item, gpointer aiconfig)

  /**
   **
   ** destroy the menu
   **
   ** @param	menu		the menu that is destroyed
   ** @param	-	
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.4
   **
   ** @todo	validate, that here is no memory leak
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::menu_destroy(GtkWidget* menu, gpointer)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::menu_destroy(menu, gpointer)");

#if 0
      // is the widget destroyed automatic?
      gtk_widget_destroy(widget);
#endif

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::menu_destroy(menu, gpointer)");
    } // static void PartySettings::Players::AiConfigs::AiConfig::menu_destroy(GtkWidget* menu, gpointer)

  /**
   **
   ** load the aiconfigs
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::load(string const& filename)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::load(filename)");

      this->aiconfig().load(filename);
      this->update();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::load(filename)");
    } // void PartySettings::Players::AiConfigs::AiConfig::load(string const& filename)

  /**
   **
   ** event: the aiconfig shall be saved
   **
   ** @param	aiconfig	the aiconfig
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::save_event(GtkWidget* widget,
							    gpointer aiconfig)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::save_event(aiconfig)");

      static_cast<AiConfig*>(aiconfig)->save();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::save_event(aiconfig)");
    } // void PartySettings::Players::AiConfigs::AiConfig::save_event(GtkWidget*, gpointer aiconfig)

  /**
   **
   ** save the aiconfigs
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::save()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::save()");

      string filename = gtk_file_selection_get_filename(GTK_FILE_SELECTION(this->file_selection_save));

      if (!this->aiconfig().save(filename))
	cerr << "Could not save aiconfig in file '" << filename << "'" << endl;

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::save()");
    } // void PartySettings::Players::AiConfigs::AiConfig::save()

  /**
   **
   ** event: an aiconfig to adopt shall be selected
   **
   ** @param	aiconfig	the aiconfig
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::adopt_select_event(GtkWidget*,
								    gpointer aiconfig)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::adopt_select_event(aiconfig)");

      static_cast<AiConfig*>(aiconfig)->adopt_select();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::adopt_select_event(aiconfig)");
    } // void PartySettings::Players::AiConfigs::AiConfig::adopt_select_event(GtkWidget*, gpointer aiconfig)

  /**
   **
   ** create a menu to select a aiconfig to adopt
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::adopt_select()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::adopt_select()");

      GtkWidget* menu = gtk_menu_new();
      gtk_menu_prepend(GTK_MENU(menu), gtk_tearoff_menu_item_new());
      gtk_signal_connect(GTK_OBJECT(menu), "deactivate",
			 GTK_SIGNAL_FUNC(PartySettings::Players::AiConfigs::AiConfig::menu_destroy), NULL);
      gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0);
      for (unsigned p = 0; p < ::party.playerno(); p++) {
	if (p != this->player().no()) {
	  GtkWidget* item = gtk_menu_item_new_with_label(::party.player(p).name().c_str());
	  gtk_object_set_data(GTK_OBJECT(item), "aiconfig",
			      static_cast<gpointer>(&(this->aiconfigs().aiconfig(p).aiconfig())));
	  gtk_signal_connect(GTK_OBJECT(item), "activate",
			     GTK_SIGNAL_FUNC(PartySettings::Players::AiConfigs::AiConfig::adopt_event),
			     this);
	  gtk_menu_append(GTK_MENU(menu), item);
	} // if (p != this->player().no())
      } // for (p < ::party.playerno())
      gtk_widget_show_all(menu);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::adopt_select()");
    } // void PartySettings::Players::AiConfigs::AiConfig::adopt_select()

  /**
   **
   ** event: adopt an aiconfig
   **
   ** @param	widget		widget of the event
   ** @param	aiconfig	the aiconfig
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::adopt_event(GtkWidget* widget,
							     gpointer aiconfig)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::adopt_event(aiconfig)");

      static_cast<AiConfig*>(aiconfig)->adopt(*(static_cast<Aiconfig*>(gtk_object_get_data(GTK_OBJECT(widget), "aiconfig"))));

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::adopt_event(aiconfig)");
    } // void PartySettings::Players::AiConfigs::AiConfig::adopt_event(GtkWidget* widget, gpointer aiconfig)

  /**
   **
   ** atopt the aiconfig
   **
   ** @param	aiconfig	aiconfig to adopt
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::adopt(::Aiconfig const& aiconfig)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::adopt(aiconfig)");

      this->aiconfig() = aiconfig;
      this->update();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::adopt(aiconfig)");
    } // void PartySettings::Players::AiConfigs::AiConfig::adopt(::Aiconfig const& aiconfig)

  /**
   **
   ** event: the aiconfig will be alloted to all aiconfigs
   **
   ** @param	aiconfig	the aiconfig
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::allot_event(GtkWidget*,
							     gpointer aiconfig)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::allot_event(aiconfig)");

      static_cast<AiConfig*>(aiconfig)->allot();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::allot_event(aiconfig)");
    } // void PartySettings::Players::AiConfigs::AiConfig::allot_event(GtkWidget*, gpointer aiconfig)

  /**
   **
   ** allot the aiconfig to all players
   **
   ** @param	-
   **
   ** @return	-
   **
   ** @version	0.5.4
   **
   ** @author	Diether Knof
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::allot()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		    "PartySettings::Players::AiConfigs::AiConfig::allot()");

      for (unsigned p = 0; p < ::party.playerno(); p++) {
	this->aiconfigs().aiconfig(p).aiconfig() = this->aiconfig();
	this->aiconfigs().aiconfig(p).update();
      } // for (p < ::party.playerno())

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_EVENT,
		      "PartySettings::Players::AiConfigs::AiConfig::allot()");
    } // void PartySettings::Players::AiConfigs::AiConfig::allot()

  /**
   **
   ** updates the language of all elements
   **
   ** @param	-
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::language_update()
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_UPDATE,
		    "PartySettings::Players::AiConfigs::AiConfig::language_update()");

      gtk_label_set_text(GTK_LABEL(GTK_BIN(this->button_hardcoded)->child),
			 (" " + ::language("hardcoded") + " ").c_str());
      gtk_label_set_text(GTK_LABEL(GTK_BIN(this->button_load)->child),
			 (" " + ::language("load") + " ").c_str());
      gtk_label_set_text(GTK_LABEL(GTK_BIN(this->button_save)->child),
			 (" " + ::language("save") + " ").c_str());
      gtk_window_set_title(GTK_WINDOW(this->file_selection_save),
			   (::language("save") + " ("
			    + this->player().name() + ")").c_str());
      gtk_label_set_text(GTK_LABEL(GTK_BIN(this->button_adopt)->child),
			 (" " + ::language("adopt") + " ").c_str());
      gtk_label_set_text(GTK_LABEL(GTK_BIN(this->button_allot)->child),
			 (" " + ::language("allot") + " ").c_str());

      for (int t = AITYPE::AITYPE_FIRST; t <= AITYPE::AITYPE_LAST; t++)
	this->aitype_[t]->language_update();
      for (int i = Aiconfig::BOOL_FIRST; i <= Aiconfig::BOOL_LAST; i++)
	this->button(Aiconfig::TypeBool(i)).language_update();
      for (int i = Aiconfig::UNSIGNED_FIRST; i <= Aiconfig::UNSIGNED_LAST; i++)
	this->button(Aiconfig::TypeUnsigned(i)).language_update();

      for (vector<XGtkLabel*>::iterator label = this->label_.begin();
	   label != this->label_.end();
	   label++)
	(*label)->language_update();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_UPDATE,
		      "PartySettings::Players::AiConfigs::AiConfig::language_update()");
    } // void PartySettings::Players::AiConfigs::AiConfig::language_update()


  /**
   **
   ** react to the pressed key
   **
   ** @param	key	the pressed key
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.2
   **
   **/
  void
    PartySettings::Players::AiConfigs::AiConfig::key(GdkEventKey* key)
    {
      DEBUG_CALLING(INFO_GTK_AICONFIG && INFO_GTK_KEY,
		    "PartySettings::Players::AiConfigs::AiConfig::key()");

#include <gdk/gdkkeysyms.h>

      switch (key->keyval) {
#ifndef RELEASE
      case GDK_o: // output of the settings
      case GDK_O:
	cout << this->aiconfig();
	break;
#endif

      default: // pass the key to the dialog
	this->aiconfigs().key(key);
	break;
      } // switch (key->keyval)

      DEBUG_RETURNING(VOID,
		      INFO_GTK_AICONFIG && INFO_GTK_KEY,
		      "PartySettings::Players::AiConfigs::AiConfig::key()");
    } // void PartySettings::Players::AiConfigs::AiConfig::key(GdkKeyEvent);


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