/* Jungle Monkey
 * Copyright (C) 1999-2001  The Regents of the University of Michigan
 *
 * 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 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
 */


#include "ggui.h"
#include "ggui_preferences.h"
#include "ggui_chat.h"
#include "ggui_config.h"

#include <gnet/gnet.h>
#include "btp/btp.h"
#include "mtp/mtp_types.h"


static GtkWindow*		jm_preferences		 	= NULL;
static GtkEntry*		download_directory_entry 	= NULL;

static GtkEntry*		chat_nickname_entry		= NULL;

static GtkToggleButton*		network_name_auto_button 	= NULL;
static GtkLabel*		network_name_label		= NULL;
static GtkToggleButton*		network_use_dns_button 		= NULL;
static GtkContainer*		network_name_auto_container	= NULL;

static GtkToggleButton*		network_name_manual_button 	= NULL;
static GtkEntry*		network_name_entry		= NULL;

static GtkToggleButton*		network_addr_auto_button 	= NULL;
static GtkLabel*		network_addr_label		= NULL;
static GtkToggleButton*		network_addr_manual_button 	= NULL;
static GtkOptionMenu* 		network_addr_menu		= NULL;

static GtkToggleButton*		channels_port_default_button 	= NULL;
static GtkToggleButton*		channels_port_manual_button 	= NULL;
static GtkEntry*		channels_port_entry		= NULL;
static GtkToggleButton*		channels_port_use_any_button	= NULL;

static GtkToggleButton*		files_port_default_button 	= NULL;
static GtkToggleButton*		files_port_manual_button 	= NULL;
static GtkEntry*		files_port_entry		= NULL;
static GtkToggleButton*		files_port_use_any_button	= NULL;

static GtkToggleButton*		files_automirror_button 	= NULL;

static GtkToggleButton*		files_rendezvous_locally_button	= NULL;
static GtkToggleButton*		files_rendezvous_remotely_button= NULL;
static GtkCombo*		files_rendezvous_combo		= NULL;
static GtkContainer*		files_rendezvous_remotely_container = NULL;



static GInetAddr* 	ad_interface = NULL; 	/* Auto-detected interface */
static gchar* 		ad_address = NULL;	/* Auto-detected address   */
static gchar* 		ad_hostname = NULL;	/* Auto-detected hostname  */
static GList* 		address_strings = NULL;


static void 	initialize_general (void);
static void 	initialize_chat (void);
static void 	initialize_network_interface_auto (void);
static void 	initialize_network_interface_manual (void);
static void 	initialize_network_name (void);
static void	initialize_channels (void);
static void	initialize_files (void);

static void	apply_general (void);
static void	apply_chat (void);
static void	apply_network (void);
static void	apply_channels (void);
static void	apply_files (void);
static void	apply_network2 (void);

#ifndef JM_ENABLE_GNOME
static GtkButton*		apply_button			= NULL;
#endif



void
ggui_preferences_init (void)
{
  /* do nothing */
}


void
ggui_preferences_shutdown (void)
{
  if (jm_preferences)
    {
      gtk_widget_destroy (GTK_WIDGET(jm_preferences));
      jm_preferences = NULL;
    }
}


void
on_preferences (gpointer callback_data, guint callback_action, GtkWidget* widg)
{
  gchar* widget_name;
  GtkWidget* widget;
  GladeXML* preferences_xml;

  /* Redisplay the preferences if they are already showing */
  if (jm_preferences)
    {
      gtk_widget_show (GTK_WIDGET(jm_preferences));
      return;
    }

  /* Get the XML */
# ifdef JM_ENABLE_GNOME
  widget_name = "preferences_dialog_gnome";
# else
  widget_name = "preferences_dialog";
# endif

  preferences_xml = ggui_get_glade_xml (widget_name, "preferences_dialog.glade");
  g_return_if_fail (preferences_xml != NULL);
  glade_xml_signal_autoconnect(preferences_xml);

  /* Get the widgets */
  widget = glade_xml_get_widget (preferences_xml, widget_name);
  jm_preferences 		= GTK_WINDOW(widget); /* GTK_DIALOG/GNOME_PROPERTY_BOX */
  widget = glade_xml_get_widget (preferences_xml, "preferences_download_directory_entry");
  download_directory_entry 	= GTK_ENTRY(widget);;

  widget = glade_xml_get_widget (preferences_xml, "chat_nickname_entry");
  chat_nickname_entry	 	= GTK_ENTRY(widget);;

  widget = glade_xml_get_widget (preferences_xml, "network_name_auto_button");
  network_name_auto_button 	= GTK_TOGGLE_BUTTON(widget);
  widget = glade_xml_get_widget (preferences_xml, "network_name_label");
  network_name_label	 	= GTK_LABEL(widget);
  widget = glade_xml_get_widget (preferences_xml, "network_use_dns_button");
  network_use_dns_button 	= GTK_TOGGLE_BUTTON(widget);
  widget = glade_xml_get_widget (preferences_xml, "network_name_auto_container");
  network_name_auto_container 	= GTK_CONTAINER(widget);

  widget = glade_xml_get_widget(preferences_xml, "network_name_manual_button");
  network_name_manual_button 	= GTK_TOGGLE_BUTTON(widget);
  widget = glade_xml_get_widget(preferences_xml, "network_name_entry");
  network_name_entry	 	= GTK_ENTRY(widget);

  widget = glade_xml_get_widget (preferences_xml, "network_addr_auto_button");
  network_addr_auto_button 	= GTK_TOGGLE_BUTTON (widget);
  widget = glade_xml_get_widget (preferences_xml, "network_addr_label");
  network_addr_label		= GTK_LABEL (widget);
  widget = glade_xml_get_widget (preferences_xml, "network_addr_manual_button");
  network_addr_manual_button 	= GTK_TOGGLE_BUTTON (widget);
  widget = glade_xml_get_widget (preferences_xml, "network_addr_menu");
  network_addr_menu 		= GTK_OPTION_MENU (widget);

  widget = glade_xml_get_widget (preferences_xml, "channels_port_default_button");
  channels_port_default_button 	= GTK_TOGGLE_BUTTON(widget);
  widget = glade_xml_get_widget (preferences_xml, "channels_port_manual_button");
  channels_port_manual_button	= GTK_TOGGLE_BUTTON (widget);
  widget = glade_xml_get_widget (preferences_xml, "channels_port_entry");
  channels_port_entry	 	= GTK_ENTRY (widget);
  widget = glade_xml_get_widget (preferences_xml, "channels_port_use_any_button");
  channels_port_use_any_button	= GTK_TOGGLE_BUTTON (widget);

  widget = glade_xml_get_widget (preferences_xml, "files_port_default_button");
  files_port_default_button 	= GTK_TOGGLE_BUTTON(widget);
  widget = glade_xml_get_widget (preferences_xml, "files_port_manual_button");
  files_port_manual_button	= GTK_TOGGLE_BUTTON (widget);
  widget = glade_xml_get_widget (preferences_xml, "files_port_entry");
  files_port_entry	 	= GTK_ENTRY (widget);
  widget = glade_xml_get_widget (preferences_xml, "files_port_use_any_button");
  files_port_use_any_button	= GTK_TOGGLE_BUTTON (widget);

  widget = glade_xml_get_widget (preferences_xml, "files_automirror_button");
  files_automirror_button	= GTK_TOGGLE_BUTTON (widget);

  widget = glade_xml_get_widget (preferences_xml, "files_rendezvous_locally_button");
  files_rendezvous_locally_button= GTK_TOGGLE_BUTTON (widget);
  widget = glade_xml_get_widget (preferences_xml, "files_rendezvous_remotely_button");
  files_rendezvous_remotely_button= GTK_TOGGLE_BUTTON (widget);
  widget = glade_xml_get_widget (preferences_xml, "files_rendezvous_combo");
  files_rendezvous_combo	= GTK_COMBO (widget);
  widget = glade_xml_get_widget (preferences_xml, "files_rendezvous_remotely_container");
  files_rendezvous_remotely_container = GTK_CONTAINER (widget);

  if (!jm_preferences)
    {
      ggui_show_message ("error", _("Could not create preferences dialog.\n"
				    "Either JM is not correctly installed or libglade is\n"
				    "out-of-date."));
      return;
    }

  /* Make sure we got them */
  g_return_if_fail (jm_preferences 			);
  g_return_if_fail (download_directory_entry 		);
							
  g_return_if_fail (network_name_auto_button 		);
  g_return_if_fail (network_name_label	 		);
  g_return_if_fail (network_use_dns_button 		);
  g_return_if_fail (network_name_auto_container		);
							
  g_return_if_fail (network_name_manual_button 		);
  g_return_if_fail (network_name_entry	 		);
							
  g_return_if_fail (network_addr_auto_button 		);
  g_return_if_fail (network_addr_label			);
  g_return_if_fail (network_addr_manual_button 		);
  g_return_if_fail (network_addr_menu			);      

  g_return_if_fail (channels_port_default_button 	);
  g_return_if_fail (channels_port_manual_button	 	);
  g_return_if_fail (channels_port_entry 	 	);
  g_return_if_fail (channels_port_use_any_button 	);     

  g_return_if_fail (files_port_default_button		);
  g_return_if_fail (files_port_manual_button 		);
  g_return_if_fail (files_port_entry	 		);
  g_return_if_fail (files_port_use_any_button		);

  g_return_if_fail (files_automirror_button		);

  g_return_if_fail (files_rendezvous_locally_button	);
  g_return_if_fail (files_rendezvous_remotely_button	);
  g_return_if_fail (files_rendezvous_combo		);
  g_return_if_fail (files_rendezvous_remotely_container	);


  /* Get the apply button maybe */
#ifndef JM_ENABLE_GNOME
  widget = glade_xml_get_widget (preferences_xml, "apply_button");
  apply_button = GTK_BUTTON(widget);
  g_return_if_fail (apply_button);
  gtk_widget_set_sensitive (GTK_WIDGET(apply_button), FALSE);
#endif

  /* Set some tool tips */
  ggui_set_tooltip (GTK_WIDGET(network_use_dns_button), 
		    _("Enable this if your host has a real domain name"));
  /* TODO: Set some more !!! */

  /* Set the dialog's parent or mouse point */
# ifdef JM_ENABLE_GNOME
  gnome_dialog_set_parent (GNOME_DIALOG(jm_preferences), GTK_WINDOW(jmw));
# else
  GTK_WINDOW(jm_preferences)->position = GTK_WIN_POS_MOUSE;
#endif

  /* Initialize everything */
  initialize_general ();
  initialize_chat ();
  initialize_network_interface_auto ();	/* most go before name */
  initialize_network_interface_manual ();
  initialize_network_name ();
  initialize_channels ();
  initialize_files ();


  /* Set to unmodified */
# ifdef JM_ENABLE_GNOME
  gnome_property_box_set_modified (GNOME_PROPERTY_BOX(jm_preferences), FALSE);
# endif

  /* Show it */
  gtk_widget_show (GTK_WIDGET(jm_preferences));
}


void
initialize_general (void)
{
  gchar* home_dir;
  gint home_dir_length;

  g_return_if_fail (download_directory_entry != NULL);
  g_return_if_fail (jm_home != NULL);

  /* Get the home directory */
  home_dir = g_get_home_dir();	/* don't delete */
  g_return_if_fail (home_dir != NULL);

  /* If it begins with $HOME, then replace it with ~ */
  home_dir_length = strlen(home_dir);
  if (!strncmp(jm_home, home_dir, home_dir_length))
    {
      gchar* dir;

      dir = g_strconcat("~", G_DIR_SEPARATOR_S, &jm_home[home_dir_length + 1], NULL);
      gtk_entry_set_text (download_directory_entry, dir);
      g_free(dir);
    }
  else
    gtk_entry_set_text (download_directory_entry, jm_home);
}


void
initialize_chat (void)
{
  gchar* nickname;

  g_return_if_fail (chat_nickname_entry);

  nickname = ggui_chat_get_nickname();

  if (nickname)
    gtk_entry_set_text (chat_nickname_entry, nickname);
}



void
initialize_network_interface_auto (void)
{
  gboolean do_auto;

  ad_interface = NULL;
  ad_address = NULL;

  /* Determine if we should auto-detect the address */
  do_auto = 
    ggui_config_get_bool("/Jungle Monkey/Network/Auto detect interface", TRUE);

  /* Auto-detect interface */
  ad_interface = gnet_inetaddr_autodetect_internet_interface ();
  if (ad_interface)
    {
      /* Get the canonical name */
      ad_address = gnet_inetaddr_get_canonical_name (ad_interface);

      /* Set the address label to the canonical name */
      if (ad_address)
	gtk_label_set_text (network_addr_label, ad_address);
    }

  gtk_toggle_button_set_active (network_addr_auto_button,   do_auto);
  gtk_toggle_button_set_active (network_addr_manual_button, !do_auto);
  gtk_widget_set_sensitive (GTK_WIDGET(network_addr_label), do_auto);
  gtk_widget_set_sensitive (GTK_WIDGET(network_addr_menu),  !do_auto);
}


void
initialize_network_interface_manual(void)
{
  gchar* manual_address = NULL;
  gchar* address_string;

  GList* interfaces;
  GList* i;
  GtkMenu* menu;
  GtkWidget* item;
  gboolean found_manual = FALSE;

  g_return_if_fail (network_addr_menu != NULL);

  /* **************************************** */

  /* Get the address from the configuration file */
  manual_address = 
    ggui_config_get_string("/Jungle Monkey/Network/Interface", NULL);

  /* Create the menu */
  menu = GTK_MENU(gtk_menu_new());

  /* Get the interfaces */
  interfaces = gnet_inetaddr_list_interfaces ();

  /* Add an interface for everyone but the manual address */
  for (i = interfaces; i != NULL; i = i->next)
    {
      GInetAddr* interface;
      gchar* canonical_name;

      /* Get the interface */
      interface = (GInetAddr*) i->data;
      g_return_if_fail (interface != NULL);

      /* Get the canonical name */
      canonical_name = gnet_inetaddr_get_canonical_name(interface);
      g_return_if_fail (canonical_name != NULL);

      /* Skip if it's the manual address - we want to add it first */
      if (manual_address && !strcmp(manual_address, canonical_name))
	{
	  g_free (canonical_name);
	  found_manual = TRUE;
	}
      /* Otherwise, add it */
      else
	{
	  item = gtk_menu_item_new_with_label(canonical_name);
	  g_list_prepend(address_strings, canonical_name);
	  gtk_object_set_user_data(GTK_OBJECT(item), canonical_name);
	  gtk_menu_append(menu, item);
	  gtk_widget_show(item);
	}

      gnet_inetaddr_delete (interface);
    }
  g_list_free(interfaces);

  /* If there's a saved manual address and we found it, then add it */
  if (manual_address && found_manual)
    {
      address_string = g_strdup(manual_address);

      item = gtk_menu_item_new_with_label(manual_address);
      g_list_prepend(address_strings, address_string);
      gtk_object_set_user_data(GTK_OBJECT(item), address_string);
      gtk_menu_prepend(menu, item);
      gtk_widget_show(item);
    }

  /* Also add 127.0.0.1.  It shouldn't have been in the list of
     interfaces. */
  address_string = g_strdup("127.0.0.1");
  g_list_prepend (address_strings, address_string);

  item = gtk_menu_item_new_with_label ("127.0.0.1");
  if (manual_address && !strcmp(manual_address, "127.0.0.1"))
    gtk_menu_prepend (menu, item);
  else
    gtk_menu_append (menu, item);
  gtk_object_set_user_data (GTK_OBJECT(item), address_string);
  gtk_widget_show (item);


  /* Show and set the menu */
  gtk_widget_show(GTK_WIDGET(menu));
  gtk_option_menu_set_menu(network_addr_menu, GTK_WIDGET(menu));

  g_free (manual_address);
}


void
initialize_network_name (void)
{
  gboolean do_auto;
  gboolean use_dns = FALSE;
  gchar* manual_hostname = NULL;

  ad_hostname = NULL;

  /* Determine if we should auto-detect the hostname */
  do_auto = 
    ggui_config_get_bool("/Jungle Monkey/Network/Auto detect hostname", TRUE);

  /* Initialize "Use DNS" */
  if (ggui_config_get_bool("/Jungle Monkey/Network/Use DNS", FALSE))
    {
      gtk_toggle_button_set_active(network_use_dns_button, TRUE);
      use_dns = TRUE;
    }

  /* Initialize the auto-detected hostname based on what auto-detect returned */
  if (ad_interface && ad_address)
    {
      /* Use DNS regardless of flag setting */
      ad_hostname = gnet_inetaddr_get_name (ad_interface);
      if (!ad_hostname)
	ad_hostname = g_strdup (ad_address);

      if (!gnet_inetaddr_is_internet_domainname (ad_hostname))
	{
	  g_free (ad_hostname);
	  ad_hostname = NULL;
	}

      if (ad_hostname)
	{
	  if (use_dns)
	    gtk_label_set_text (network_name_label, ad_hostname);
	  else if (ad_address)
	    gtk_label_set_text (network_name_label, ad_address);
	}
    }

  /* Initialize the manually set hostname */
  if ((manual_hostname = 
       ggui_config_get_string("/Jungle Monkey/Network/Hostname", NULL)) != NULL)
    {
      gtk_entry_set_text (network_name_entry, manual_hostname);
    }
  else if (ad_hostname)
    {
      gtk_entry_set_text (network_name_entry, ad_hostname);
    }

  gtk_toggle_button_set_active (network_name_auto_button, do_auto);
  gtk_toggle_button_set_active (network_name_manual_button, !do_auto);
  gtk_widget_set_sensitive (GTK_WIDGET(network_name_auto_container), do_auto);
  gtk_widget_set_sensitive (GTK_WIDGET(network_name_entry), !do_auto);

  g_free (manual_hostname);
}


void
initialize_channels (void)
{
  gboolean use_any_port;
  gboolean use_default_port;
  gint port;
  gchar buffer[16];
  GtkLabel* label;
  gchar* str;

  use_any_port = ggui_config_get_bool ("/Jungle Monkey/Channels/Use any BTP Port if unavailable", TRUE);
  use_default_port = ggui_config_get_bool ("/Jungle Monkey/Channels/Use Default BTP Port", TRUE);
  port = ggui_config_get_int ("/Jungle Monkey/Channels/BTP Port", -1);
  if (port == -1) 
    port = BTP_PORT;

  label = GTK_LABEL((GTK_BIN(channels_port_default_button)->child));
  g_return_if_fail (label);

  str = g_strdup_printf (_("Use default port (%d)"), BTP_PORT);
  gtk_label_set_text (label, str);
  g_free (str);
  
  gtk_toggle_button_set_active (channels_port_default_button, use_default_port);
  gtk_toggle_button_set_active (channels_port_manual_button, !use_default_port);
  gtk_widget_set_sensitive (GTK_WIDGET(channels_port_entry), !use_default_port);

  g_snprintf (buffer, sizeof(buffer), "%d", port);
  gtk_entry_set_text (channels_port_entry, buffer);
}



void
initialize_files (void)
{
  gboolean use_any_port;
  gboolean use_default_port;
  gint port;
  gchar buffer[16];
  GtkLabel* label;
  gchar* str;
  gchar* rendezvous_url;
  gboolean rendezvous_locally;

  use_any_port = ggui_config_get_bool ("/Jungle Monkey/Files/Use any MTP Port if unavailable", TRUE);
  use_default_port = ggui_config_get_bool ("/Jungle Monkey/Files/Use Default MTP Port", TRUE);
  port = ggui_config_get_int ("/Jungle Monkey/Files/MTP Port", -1);
  if (port == -1) 
    port = MTP_SERVER_PORT;

  label = GTK_LABEL((GTK_BIN(files_port_default_button)->child));
  g_return_if_fail (label);

  str = g_strdup_printf (_("Use default port (%d)"), MTP_SERVER_PORT);
  gtk_label_set_text (label, str);
  g_free (str);
  
  gtk_toggle_button_set_active (files_port_default_button, use_default_port);
  gtk_toggle_button_set_active (files_port_manual_button, !use_default_port);
  gtk_widget_set_sensitive (GTK_WIDGET(files_port_entry), !use_default_port);

  g_snprintf (buffer, sizeof(buffer), "%d", port);
  gtk_entry_set_text (files_port_entry, buffer);

  gtk_toggle_button_set_active (files_automirror_button,
				ggui_config_get_bool ("/Jungle Monkey/Files/Automirror", TRUE));

  rendezvous_locally = ggui_config_get_bool("/Jungle Monkey/Files/Rendezvous locally", TRUE);
  gtk_toggle_button_set_active (files_rendezvous_locally_button,  rendezvous_locally);
  gtk_toggle_button_set_active (files_rendezvous_remotely_button, !rendezvous_locally);
  gtk_widget_set_sensitive (GTK_WIDGET(files_rendezvous_remotely_container), !rendezvous_locally);

  rendezvous_url = ggui_config_get_string("/Jungle Monkey/Files/Rendezvous URL", NULL);
  if (rendezvous_url)
    gtk_entry_set_text (GTK_ENTRY(files_rendezvous_combo->entry), rendezvous_url);
}



/* ************************************************************ */


# ifdef JM_ENABLE_GNOME

void
on_preferences_apply (GnomePropertyBox *propertybox, gint page_num)
{
  if (page_num != -1)
    return;

  apply_general ();
  apply_chat ();
  apply_network ();
  apply_channels ();
  apply_files ();

  ggui_config_sync ();

  apply_network2 ();
}

#else

void
on_preferences_apply (gpointer widget)
{
  gtk_widget_set_sensitive (GTK_WIDGET(apply_button), FALSE);

  apply_general ();
  apply_chat ();
  apply_network ();
  apply_channels ();
  apply_files ();
  apply_network2 ();

  ggui_config_sync ();
}

#endif

static gboolean		network_changed = FALSE;


void
apply_general(void)
{
  gchar* text;
  gchar* new_home = NULL;

  /* Set jmhome */
  text = gtk_entry_get_text(download_directory_entry);  /* don't delete */
  if (!text || !text[0])
    return;
  
  /* Remove the ~ */
  if (text[0] == '~')
    {
      gchar* home_dir;
      home_dir = g_get_home_dir();	/* don't delete */
      g_return_if_fail (home_dir != NULL);

      new_home = g_strconcat(home_dir, &text[1], NULL);
    }
  else
    new_home = g_strdup(text);

  /* Remove the trailing / if necessary */
  if (*new_home && new_home[strlen(new_home)-1] == G_DIR_SEPARATOR)
    new_home[strlen(new_home)-1] = '\0';

  /* Set jm_home */
  if (jm_home)
    g_free (jm_home);
  jm_home = new_home;

  /* Save the value */
  ggui_config_set_string("/Jungle Monkey/General/home", new_home);
}


void
apply_chat (void)
{
  gchar* nickname;

  g_return_if_fail (chat_nickname_entry);

  nickname = gtk_entry_get_text (chat_nickname_entry);
  if (nickname && *nickname)
    ggui_chat_set_nickname (nickname);
}


void
apply_network (void)
{
  gboolean state;

  /* ******************** */

  /* Save "Use DNS" */
  state = gtk_toggle_button_get_active(network_use_dns_button);
  if (state != ggui_config_get_bool ("/Jungle Monkey/Network/Use DNS", FALSE))
    network_changed = TRUE;
  ggui_config_set_bool ("/Jungle Monkey/Network/Use DNS", state);

  /* Save "Auto detect interface" */
  state = gtk_toggle_button_get_active(network_addr_auto_button);
  if (state != ggui_config_get_bool("/Jungle Monkey/Network/Auto detect interface", TRUE))
    network_changed = TRUE;
  ggui_config_set_bool ("/Jungle Monkey/Network/Auto detect interface", state);

  /* If manual, save the manual information */
  if (!state)
    {
      gchar* address;	/* don't delete */
      gchar* old_address;
      GtkMenu* menu;
      GtkWidget* item;

      /* Save the address */
      menu = GTK_MENU(gtk_option_menu_get_menu(network_addr_menu));
      g_return_if_fail (menu != NULL);

      item = gtk_menu_get_active(menu);
      g_return_if_fail (item != NULL);

      address = (gchar*) gtk_object_get_user_data(GTK_OBJECT(item));
      g_return_if_fail (address != NULL);

      old_address = 
	ggui_config_get_string ("/Jungle Monkey/Network/Interface", NULL);
      if (!old_address || (old_address && strcmp(address, old_address)))
	network_changed = TRUE;

      ggui_config_set_string ("/Jungle Monkey/Network/Interface", address);

      g_free (old_address);
    }

  /* ******************** */

  /* Set "Auto detect hostname" */
  state = gtk_toggle_button_get_active (network_name_auto_button);
  if (state != ggui_config_get_bool("/Jungle Monkey/Network/Auto detect hostname", TRUE))
    network_changed = TRUE;
  ggui_config_set_bool ("/Jungle Monkey/Network/Auto detect hostname", state);

  /* If manual, save the manual information */
  if (!state)
    {
      gchar* hostname;

      /* Save the hostname */
      hostname = gtk_entry_get_text(network_name_entry);	/* don't delete */
      if (hostname && *hostname)
	{
	  gchar* old_hostname;

	  old_hostname = ggui_config_get_string ("/Jungle Monkey/Network/Hostname", NULL);
	  if (!old_hostname || (old_hostname && strcmp(hostname, old_hostname)))
	    network_changed = TRUE;

	  ggui_config_set_string ("/Jungle Monkey/Network/Hostname", hostname);

	  g_free (old_hostname);
	}
    }
}



static void
apply_channels (void)
{
  gboolean state;
  gint new_btp_port;
  gboolean new_use_any_btp_port;


  /* Save port */
  new_use_any_btp_port = 
    gtk_toggle_button_get_active (channels_port_use_any_button);
  if (new_use_any_btp_port != 
      ggui_config_get_bool ("/Jungle Monkey/Channels/Use any BTP Port if unavailable", TRUE))
    {
      network_changed = TRUE;
    }
  ggui_config_set_bool ("/Jungle Monkey/Channels/Use any BTP Port if unavailable", 	
			new_use_any_btp_port);

  /* Save use default port */
  state = gtk_toggle_button_get_active (channels_port_default_button);
  if (state != 
      ggui_config_get_bool("/Jungle Monkey/Channels/Use Default BTP Port", TRUE))
    network_changed = TRUE;
  ggui_config_set_bool ("/Jungle Monkey/Channels/Use Default BTP Port", state);

  /* Save port (only if changed significantly) */
  new_btp_port = atoi(gtk_entry_get_text(channels_port_entry));
  if (!state && 
      new_btp_port != ggui_config_get_int("/Jungle Monkey/Channels/BTP Port", -1))
    network_changed = TRUE;
  if (!state || (state && new_btp_port != BTP_PORT))
    ggui_config_set_int ("/Jungle Monkey/Channels/BTP Port", new_btp_port);
}



static void
apply_files (void)
{
  gboolean 	new_use_any_mtp_port;
  gint 		new_mtp_port;
  gboolean 	state;
  gchar*	rendezvous_url;

  /* Save port */
  new_use_any_mtp_port = gtk_toggle_button_get_active (files_port_use_any_button);
  if (new_use_any_mtp_port != 
      ggui_config_get_bool ("/Jungle Monkey/Files/Use any MTP Port if unavailable", TRUE))
    {
      network_changed = TRUE;
    }
  ggui_config_set_bool ("/Jungle Monkey/Files/Use any MTP Port if unavailable", 	
			new_use_any_mtp_port);

  /* Save use default port */
  state = gtk_toggle_button_get_active (files_port_default_button);
  if (state != 
      ggui_config_get_bool("/Jungle Monkey/Files/Use Default MTP Port", TRUE))
    {
      network_changed = TRUE;
    }
  ggui_config_set_bool ("/Jungle Monkey/Files/Use Default MTP Port", state);

  /* Save port (only if changed significantly) */
  new_mtp_port = atoi(gtk_entry_get_text(files_port_entry));
  if (!state && 
      new_mtp_port != ggui_config_get_int("/Jungle Monkey/Files/MTP Port", -1))
    {
      network_changed = TRUE;
    }
  if (!state || (state && new_mtp_port != MTP_SERVER_PORT))
    ggui_config_set_int ("/Jungle Monkey/Files/MTP Port", new_mtp_port);

  /* ******************** */

  jm_mtp_mirror_on_download = 
    gtk_toggle_button_get_active (files_automirror_button);
  ggui_config_set_bool ("/Jungle Monkey/Files/Automirror", 
			jm_mtp_mirror_on_download);

  /* ******************** */

  state = gtk_toggle_button_get_active (files_rendezvous_locally_button);
  ggui_config_set_bool ("/Jungle Monkey/Files/Rendezvous locally", state);
  jm_mtp_rvous_locally = state;

  rendezvous_url = gtk_entry_get_text (GTK_ENTRY(files_rendezvous_combo->entry));
  if (!state && rendezvous_url && *rendezvous_url)
    {
      GURL* url = gnet_url_new (rendezvous_url);

      if (url)
	{
	  ggui_config_set_string ("/Jungle Monkey/Files/Rendezvous URL", rendezvous_url);
	  gnet_url_delete (url);
	}
      else
	ggui_show_message("warning", _("Bad Rendezvous URL: %s"), rendezvous_url);
    }
}


static void
apply_network2 (void)
{

  /* Warn if the backend is initialized and they changed something */
  if (jm_running && network_changed)
    {
      ggui_show_message("info", _("You must restart Jungle Monkey for the new network "
				  "configuration to take effect."));
    }

  /* Otherwise, try to start the backend based on the new
     configuration. */
  else if (!jm_running)
    {
      if (jmutil_init (NULL, FALSE, NULL, 0, FALSE, 0, FALSE, FALSE))
	{
	  ggui_disable();

	  ggui_show_message ("error", 
			     _("Could not start backend with "
			       "given network configuration"));
	}
      else
	{
	  ggui_enable ();
	  ggui_check_network_config ();
	}
    }

  network_changed = FALSE;
}




void
on_preferences_close (gpointer widget)
{
  GList* i;

  gtk_widget_destroy (GTK_WIDGET(jm_preferences));

  jm_preferences		= NULL;
  download_directory_entry 	= NULL;

  network_name_auto_button 	= NULL;
  network_name_label		= NULL;
  network_use_dns_button 	= NULL;
  network_name_auto_container	= NULL;

  network_name_manual_button 	= NULL;
  network_name_entry		= NULL;

  network_addr_auto_button 	= NULL;
  network_addr_label		= NULL;
  network_addr_manual_button 	= NULL;
  network_addr_menu		= NULL;

  channels_port_default_button 	= NULL;
  channels_port_manual_button 	= NULL;
  channels_port_entry		= NULL;
  channels_port_use_any_button	= NULL;

  files_port_default_button 	= NULL;
  files_port_manual_button 	= NULL;
  files_port_entry		= NULL;
  files_port_use_any_button	= NULL;

  files_automirror_button 	= NULL;
  
  files_rendezvous_locally_button	= NULL;
  files_rendezvous_remotely_button	= NULL;
  files_rendezvous_combo		= NULL;
  files_rendezvous_remotely_container	= NULL;

  gnet_inetaddr_delete (ad_interface);	ad_interface = NULL;
  g_free(ad_address);			ad_address   = NULL;
  g_free(ad_hostname);			ad_hostname  = NULL;

  for (i = address_strings; i != NULL; i = i->next)
    g_free (i->data);
  g_list_free (address_strings);
  address_strings = NULL;
}


void
on_preferences_changed (gpointer widget)
{
#ifdef JM_ENABLE_GNOME
  gnome_property_box_changed (GNOME_PROPERTY_BOX(jm_preferences));
#else
  gtk_widget_set_sensitive (GTK_WIDGET(apply_button), TRUE);
#endif
}


void
on_preferences_network_addr_toggled (GtkToggleButton* button)
{
  gboolean do_auto;

  if (button == network_addr_auto_button)
    do_auto = gtk_toggle_button_get_active (network_addr_auto_button);
  else
    do_auto = !gtk_toggle_button_get_active (network_addr_manual_button);

  gtk_widget_set_sensitive (GTK_WIDGET(network_addr_label), do_auto);
  gtk_widget_set_sensitive (GTK_WIDGET(network_addr_menu),  !do_auto);

  on_preferences_changed (NULL);
}


void
on_preferences_network_name_toggled (GtkToggleButton* button)
{
  gboolean do_auto;

  if (button == network_name_auto_button)
    do_auto = gtk_toggle_button_get_active (network_name_auto_button);
  else
    do_auto = !gtk_toggle_button_get_active (network_name_manual_button);

  gtk_widget_set_sensitive (GTK_WIDGET(network_name_auto_container), do_auto);
  gtk_widget_set_sensitive (GTK_WIDGET(network_name_entry), !do_auto);

  on_preferences_changed (NULL);
}


void
on_preferences_channels_port_toggled (GtkToggleButton* button)
{
  gboolean b;

  if (button == channels_port_default_button)
    b = gtk_toggle_button_get_active (channels_port_default_button);
  else
    b = !gtk_toggle_button_get_active (channels_port_manual_button);

  gtk_widget_set_sensitive (GTK_WIDGET(channels_port_entry), !b);

  on_preferences_changed (NULL);
}


void
on_preferences_files_port_toggled (GtkToggleButton* button)
{
  gboolean b;

  if (button == files_port_default_button)
    b = gtk_toggle_button_get_active (files_port_default_button);
  else
    b = !gtk_toggle_button_get_active (files_port_manual_button);

  gtk_widget_set_sensitive (GTK_WIDGET(files_port_entry), !b);

  on_preferences_changed (NULL);
}


void
on_preferences_files_rendezvous_toggled (GtkToggleButton* button)
{
  gboolean b;

  if (button == files_rendezvous_locally_button)
    b = gtk_toggle_button_get_active (files_rendezvous_locally_button);
  else
    b = !gtk_toggle_button_get_active (files_rendezvous_remotely_button);

  gtk_widget_set_sensitive (GTK_WIDGET(files_rendezvous_remotely_container), !b);

  on_preferences_changed (NULL);
}



void
on_preferences_use_dns_toggled (GtkToggleButton* button)
{
  gboolean state;

  state = gtk_toggle_button_get_active(network_use_dns_button);

  /* If we turned it on, display the auto-detected hostname */
  if (state && ad_hostname)
    {
      gtk_label_set_text (network_name_label, ad_hostname);
    }
  /* Otherwise, display the IP address */
  else if (!state && ad_address)
    {
      gtk_label_set_text (network_name_label, ad_address);
    }

  on_preferences_changed (NULL);
}



#ifndef JM_ENABLE_GNOME

void
on_preferences_ok (gpointer widget)
{
  on_preferences_apply (NULL);
  on_preferences_close (NULL);
}

#endif


syntax highlighted by Code2HTML, v. 0.9.1