/**********************************************************************
 *
 *   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 "settings.h"
#include "gtk_gui.h"

#include "../../utils/file.h"
#include "../../misc/language.h"

namespace GTK_DOKO {

  /**
   **
   ** destroy the menu
   **
   ** @param	widget		the menu
   ** @param	-	
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   **
   ** @todo	validate, that here is no memory leak
   **
   **/
  void
    Settings::menu_destroy(GtkWidget* widget, gpointer)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::menu_destroy(widget, gpointer)");

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

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::menu_destroy(widget, gpointer)");
    } // void Settings::menu_destroy(GtkWidget* widget, gpointer)

  /**
   **
   ** creates the menu for the selection of the graphic files in 'directory'
   **
   ** @param	menu		the menu where the entries are created
   ** @param	directory	the directory which is searched
   ** @param	type		the setting type
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   ** @todo	sorting the entries
   **
   **/
  void
    Settings::graphic_files_menu_create(GtkWidget* menu,
					string const& directory,
					Setting::TypeString const type)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
		    "Settings::graphic_files_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->graphic_files_menu_add_subdir(menu,
					  ".",
					  "",
					  0,
					  type);
#endif
      this->graphic_files_menu_add_subdir(menu,
					  ::setting(Setting::PRIVATE_DATA_DIRECTORY)
					  + "/"
					  + directory,
					  "",
					  0,
					  type);
      // 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->graphic_files_menu_add_subdir(menu,
					  ::setting(Setting::PUBLIC_DATA_DIRECTORY)
					  + "/"
					  + directory,
					  "",
					  0,
					  type);

      if (::setting(Setting::PUBLIC_DATA_DIRECTORY) != ".") {
	// add a separator between the private and public elements
	separator = gtk_menu_item_new();
	gtk_widget_show(separator);
	gtk_menu_append(GTK_MENU(menu), separator);

	this->graphic_files_menu_add_subdir(menu,
					    "./"
					    + directory,
					    "",
					    0,
					    type);
      } // if (::setting(Setting::PUBLIC_DATA_DIRECTORY) != ".")

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

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
		      "Settings::graphic_files_menu_create()");
    } // void Settings::graphic_files_menu_create(GtkWidget* menu, string const& directory)

  /**
   **
   ** 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
   ** @param	type		the setting type
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::graphic_files_menu_add_subdir(GtkWidget* menu,
					    string const& main_directory,
					    string const& directory,
					    unsigned const depth,
					    Setting::TypeString const type)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
		    "Settings::graphic_files_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_SETTINGS && INFO_GTK_UPDATE,
			"Settings::graphic_files_menu_add_subdir(menu, main_directory, style, depth)");

      DIR *dir = opendir((main_directory + "/" + directory).c_str());
      if (dir == NULL) {
	DEBUG_RETURNING(VOID,
			INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
			"Settings::graphic_files_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->graphic_files_menu_add_subdir(submenu,
					      main_directory,
					      (directory.empty()
					       ? string()
					       : string(directory + "/"))
					      + entry->d_name,
					      depth + 1,
					      type);

	  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->gui().update();
	  } // if (entries in the menu)
	} else if (DK::Utils::File::isfile(main_directory + "/" + directory
					   + "/" + entry->d_name)) {
	  string const file = entry->d_name;
	  if ((file.size() > 1 + ::setting.value(Setting::GRAPHIC_EXTENSION).size())
	      && (string(file,
			 file.size()
			 - 1
			 - ::setting.value(Setting::GRAPHIC_EXTENSION).size(),
			 file.size())
		  == "." + ::setting.value(Setting::GRAPHIC_EXTENSION))) {
	    // found a graphic file
	    string const file_basename = string(file,
						0,
						file.size()
						- 1
						- ::setting.value(Setting::GRAPHIC_EXTENSION).size());
	    // add the entry to the menu
	    GtkWidget*
	      item = gtk_menu_item_new_with_label(file_basename.c_str());
	    if (directory.empty())
	      gtk_object_set_data(GTK_OBJECT(item), "value",
				  new string(file_basename));
	    else
	      gtk_object_set_data(GTK_OBJECT(item), "value",
				  new string(directory + "/" + file_basename)
				 );
	    gtk_object_set_data(GTK_OBJECT(item), "setting",
				new Setting::TypeString(type));
	    gtk_signal_connect(GTK_OBJECT(item), "activate",
			       GTK_SIGNAL_FUNC(Settings::settings_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->gui().update();
	  } // if (is graphics file)
	} // 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_SETTINGS && INFO_GTK_UPDATE,
		      "Settings::graphic_files_menu_add_subdir(menu, main_directory, directory, depth)");
    } // void Setting::graphic_files_menu_add_subdir(GtkWidget* menu, string const& main_directory, string const& directory, unsigned const depth, Setting::TypeString const type)

  /**
   **
   ** a new back of the cards is selected
   **
   ** @param	menu_item	the menu item clicked
   ** @param	settings	the settings
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::settings_menu_select_event(GtkWidget* menu_item,
					 gpointer settings)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::settings_menu_select_event(menu_item, settings)");

      ::setting.set(*(static_cast<Setting::TypeString*>(gtk_object_get_data(GTK_OBJECT(menu_item), "setting"))),
		    *(static_cast<string*>(gtk_object_get_data(GTK_OBJECT(menu_item), "value"))));

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::settings_menu_select_event(menu_item, settings)");
    } // void Settings::settings_menu_select_event(GtkWidget* menu_item, gpointer settings)

  /**
   **
   ** creates the menu for the selection of the cardset
   **
   ** @param	menu	the menu where the entries are created
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   ** @todo	sorting the entries
   **
   **/
  void
    Settings::cardset_menu_create(GtkWidget* menu)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
		    "Settings::cardset_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
      this->cardset_menu_add_subdir(menu,
				    "./"
				    + ::setting(Setting::CARDSETS_DIRECTORY),
				    "",
				    0);
      this->cardset_menu_add_subdir(menu,
				    ::setting(Setting::PRIVATE_DATA_DIRECTORY)
				    + "/"
				    + ::setting(Setting::CARDSETS_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->cardset_menu_add_subdir(menu,
				    ::setting(Setting::PUBLIC_DATA_DIRECTORY)
				    + "/"
				    + ::setting(Setting::CARDSETS_DIRECTORY),
				    "",
				    0);

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

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
		      "Settings::cardset_menu_create()");
    } // void Settings::cardset_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 directory
   ** @param	depth		the depth in the directory structure
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::cardset_menu_add_subdir(GtkWidget* menu,
				      string const& main_directory,
				      string const& directory,
				      unsigned const depth)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
		    "Settings::cardset_menu_add_subdir(menu, main_directory, directory, depth)");

#ifdef OUTDATED
      if (depth == ::setting(Setting::DIRECTORY_SEARCH_DEPTH))
#else
      if (depth == 5)
#endif
	DEBUG_RETURNING(VOID,
			INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
			"Settings::cardset_menu_add_subdir(menu, main_directory, directory, depth)");

      DIR *dir = opendir((main_directory + "/" + directory).c_str());
      if (dir == NULL) {
	DEBUG_RETURNING(VOID,
			INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
			"Settings::cardset_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);
      }

      struct dirent *entry;
      // search all entries in the directory
      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
	{
	  if (DK::Utils::File::isfile(main_directory + "/" + directory + "/"
				      + entry->d_name
				      + "/" + ::setting.value(Setting::CARDS_DIRECTORY)
				      + "/club/ace."
				      + ::setting(Setting::GRAPHIC_EXTENSION))) {
	    // found a valid directory
	    // add the entry to the menu
	    GtkWidget* item = gtk_menu_item_new_with_label(entry->d_name);
	    gtk_object_set_data(GTK_OBJECT(item), "setting",
				new Setting::TypeString(Setting::CARDSET));
	    if (directory.empty())
	      gtk_object_set_data(GTK_OBJECT(item), "value",
				  new string(entry->d_name));
	    else
	      gtk_object_set_data(GTK_OBJECT(item), "value",
				  new string(directory + "/" + entry->d_name));
	    gtk_signal_connect(GTK_OBJECT(item), "activate",
			       GTK_SIGNAL_FUNC(Settings::settings_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->gui().update();
	  } else { // if !(is style directory)
	    GtkWidget* submenu = gtk_menu_new();
	    this->cardset_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->gui().update();
	    } // if (entries in the menu)
	  } // if !(is style directory)
	} // 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_SETTINGS && INFO_GTK_UPDATE,
		      "Settings::cardset_menu_add_subdir(menu, main_directory, directory, depth)");
    } // void Setting::cardset_menu_add_subdir(GtkWidget* menu, string const& main_directory, string const& directory, unsigned const depth)

  /**
   **
   ** show the cardset menu
   **
   ** @param	widget		-
   ** @param	settings	the settings
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::cardset_menu_show_event(GtkWidget* widget, gpointer settings)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::cardset_menu_show_event(widget, settings)");

      ((Settings*)settings)->cardset_menu_show();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::cardset_menu_show_event(widget, settings)");
    } // void Settings::cardset_menu_show_event(GtkWidget* widget, gpointer settings)

  /**
   **
   ** show the cardset menu
   **
   ** @param	widget		-
   ** @param	settings	the settings
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::cardset_menu_show()
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::cardset_menu_show()");

      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(Settings::menu_destroy), NULL);
      gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0);
      gtk_widget_show_all(menu);
      this->cardset_menu_create(menu);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::cardset_menu_show()");
    } // void Settings::cardset_menu_show()

  /**
   **
   ** show the back of the cards menu
   **
   ** @param	widget		-
   ** @param	settings	the settings
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::cards_back_menu_show_event(GtkWidget* widget, gpointer settings)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::cards_back_menu_show_event(widget, settings)");

      ((Settings*)settings)->cards_back_menu_show();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::cards_back_menu_show_event(widget, settings)");
    } // void Settings::cards_back_menu_show_event(GtkWidget* widget, gpointer settings)

  /**
   **
   ** show the back of the cards menu
   **
   ** @param	widget		-
   ** @param	settings	the settings
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::cards_back_menu_show()
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::cards_back_menu_show()");

      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(Settings::menu_destroy), NULL);
      gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0);
      gtk_widget_show_all(menu);
      this->graphic_files_menu_create(menu,
				      ::setting(Setting::CARDS_BACK_DIRECTORY),
				      Setting::CARDS_BACK);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::cards_back_menu_show()");
    } // void Settings::cards_back_menu_show()


  /**
   **
   ** show the back of the cards menu
   **
   ** @param	widget		-
   ** @param	settings	the settings
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::background_menu_show_event(GtkWidget* widget, gpointer settings)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::background_menu_show_event(widget, settings)");

      ((Settings*)settings)->background_menu_show();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::background_menu_show_event(widget, settings)");
    } // void Settings::background_menu_show_event(GtkWidget* widget, gpointer settings)

  /**
   **
   ** show the back of the cards menu
   **
   ** @param	widget		-
   ** @param	settings	the settings
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::background_menu_show()
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::background_menu_show()");

      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(Settings::menu_destroy), NULL);
      gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0);
      gtk_widget_show_all(menu);
      this->graphic_files_menu_create(menu,
				      ::setting(Setting::BACKGROUNDS_DIRECTORY),
				      Setting::BACKGROUND);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::background_menu_show()");
    } // void Settings::background_menu_show()


#ifdef OUTDATED
  /**
   **
   ** creates the menu for the selection of the help icons
   **
   ** @param	menu	the menu where the entries are created
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   ** @todo	sorting the entries
   **
   **/
  void
    Settings::help_icons_menu_create(GtkWidget* menu)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
		    "Settings::help_icons_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
      this->help_icons_menu_add_subdir(menu,
				       "./"
				       + ::setting(Setting::HELP_ICONS_DIRECTORY),
				       "",
				       0);
      this->help_icons_menu_add_subdir(menu,
				       ::setting(Setting::PRIVATE_DATA_DIRECTORY)
				       + "/"
				       + ::setting(Setting::HELP_ICONS_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->help_icons_menu_add_subdir(menu,
				       ::setting(Setting::PUBLIC_DATA_DIRECTORY)
				       + "/"
				       + ::setting(Setting::HELP_ICONS_DIRECTORY),
				       "",
				       0);

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

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
		      "Settings::help_icons_menu_create()");
    } // void Settings::help_icons_menu_create(GtkWidget* menu)

  /**
   **
   ** adds all subdirs from 'directory' with directory information to 'menu'
   **
   ** @param	menu		the menu where the entries are added
   ** @param	main_directory	the main directory (public/private data)
   ** @param	directory		the directory
   ** @param	depth		the depth in the directory structure
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::help_icons_menu_add_subdir(GtkWidget* menu,
					 string const& main_directory,
					 string const& directory,
					 unsigned const depth)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
		    "Settings::help_icons_menu_add_subdir(menu, main_directory, directory, depth)");

      if (depth == ::setting(Setting::DIRECTORY_SEARCH_DEPTH))
	DEBUG_RETURNING(VOID,
			INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
			"Settings::help_icons_menu_add_subdir(menu, main_directory, directory, depth)");

      DIR *dir = opendir((main_directory + "/" + directory).c_str());
      if (dir == NULL) {
	DEBUG_RETURNING(VOID,
			INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
			"Settings::help_icons_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
	{
	  if (DK::Utils::File::isfile(main_directory + "/" + directory + "/"
				      + entry->d_name
				      + "/" + "browser."
				      + ::setting(Setting::GRAPHIC_EXTENSION))) {
	    // found a valid directory
	    // add the entry to the menu
	    GtkWidget* item = gtk_menu_item_new_with_label(entry->d_name);
	    gtk_object_set_data(GTK_OBJECT(item), "setting",
				new Setting::TypeString(Setting::HELP_ICONS_STYLE));
	    if (directory.empty())
	      gtk_object_set_data(GTK_OBJECT(item), "value",
				  new string(entry->d_name));
	    else
	      gtk_object_set_data(GTK_OBJECT(item), "value",
				  new string(directory + "/" + entry->d_name));
	    gtk_signal_connect(GTK_OBJECT(item), "activate",
			       GTK_SIGNAL_FUNC(Settings::settings_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->gui().update();
	  } else { // if !(is directory directory)
	    GtkWidget* submenu = gtk_menu_new();
	    this->help_icons_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->gui().update();
	    } // if (entries in the menu)
	  } // if !(is directory directory)
	} // 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_SETTINGS && INFO_GTK_UPDATE,
		      "Settings::help_icons_menu_add_subdir(menu, main_directory, directory, depth)");
    } // void Setting::help_icons_menu_add_subdir(GtkWidget* menu, string const& main_directory, string const& directory, unsigned const depth)

  /**
   **
   ** show the help icons menu
   **
   ** @param	widget		-
   ** @param	settings	the settings
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::help_icons_menu_show_event(GtkWidget* widget, gpointer settings)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::help_icons_menu_show_event(widget, settings)");

      ((Settings*)settings)->help_icons_menu_show();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::help_icons_menu_show_event(widget, settings)");
    } // void Settings::help_icons_menu_show_event(GtkWidget* widget, gpointer settings)

  /**
   **
   ** show the help icons style menu
   **
   ** @param	widget		-
   ** @param	settings	the settings
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::help_icons_menu_show()
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::help_icons_menu_show()");

      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(Settings::menu_destroy), NULL);
      gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0);
      gtk_widget_show_all(menu);
      this->help_icons_menu_create(menu);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::help_icons_menu_show()");
    } // void Settings::help_icons_menu_show()
#endif



  /**
   **
   ** creates the menu for the selection of the language
   **
   ** @param	menu	the menu where the entries are created
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   ** @todo	sorting the entries
   **
   **/
  void
    Settings::language_menu_create(GtkWidget* menu)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
		    "Settings::language_menu_create()");

      { // add an entry for the default language
	GtkWidget* item = gtk_menu_item_new_with_label(::language("default").c_str());
	gtk_widget_show(item);
	gtk_object_set_data(GTK_OBJECT(item), "setting",
			    new Setting::TypeString(Setting::LANGUAGE));
	gtk_object_set_data(GTK_OBJECT(item), "value",
			    new string());
	gtk_signal_connect(GTK_OBJECT(item), "activate",
			   GTK_SIGNAL_FUNC(Settings::settings_menu_select_event),
			   this);
	gtk_menu_append(GTK_MENU(menu), item);
      } // add an entry for the default language


      { // add a separator
	GtkWidget* separator = gtk_menu_item_new();
	gtk_widget_show(separator);
	gtk_menu_append(GTK_MENU(menu), separator);
      } // add a separator

      // let language do the work on finding the languages :-)
      Language::dir_scan();

      // create the menu for the languages
      for (vector<string>::const_iterator name = Language::names.begin();
	   name != Language::names.end();
	   name++) {
	GtkWidget* item = gtk_menu_item_new_with_label(name->c_str());
	gtk_widget_show(item);
	gtk_object_set_data(GTK_OBJECT(item), "setting",
			    new Setting::TypeString(Setting::LANGUAGE));
	gtk_object_set_data(GTK_OBJECT(item), "value",
			    new string(*name));
	gtk_signal_connect(GTK_OBJECT(item), "activate",
			   GTK_SIGNAL_FUNC(Settings::settings_menu_select_event),
			   this);
	gtk_menu_append(GTK_MENU(menu), item);
      } // for (name)

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_UPDATE,
		      "Settings::language_menu_create()");
    } // void Settings::language_menu_create(GtkWidget* menu)

  /**
   **
   ** show the language menu
   **
   ** @param	widget		-
   ** @param	settings	the settings
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::language_menu_show_event(GtkWidget* widget, gpointer settings)
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::language_menu_show_event(widget, settings)");

      ((Settings*)settings)->language_menu_show();

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::language_menu_show_event(widget, settings)");
    } // void Settings::language_menu_show_event(GtkWidget* widget, gpointer settings)

  /**
   **
   ** show the language menu
   **
   ** @param	widget		-
   ** @param	settings	the settings
   **
   ** @return	-
   ** 
   ** @author	Diether Knof
   **
   ** @version	0.5.1
   **
   **/
  void
    Settings::language_menu_show()
    {
      DEBUG_CALLING(INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		    "Settings::language_menu_show()");

      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(Settings::menu_destroy), NULL);
      gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, 0);
      gtk_widget_show_all(menu);
      this->language_menu_create(menu);

      DEBUG_RETURNING(VOID,
		      INFO_GTK_SETTINGS && INFO_GTK_EVENT,
		      "Settings::language_menu_show()");
    } // void Settings::language_menu_show()

} // namespace GTK_DOKO

#endif // #ifdef USE_UI_GTK
