/*
**  $Id: graph_panel.c,v 1.16 1999/06/14 22:38:56 gregm Exp $
**
**  GXSNMP -- An snmp management application.
**
**  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.
**
**  graph_panel.c 
**
**  graph_panel.c implements a widget that is used to enter and edit
**  information about how an item is displayed on a map.
*/

#include <gnome.h>
#include "graph_panel.h"
#include "panel_utility.h"
#include "debug.h"
/*
**  Table of descriptive labels to display as the first column of the table
*/

#define PANEL_ROWS 4

static char *graph_label[] = {
  N_("X location"),
  N_("Y location"),
  N_("Created"),
  N_("Modified")
};

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

static char *graph_tooltip[] = {
  N_("The X location on the specified map"),
  N_("The Y location on the specified map"),
  N_("Date and time this host was added to this map."),
  N_("Date and time this host map entry was changed in the database.")
};

/*
**  Signal information
*/

enum {
  CHANGED_SIGNAL,
  LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = { 0 };

static gchar * default_pixmap = "desktop.xpm";

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

static void    graph_panel_class_init 	(GXsnmp_graph_panelClass  *klass);

static void    graph_panel_init       	(GXsnmp_graph_panel       *panel);

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

/*******************************************************************************
**
**  gxsnmp_graph_panel_get_type ()
**
*******************************************************************************/

guint
gxsnmp_graph_panel_get_type()
{
  static guint gp_type = 0;

  if (!gp_type)
    {
      GtkTypeInfo gp_info =
      {
	"GXsnmp_graph_panel",
	sizeof (GXsnmp_graph_panel),
	sizeof (GXsnmp_graph_panelClass),
	(GtkClassInitFunc) graph_panel_class_init,
	(GtkObjectInitFunc) graph_panel_init,
	(GtkArgSetFunc) NULL,
	(GtkArgGetFunc) NULL
      };
      gp_type = gtk_type_unique (gtk_vbox_get_type (), &gp_info);
    }
  return gp_type;
}

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

static void
graph_panel_class_init (GXsnmp_graph_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_graph_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
graph_panel_init (GXsnmp_graph_panel *panel)
{
  GtkWidget     * entry;
  GtkTooltips	* tooltips;
  GtkStyle	* style;
  GtkWidget	* label;
  GtkWidget     * event_box;
  GtkWidget	* table;
  GtkWidget	* hbox;
  gint	      	  i;
  gint            c_width, c_height;
  D_FUNC_START;
/*
**  The controls are stored in a vbox
*/

  style = GTK_WIDGET (panel)->style;

  c_width  = gdk_string_width (style->font, "xW") / 2;
  c_height = style->font->ascent + style->font->descent;

/*
**  The first control is "Pixmap"
*/

  panel->pixmap = gnome_pixmap_entry_new ("pixmap_hist",
                                          _("Choose a Pixmap"), TRUE);
  gnome_pixmap_entry_set_preview_size (GNOME_PIXMAP_ENTRY (panel->pixmap),
                                     64, 64);
  entry = gnome_pixmap_entry_gtk_entry (GNOME_PIXMAP_ENTRY (panel->pixmap));
  gtk_signal_connect_while_alive (GTK_OBJECT(entry), "changed",
                                  (GtkSignalFunc) changed_cb,
                                  GTK_OBJECT (panel), GTK_OBJECT (entry));
  gtk_box_pack_start (GTK_BOX (panel), panel->pixmap, FALSE, FALSE, 4);
/*
**  next comes the rest of the controls, in an HBox and a table
*/

  hbox = gtk_hbox_new (FALSE, 4);
  gtk_box_pack_start (GTK_BOX (panel), hbox, FALSE, FALSE, 0);

  table = gtk_table_new (2, 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_box_pack_start (GTK_BOX (panel), table, FALSE, FALSE, 4);

  tooltips = gtk_tooltips_new ();

  for (i = 0; i < PANEL_ROWS; i++)
    {
      event_box = gtk_event_box_new ();
      gtk_widget_show (event_box);
      label = gtk_label_new (gettext (graph_label[i]));
      gtk_widget_show (label);
      gtk_container_add (GTK_CONTAINER (event_box), label);
      gtk_tooltips_set_tip (tooltips, event_box, 
			    gettext (graph_tooltip[i]), NULL);
      switch (i) 
        {
          case 0:
	    gtk_misc_set_alignment (GTK_MISC(label), 1.0, 0.5);
            gtk_box_pack_start (GTK_BOX (hbox), event_box, FALSE, FALSE, 0);
  	    panel->x = gtk_entry_new_with_max_length (10);
	    gtk_widget_set_usize (GTK_WIDGET (panel->x), c_width * 7, -1); 
	    gtk_signal_connect (GTK_OBJECT(panel->x), "changed",
	                        (GtkSignalFunc) changed_cb, panel);
	    gtk_box_pack_start (GTK_BOX (hbox), panel->x, 0, 0, 0);
            break;      

	  case 1:
            gtk_misc_set_alignment (GTK_MISC(label), 1.0, 0.5);
            gtk_box_pack_start (GTK_BOX (hbox), event_box, FALSE, FALSE, 0);
	    panel->y = gtk_entry_new_with_max_length (10);
	    gtk_widget_set_usize (GTK_WIDGET (panel->y), c_width * 7, -1);
	    gtk_signal_connect (GTK_OBJECT(panel->y), "changed",
	                        (GtkSignalFunc) changed_cb, panel);
	    gtk_box_pack_start (GTK_BOX (hbox), panel->y, 0, 0, 0);
	    break;

          case 2:
            gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.5);
            gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
			      GTK_FILL | GTK_EXPAND, 0, 0, 0);
	    panel->created = gtk_entry_new ();
	    gtk_widget_set_sensitive (panel->created, FALSE);
	    gtk_table_attach (GTK_TABLE (table), panel->created, 1, 2, 0, 1,
			      GTK_FILL, 0, 0, 0);
	    break;

          case 3:
            gtk_misc_set_alignment (GTK_MISC(label), 0.0, 0.5);
            gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 1, 2,
                              GTK_FILL, 0, 0, 0);
            panel->modified = gtk_entry_new ();
            gtk_widget_set_sensitive (panel->modified, FALSE);
            gtk_table_attach (GTK_TABLE (table), panel->modified, 1, 2, 1, 2,
                              GTK_FILL | GTK_EXPAND, 0, 0, 0);
            break;

	  default:
            break;
	}
    }
  gtk_widget_show_all (panel);
  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_graph_panel *panel;         /* Pointer to  panel widget */
  D_FUNC_START;
  g_return_if_fail (GXSNMP_IS_GRAPH_PANEL (data));

  panel = GXSNMP_GRAPH_PANEL(data);  /* Argument --> panel widget */

  gtk_signal_emit (GTK_OBJECT(panel), signals[CHANGED_SIGNAL]);
  D_FUNC_END;
}

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

GtkWidget *
gxsnmp_graph_panel_new()
{
  return GTK_WIDGET (gtk_type_new (gxsnmp_graph_panel_get_type()));
}

/****************************************************************************
**
**  Public function to copy settings from a graph object into the widgets.
**
****************************************************************************/

void
gxsnmp_graph_panel_put_data (GXsnmp_graph_panel * panel,
			    DB_graph           * dbg)
{
  gchar * numbuf;
  gchar * pixmap;
  D_FUNC_START;
  g_return_if_fail (panel != NULL);
  g_return_if_fail (GXSNMP_IS_GRAPH_PANEL(panel));
  g_return_if_fail (dbg != NULL);

  panel->rowid = dbg->rowid;
  numbuf = g_strdup_printf ("%5.2f", dbg->x);
  gtk_entry_set_text(GTK_ENTRY(panel->x), numbuf);
  g_free (numbuf);
  numbuf = g_strdup_printf ("%5.2f", dbg->y);
  gtk_entry_set_text(GTK_ENTRY(panel->y), numbuf);
  g_free (numbuf);

/*
**  FIXME: This duplicates code in gxsnmp_host.c ... jms
**  ?? -- Greg
*/

  pixmap = dbg->pixmap;
  if (pixmap == NULL)
      pixmap = default_pixmap;

  gnome_pixmap_entry_set_pixmap_subdir (GNOME_PIXMAP_ENTRY (panel->pixmap),
					"gxsnmp");
  gtk_entry_set_text (GTK_ENTRY (gnome_pixmap_entry_gtk_entry 
					(GNOME_PIXMAP_ENTRY(panel->pixmap))), 
		      pixmap);

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

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

gboolean
gxsnmp_graph_panel_get_data (GXsnmp_graph_panel * panel,
			    DB_graph           * dbg)
{
  gdouble   d;
  gint      changed = FALSE;
  D_FUNC_START;
  g_return_val_if_fail (panel != NULL, FALSE);
  g_return_val_if_fail (GXSNMP_IS_GRAPH_PANEL(panel), FALSE);
  g_return_val_if_fail (dbg != NULL, FALSE);
  if (dbg->rowid != panel->rowid)
    {
      g_warning ("gxsnmp_graph_panel_get_data: dbg->rowid != panel->rowid?");
      D_FUNC_END;
      return FALSE;
    }
  /* assignment intented */
  if ( (d = strtod (gtk_entry_get_text (GTK_ENTRY (panel->x)), NULL)) )
    {
      if (d != dbg->x)
	{
	  dbg->x = d;
	  changed = TRUE;
	}
    }
  /* assignment intended. */
  if ( (d = strtod (gtk_entry_get_text (GTK_ENTRY (panel->y)), NULL)) )
    {
      if (d != dbg->y)
	{
	  dbg->y = d;
	  changed = TRUE;
	}
    }
  changed |= update_string_field (&dbg->pixmap,
				  g_basename (gtk_entry_get_text 
				   (GTK_ENTRY (gnome_pixmap_entry_gtk_entry 
				   (GNOME_PIXMAP_ENTRY(panel->pixmap))))));
  return (changed != FALSE);
}

void
gxsnmp_graph_panel_set_state (GXsnmp_graph_panel *panel, gboolean state)
{
  D_FUNC_START;
  g_return_if_fail (panel != NULL);
  g_return_if_fail (GXSNMP_IS_GRAPH_PANEL (panel));
  
  gtk_widget_set_sensitive (GTK_WIDGET (panel->x), state);
  gtk_widget_set_sensitive (GTK_WIDGET (panel->y), state);
  gtk_widget_set_sensitive (GTK_WIDGET (panel->pixmap), state);
  D_FUNC_END;
}

/* EOF */

