/*
**  $Id: interface_panel.c,v 1.10 1999/06/14 22:38:58 gregm Exp $
**
**  GXSNMP -- An snmp management application.
**  Copyright (C) 1998 Gregory Mclean
**
**  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, Cambridge, MA 02139, USA.
**
**  interface_panel.c -- Network interface configuration panel 
**
**  interface_panel.c implements a widget that is used to enter and edit
**  information about a host network interface.
**
*/

#include <config.h>
#include <gnome.h>
#include "interface_panel.h"
#include "panel_utility.h"
#include "debug.h"

#define PANEL_ROWS 6

/*
**  Table of descriptive labels to display as the first column of the table
*/

static char *interface_label[] = {
  N_("Name"),
  N_("Transport"),
  N_("Address"),
  N_("Netmask"),
  N_("Created"),
  N_("Modified")
};

/*
**  Table of tooltips to associate with the table columns
*/

static char *interface_tooltip[] = {
  N_("Name assigned to this interface, e.g. 'eth0'"),
  N_("Transport type used by this interface"),
  N_("The network address of the interface"),
  N_("The netmask used by the interface"),
  N_("Date and time this interface was added to the database."),
  N_("Date and time this interface was modified in the database.")
};

/*
** Dynamic label and tooltips dependent on transport choosen.
**
** Used for:
**
** AF_INET:         netmask
** AF_IPX:          (unused)
** AF_INET6:        prefix length
*/

static char *transport_mlabels[] = {
#ifdef HAVE_INET
  N_("Netmask:"),
#endif
#ifdef HAVE_IPX
  N_("(n/a)"),
#endif
#ifdef HAVE_INET6
  N_("Prefixlen:"),
#endif
};

static char *transport_mtooltip[] = {
#ifdef HAVE_INET
  N_("The netmask used by the interface, e.g. '255.255.255.0'"),
#endif
#ifdef HAVE_IPX
  N_("IPX has fixed network lenghts. No configuration possible."),
#endif
#ifdef HAVE_INET6
  N_("The prefix length used by the interface, e.g. '96'"),
#endif
};

static char *transport_atooltip[] = {
#ifdef HAVE_INET
  N_("The network address of the interface, e.g. '192.168.1.1'"),
#endif
#ifdef HAVE_IPX
  N_("The network address of the interface, e.g. '01:02:03:04:05:06.1'"),
#endif
#ifdef HAVE_INET6
  N_("The network address of the interface, e.g. 'fcc0:1:2:a::1'"),
#endif
};
 
/*
**  Signal information
*/

enum {
  CHANGED_SIGNAL,
  LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = { 0 };

/*******************************************************************************
**
**  Local forward references
**
*******************************************************************************/

static void    interface_panel_class_init (GXsnmp_interface_panelClass  *klass);

static void    interface_panel_init       (GXsnmp_interface_panel       *panel);

static void    changed_cb     		(GtkWidget		*widget,
					 gpointer		 data);

/*******************************************************************************
**
**  gxsnmp_interface_panel_get_type ()
**
*******************************************************************************/

guint
gxsnmp_interface_panel_get_type()
{
  static guint if_type = 0;

  if (!if_type)
    {
      GtkTypeInfo if_info =
      {
	"GXsnmp_interface_panel",
	sizeof (GXsnmp_interface_panel),
	sizeof (GXsnmp_interface_panelClass),
	(GtkClassInitFunc) interface_panel_class_init,
	(GtkObjectInitFunc) interface_panel_init,
	(GtkArgSetFunc) NULL,
	(GtkArgGetFunc) NULL
      };
      if_type = gtk_type_unique (gtk_vbox_get_type (), &if_info);
    }
  return if_type;
}

/*******************************************************************************
**
**  The class initialization subroutine
**
*******************************************************************************/

static void
interface_panel_class_init (GXsnmp_interface_panelClass *class)
{
  GtkObjectClass *object_class;

  object_class = (GtkObjectClass*) class;

  signals[CHANGED_SIGNAL] =
    gtk_signal_new("changed",
                   GTK_RUN_FIRST,
                   object_class->type,
                   GTK_SIGNAL_OFFSET (GXsnmp_interface_panelClass, changed),
                   gtk_signal_default_marshaller,
                   GTK_TYPE_NONE, 0);
  gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
  class->changed = NULL;
}

/*******************************************************************************
**
**  The widget initialization subroutine
**
*******************************************************************************/

static void
interface_panel_init (GXsnmp_interface_panel *panel)
{
  GtkWidget 	*table;
  GtkWidget	*label;
  GtkWidget 	*event_box;
  int	     	 i;
  D_FUNC_START;
/*
**  The controls are organized in a PANEL_ROWS by 2 table
*/

  table = gtk_table_new (PANEL_ROWS, 2, FALSE);
  gtk_table_set_row_spacings (GTK_TABLE (table), 4);
  gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  gtk_container_border_width (GTK_CONTAINER (table), 0);
  gtk_container_add (GTK_CONTAINER (panel), table);

/*
**  Start by constructing all of the label widgets and adding the tooltips.
*/

  panel->tooltips = gtk_tooltips_new ();
  for (i = 0; i < PANEL_ROWS; i++)
    {
      label = gtk_label_new (gettext(interface_label[i]));
      gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.5);
      event_box = gtk_event_box_new ();
      gtk_container_add (GTK_CONTAINER (event_box), label);
      gtk_tooltips_set_tip (panel->tooltips, event_box, 
			    gettext(interface_tooltip[i]), 
                            NULL);
      gtk_table_attach (GTK_TABLE(table), event_box, 0, 1, i, i + 1,
                        GTK_FILL, 0, 0, 0);
      /* Save label for netmask. */
      if (i == 3) panel->netmask_label = label;
      if (i == 3) panel->netmask_event = event_box;
      if (i == 2) panel->address_event = event_box;
    }

/*
**  The 1st control is "Name"
*/

  panel->name = gtk_entry_new ();
  gtk_signal_connect (GTK_OBJECT(panel->name), "changed",
                      (GtkSignalFunc) changed_cb, panel);
  gtk_table_attach (GTK_TABLE (table), panel->name, 1, 2, 0, 1,
                    GTK_FILL, 0, 0, 0 );

/*
**  The 2nd control is "Transport"
*/

  panel->transport = gtk_combo_new ();
  gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(panel->transport)->entry), FALSE);
  gtk_signal_connect (GTK_OBJECT(GTK_COMBO(panel->transport)->entry), "changed",
                      (GtkSignalFunc) changed_cb, panel);
  gtk_table_attach (GTK_TABLE (table), panel->transport, 1, 2, 1, 2,
                    GTK_FILL, 0, 0, 0);

/*
**  The 3rd control is "Address"
*/

  panel->address = gtk_entry_new ();
  gtk_signal_connect (GTK_OBJECT(panel->address), "changed",
                      (GtkSignalFunc) changed_cb, panel);
  gtk_table_attach (GTK_TABLE (table), panel->address, 1, 2, 2, 3,
                    GTK_FILL, 0, 0, 0 );

/*
**  The 4th control is "Netmask"
*/

  panel->netmask = gtk_entry_new ();
  gtk_signal_connect (GTK_OBJECT(panel->netmask), "changed",
                      (GtkSignalFunc) changed_cb, panel);
  gtk_table_attach (GTK_TABLE (table), panel->netmask, 1, 2, 3, 4,
                    GTK_FILL, 0, 0, 0);

/*
**  The fifth field is "Created"
*/

  panel->created = gtk_entry_new ();
  gtk_widget_set_sensitive (panel->created, FALSE);
  gtk_table_attach (GTK_TABLE (table), panel->created, 1, 2, 4, 5,
                    GTK_FILL, 0, 0, 0);

/*
**  The sixth field is "Modified"
*/

  panel->modified = gtk_entry_new ();
  gtk_widget_set_sensitive (panel->modified, FALSE);
  gtk_table_attach (GTK_TABLE (table), panel->modified, 1, 2, 5, 6,
                    GTK_FILL, 0, 0, 0);

  gtk_widget_show_all (table);
  D_FUNC_END;
}

/*******************************************************************************
**
**  Callback function for when any of the child control widgets is changed.
**  Emit a "changed" signal.
**
*******************************************************************************/

static void
changed_cb(GtkWidget *widget, gpointer data)
{
  GXsnmp_interface_panel *panel;      /* Pointer to interface panel widget */
  gint transport;
  D_FUNC_START;
  g_return_if_fail (data != NULL);
  panel = GXSNMP_INTERFACE_PANEL(data); /* Argument points to panel widget */
  gtk_signal_emit (GTK_OBJECT(panel), signals[CHANGED_SIGNAL]);

/*
**  This is just an idea how to make a dynamic changing field for the
**  netmask. IPX doesn't have such a parameter and IPv6 uses a prefix length
**  instead of the netmask. I guess this string should be part of the
**  network transport object...
*/

  transport = g_list_position(panel->transport_names,
                g_list_find_custom(panel->transport_names,
                  gtk_entry_get_text
			(GTK_ENTRY (GTK_COMBO (panel->transport)->entry)),
                  (GCompareFunc)strcmp));
 
  gtk_label_set_text(GTK_LABEL(panel->netmask_label), 
                     transport_mlabels[transport]);
  gtk_tooltips_set_tip (panel->tooltips, panel->netmask_event, 
		     transport_mtooltip[transport], NULL);
  gtk_tooltips_set_tip (panel->tooltips, panel->address_event, 
		     transport_atooltip[transport], NULL);
  D_FUNC_END;
}

/*******************************************************************************
**
**  Public function to create a new widget
**
*******************************************************************************/

GtkWidget *
gxsnmp_interface_panel_new (GList * transport_names,
			    GList * transport_values)
{
  GXsnmp_interface_panel * panel;
  D_FUNC_START;
  g_return_val_if_fail (transport_names  != NULL, NULL);
  g_return_val_if_fail (transport_values != NULL, NULL);

  panel = gtk_type_new (gxsnmp_interface_panel_get_type());

  panel->transport_names  = transport_names;
  panel->transport_values = transport_values;

  gtk_combo_set_popdown_strings (GTK_COMBO (panel->transport), transport_names);
  D_FUNC_END;
  return GTK_WIDGET (panel);
}

/*******************************************************************************
**
**  Public function to load settings into the panel widgets
**
*******************************************************************************/

void
gxsnmp_interface_panel_put_data (GXsnmp_interface_panel * panel,
                           	 DB_interface		* dbi)
{
  D_FUNC_START;
  g_return_if_fail (panel != NULL);
  g_return_if_fail (GXSNMP_IS_INTERFACE_PANEL(panel));
  g_return_if_fail (dbi != NULL);
  gtk_entry_set_text(GTK_ENTRY(panel->name), 
		     dbi->name ? dbi->name : "");
  gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(panel->transport)->entry),
    g_list_nth_data(panel->transport_names,
      g_list_index(panel->transport_values, GINT_TO_POINTER(dbi->transport))));

  gtk_entry_set_text(GTK_ENTRY(panel->address), 
		     dbi->address ? dbi->address : "");
  gtk_entry_set_text(GTK_ENTRY(panel->netmask), 
		     dbi->netmask ? dbi->netmask : "");
  gtk_entry_set_text(GTK_ENTRY(panel->created),
                     dbi->created ? dbi->created     : "");
  gtk_entry_set_text(GTK_ENTRY(panel->modified),
                     dbi->modified ? dbi->modified    : "");
  D_FUNC_END;
}

/****************************************************************************
**
**  Public function to read settings from the panel widgets
**
**  Returns TRUE if something changed, FALSE otherwise.
**
***************************************************************************/

gboolean
gxsnmp_interface_panel_get_data (GXsnmp_interface_panel * panel,
                           	 DB_interface		* dbi)
{
  gint	changed = FALSE;
  gint  i;
  D_FUNC_START;
  g_return_val_if_fail (panel != NULL, FALSE);
  g_return_val_if_fail (GXSNMP_IS_INTERFACE_PANEL(panel), FALSE);

  changed |= update_string_field (&dbi->name,
		gtk_entry_get_text(GTK_ENTRY(panel->name)));

  i = GPOINTER_TO_INT(
        g_list_nth_data(panel->transport_values,
          g_list_position(panel->transport_names,
            g_list_find_custom(panel->transport_names,
              gtk_entry_get_text
			(GTK_ENTRY (GTK_COMBO (panel->transport)->entry)),
              (GCompareFunc)strcmp))));
  changed |= (i != dbi->transport);
  dbi->transport = i;

  changed |= update_string_field (&dbi->address,
		gtk_entry_get_text(GTK_ENTRY(panel->address)));

  changed |= update_string_field (&dbi->netmask,
		gtk_entry_get_text(GTK_ENTRY(panel->netmask)));
  D_FUNC_END;
  return (changed != FALSE);
}

/* EOF */

