/* -*- Mode: C -*-
 *  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.
 *
 *  network item widget.
 *
 *  This is the default network object type.  Graphically, it consists of a 
 *  thick horizontal line, with all hosts on the network connected to the 
 *  line via the shortest possible connecting wire.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gnome.h>
#include "dbapi.h"
#include "gxsnmp/gxsnmp_dbapi.h"
#include "gxsnmp_network.h"
#include "gxsnmp_wire.h"
#include "menus.h"

#include "debug.h"
/* GtkArg Definitions */
enum {
  NETWORK_ARG_0,
  NETWORK_ARG_LABEL,                /* Label for this network */
  NETWORK_ARG_LABEL_COLOR,          /* What color to render it */
  NETWORK_ARG_LINE_COLOR,           /* What color should the actual line be */
  NETWORK_ARG_ORIENTATION,          /* Vertical or Horizontal line? */
  NETWORK_ARG_NETWORK_POINTER       /* Fetch the pointer for the network
				       associates with this item */
};
enum {
  NETWORK_IDLE,
  NETWORK_RESIZE
};

/******************************************************************************
**
**  Forward references
**
******************************************************************************/

static void      network_class_init 	    (GXsnmp_networkClass    *klass);
static void      network_init       	    (GXsnmp_network	    *network);
static void      network_get_arg    	    (GtkObject              *object,
					     GtkArg		    *arg,
					     guint		    arg_id);
static void      network_set_arg    	    (GtkObject	            *object,
					     GtkArg                 *arg,
					     guint                  arg_id);
static void      network_move_wire  	    (GXsnmp_map_item        *network,
					     GXsnmp_wire	    *wire);
static gboolean  network_item_select        (GXsnmp_map_item        *item);
static gboolean  network_item_deselect      (GXsnmp_map_item	    *item);
static void      network_changed            (GXsnmp_map_item        *item, 
					     gpointer               data);
static gint      select_box_event           (GXsnmp_map_item        *item,
					     GdkEvent               *event,
					     GXsnmp_network         *network);
static void      network_object_updated_cb  (G_sqldb_table          *table,
					     gpointer               row,
					     G_sqldb_cb_type        type,
					     gpointer               data);
static void      graph_object_added_cb      (G_sqldb_table          *table,
					     gpointer               row,
					     G_sqldb_cb_type        type,
					     gpointer               data);
static void      graph_object_updated_cb    (G_sqldb_table          *table,
					     gpointer               row,
					     G_sqldb_cb_type        type,
					     gpointer               data);
static void      graph_object_deleted_cb    (G_sqldb_table          *table,
					     gpointer               row,
					     G_sqldb_cb_type        type,
					     gpointer               data);

/*****************************************************************************
 *  gxsnmp_network_get_type ()
 *****************************************************************************/
static GXsnmp_map_item       *parent_class;
GtkType
gxsnmp_network_get_type()
{
  static GtkType network_type = 0;

  if (!network_type)
    {
      GtkTypeInfo network_info =
      {
        "GXsnmp_network",
        sizeof (GXsnmp_network),
        sizeof (GXsnmp_networkClass),
        (GtkClassInitFunc) network_class_init,
        (GtkObjectInitFunc) network_init,
        /* reserved 1 */ NULL,
        /* reserved 2 */ NULL,
	(GtkClassInitFunc) NULL,
      };
      network_type = 
	    gtk_type_unique (gxsnmp_map_item_get_type (), &network_info);
    }
  return network_type;
}

/***************************************************************************
 *  The class initialization subroutine
 ***************************************************************************/
static void
network_class_init (GXsnmp_networkClass *klass)
{
  GtkObjectClass        *object_class;
  GXsnmp_map_itemClass  *map_item_class;
  D_FUNC_START;

  object_class   = (GtkObjectClass *)	    klass;
  map_item_class = (GXsnmp_map_itemClass *) klass;
  
  parent_class   = gtk_type_class (gxsnmp_map_item_get_type ());

  /* Argument types */
  gtk_object_add_arg_type ("GXsnmp_network::label",
			   GTK_TYPE_STRING,
			   GTK_ARG_READWRITE,
			   NETWORK_ARG_LABEL);

  /* Object methods */
  object_class->set_arg      = network_set_arg;
  object_class->get_arg      = network_get_arg;

  /* Class methods */
  map_item_class->select     = network_item_select;
  map_item_class->deselect   = network_item_deselect;
  map_item_class->move_wire  = network_move_wire;
  map_item_class->popup_menu = menu_raise_network_popup;  /* In menus.c */
  map_item_class->changed    = network_changed;

/*
** Hook into the database so that we get a callback whenever any network
** object is added, changed, or deleted.
*/

  g_sqldb_table_cb_add (network_sqldb, NULL, 
			G_SQLDB_CB_UPDATE | G_SQLDB_CB_AFTER,
			network_object_updated_cb, NULL);

  g_sqldb_table_cb_add (graph_sqldb, NULL,
			G_SQLDB_CB_ADD | G_SQLDB_CB_AFTER,
			graph_object_added_cb, NULL);

  g_sqldb_table_cb_add (graph_sqldb, NULL, 
			G_SQLDB_CB_UPDATE | G_SQLDB_CB_AFTER,
			graph_object_updated_cb, NULL);

  g_sqldb_table_cb_add (graph_sqldb, NULL, 
			G_SQLDB_CB_DELETE | G_SQLDB_CB_AFTER,
			graph_object_deleted_cb, NULL);
  D_FUNC_END;
}

/*****************************************************************************
 *  Callback subroutines for accessing arguments
 ****************************************************************************/
static void
network_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
  GXsnmp_network   *network;
  D_FUNC_START;
  g_return_if_fail (object != NULL);
  g_return_if_fail (GXSNMP_IS_NETWORK (object));
  network = GXSNMP_NETWORK (object);
  switch (arg_id)
    {
    case NETWORK_ARG_LABEL:
      gxsnmp_network_set_display_name (network, GTK_VALUE_STRING (*arg) ?
				       GTK_VALUE_STRING (*arg) : "");
      break;
    default:
      break;
    }
  D_FUNC_END;
}

static void
network_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
{
  GXsnmp_network     *network;
  GXsnmp_map_item    *network_map_item;
  GtkArg             *my_arg;
  D_FUNC_START;
  g_return_if_fail (object != NULL);
  g_return_if_fail (GXSNMP_IS_NETWORK (object));
  network          = GXSNMP_NETWORK  (object);
  network_map_item = GXSNMP_MAP_ITEM (object);
  switch (arg_id)
    {
    case NETWORK_ARG_LABEL:
      if (network->text)
	{
	  my_arg = g_new0 (GtkArg, 1);
	  my_arg[0].name = "text";
	  gtk_object_getv (GTK_OBJECT (network->text), 1, my_arg);
	  GTK_VALUE_STRING (*arg) = g_strdup (GTK_VALUE_STRING (my_arg[0]));
	  g_free (my_arg);
	}
      else
	GTK_VALUE_STRING (*arg) = NULL;
      break;
    default:
      arg->type = GTK_TYPE_INVALID;
      break;
    }
  D_FUNC_END;
}

/****************************************************************************
 *  The widget initialization callback
 *
 ***************************************************************************/
static void
network_init (GXsnmp_network * network)
{
  D_FUNC_START;
  network->line         = NULL;
  network->text         = NULL;
  network->text_color   = NULL;
  network->length	= 90.0;	/* Length of network line */
  D_FUNC_END;
}

/*****************************************************************************
**
**  The move_wire method for this network type tries to make the wire    
**  vertical if possible.
**
*****************************************************************************/

static void
network_move_wire (GXsnmp_map_item *item, GXsnmp_wire *wire)
{
  GXsnmp_network * network;
  
  double  x, y;	    /* Attachment point of the network to the map */
  double xx, yy;    /* Correct attachment point of the wire to the network */
  D_FUNC_START;
  g_return_if_fail (network != NULL);
  g_return_if_fail (GXSNMP_IS_NETWORK (item));

  network = (GXsnmp_network *)item;

  g_return_if_fail (wire != NULL);
  g_return_if_fail (GXSNMP_IS_WIRE (wire));

  x = 0.0;              /* Get the attachment point in world coordinates */
  y = 0.0;
  gnome_canvas_item_i2w (GNOME_CANVAS_ITEM (network), &x, &y);

/*
**  Figure out the correct attachment point
*/

  xx = wire->nextpoint[0];	           /* Start xx = nextpoint's x */
  xx = MAX (xx, x - network->length / 2);  /* Make sure that xx is */
  xx = MIN (xx, x + network->length / 2);  /* over the network line */
  yy = y;			           /* Use same y as the network */

/*
**  Move the attach point and indicate that our position is ADJUSTED
*/

  wire->endpoint[0] = xx;
  wire->endpoint[1] = yy;
  wire->adjuststate = WIRE_ADJUSTED;
  D_FUNC_END;
  return;
}

/******************************************************************************
**
**  The select method for a network draws a rectangle just outside of the
**  object's bounding box.
**
******************************************************************************/

static gboolean
network_item_select (GXsnmp_map_item *item)
{
  gdouble x, y, xx, yy;
  GnomeCanvasItem   *floo;
  D_FUNC_START;
  g_return_val_if_fail (item != NULL, FALSE);
  g_return_val_if_fail (GXSNMP_IS_MAP_ITEM (item), FALSE);

  x = y = xx = yy = 0.0;

  gnome_canvas_item_get_bounds (GNOME_CANVAS_ITEM (GXSNMP_NETWORK(item)->line),
                                &x, &y, &xx, &yy);
  if (item->select_box)
    gnome_canvas_item_show (item->select_box);
  else
    {
      item->select_box = gnome_canvas_item_new 
					     (GNOME_CANVAS_GROUP(item),
					      gnome_canvas_group_get_type (),
					      NULL);
      floo = gnome_canvas_item_new (GNOME_CANVAS_GROUP (item->select_box),
						gnome_canvas_rect_get_type (),
						"x1", x - 4,  "y1", y - 4,
						"x2", xx + 4, "y2", yy + 4,
						"outline_color", "black",
						"width_units", 0.0,
						NULL);
      /* Here are the handles around the item, connect to the items to 
       * implement the item resize code.
       */
      /* Left top cube */
      floo = gnome_canvas_item_new (GNOME_CANVAS_GROUP (item->select_box),
				    gnome_canvas_rect_get_type (),
				    "x1", x - 3.0, "y1", y - 1.0,
				    "x2", x + 2.0, "y2", y + 4.0,
				    "outline_color", "black",
				    "fill_color", "black",
				    "width_units", 1.0,
				    NULL);
      gtk_signal_connect (GTK_OBJECT (floo), "event", 
			  (GtkSignalFunc) select_box_event, item); 
      /* Right top cube */
      floo = gnome_canvas_item_new (GNOME_CANVAS_GROUP (item->select_box),
				    gnome_canvas_rect_get_type (),
				    "x1", xx - 2.0, "y1", y - 1.0,
				    "x2", xx + 3.0, "y2", y + 4.0,
				    "outline_color", "black",
				    "fill_color", "black",
				    "width_units", 1.0,
				    NULL);
      gtk_signal_connect (GTK_OBJECT (floo), "event",
			  (GtkSignalFunc) select_box_event, item);
    }
  D_FUNC_END;
  return TRUE;
}

/*****************************************************************************
**
**  The default deselect method is to hide the rectangle, if it exists.
**
*****************************************************************************/

static gboolean
network_item_deselect (GXsnmp_map_item * item)
{
  g_return_val_if_fail (item != NULL, FALSE);
  g_return_val_if_fail (GXSNMP_IS_MAP_ITEM (item), FALSE);
  D_FUNC_START;
  if (item->select_box)
    {
      gtk_object_destroy (item->select_box);
      item->select_box = NULL;
    }
  D_FUNC_END;
  return TRUE;          /* Item should be deselected */
}


/****************************************************************************
 * Events on the select box 'cubes'
 ***************************************************************************/
static gint
select_box_event (GXsnmp_map_item *item, GdkEvent *event,
		  GXsnmp_network *network_item)
{
  GnomeCanvas     *map_canvas;
  gdouble         cx, cy;
  gint            ix, iy;
  
  
  map_canvas = GNOME_CANVAS (GNOME_CANVAS_ITEM (item)->canvas);
  gnome_canvas_get_scroll_offsets (map_canvas, &ix, &iy);
  cx = ix * map_canvas->pixels_per_unit;
  cy = iy * map_canvas->pixels_per_unit;
  switch (event->type)
    {
    case GDK_BUTTON_PRESS:
      if (event->button.button == 1)
	{
	  d_print (DEBUG_TRACE, "Start network item resize.\n");
	  network_item->x1 = network_item->x2 = event->button.x + cx;
	  network_item->y1 = network_item->y2 = event->button.y + cy;
	  network_item->state = NETWORK_RESIZE;
	  gnome_canvas_item_grab (item, GDK_POINTER_MOTION_MASK |
				  GDK_BUTTON_RELEASE_MASK, NULL, 
				  event->motion.time);
	  return TRUE;
	}
      return FALSE;
      break;
    case GDK_MOTION_NOTIFY:
      if (network_item->state == NETWORK_RESIZE)
	{
	  gdouble    x1, y1;
	  gdouble    dx, dy;

	  x1 = event->motion.x + cx;
	  y1 = event->motion.x + cx;
	  dx = x1 - network_item->x2;
	  dy = y1 - network_item->y2;
	  network_item->x2 = x1;
	  network_item->y2 = y1;
	  gxsnmp_network_set_length (network_item, network_item->length + dx);
	  /* Update whats connected to me */
	  gtk_signal_emit_by_name (GTK_OBJECT (GNOME_CANVAS_ITEM (network_item)),
					       "move", 0, 0);
	  return TRUE;
	}
      break;
    case GDK_BUTTON_RELEASE:
      if (network_item->state == NETWORK_RESIZE)
	{
	  network_item->state = NETWORK_IDLE;
	  gnome_canvas_item_ungrab (item, event->button.time);
	}
      break;
    default:
      break;
    } 
  /* Do something clever here, like re-size the network etc.. */
  return FALSE;
}
/*****************************************************************************
**
**  Public function to create a new gxsnmp_network object          
**
*****************************************************************************/

static GXsnmp_map_item *
gxsnmp_network_default_new (DB_graph * graph)
{
  GXsnmp_network    * network;
  GXsnmp_map_item   * network_map_item;
  GnomeCanvasGroup  * root_group;
  GnomeCanvasPoints * points;
  D_FUNC_START;
  g_return_val_if_fail (graph             != NULL, NULL);
  g_return_val_if_fail (graph->DB_map     != NULL, NULL);
  g_return_val_if_fail (graph->DB_network != NULL, NULL);

  root_group = gnome_canvas_root (GNOME_CANVAS (graph->DB_map->application));

  network = GXSNMP_NETWORK (gnome_canvas_item_new (root_group, 
                                     		   gxsnmp_network_get_type (),
				     		   "x", (double)graph->x,
				     		   "y", (double)graph->y,
				     		   NULL));
  network_map_item = GXSNMP_MAP_ITEM (network);

/*
**  Point the DB_graph object and the gxsnmp_network object at each other
*/

  network_map_item->DB_graph = graph;      /* Connect the DB_graph and the */
  graph->application = network;            /* GXsnmp_map_item objects */

/*
**  Draw the network line 
*/

  points = gnome_canvas_points_new (2);

  points->coords[0] = -network->length/2;
  points->coords[2] =  network->length/2;
  points->coords[1] = -1.0;  	 
  points->coords[3] = -1.0;

  network->line = gnome_canvas_item_new (GNOME_CANVAS_GROUP (network),
                                         gnome_canvas_line_get_type (),
                                         "points", points,
                                         "fill_color", "#006600",
                                         "width_units", 1.0,
                                         NULL);
  points->coords[1] = 0.0;
  points->coords[3] = 0.0;
  network->highlight = gnome_canvas_item_new (GNOME_CANVAS_GROUP (network),
					      gnome_canvas_line_get_type (),
					      "points", points,
					      "fill_color", "#00EE00",
					      "width_units", 1.0,
					      NULL);

  points->coords[1] = 1.0;
  points->coords[3] = 1.0;
  network->shadow = gnome_canvas_item_new (GNOME_CANVAS_GROUP (network),
                                           gnome_canvas_line_get_type (),
                                           "points", points,
                                           "fill_color", "#005500",
                                           "width_units", 1.0,
                                           NULL);

  gnome_canvas_points_free (points);

  network->text_color = "black";   /* Default color */

  gxsnmp_network_set_display_name (GXSNMP_NETWORK (network), 
	    (graph->DB_network->name) ? graph->DB_network->name : "Unnamed");
  D_FUNC_END;
  return GXSNMP_MAP_ITEM (network);
}
/****************************************************************************
 * Set the display name
 ***************************************************************************/
void
gxsnmp_network_set_display_name (GXsnmp_network *network, gchar *name)
{
  D_FUNC_START;
  g_return_if_fail (network != NULL);
  g_return_if_fail (GXSNMP_IS_NETWORK (network));
  g_return_if_fail (name != NULL);
  if (network->text)
    {
      gnome_canvas_item_set (network->text, "text", name, NULL);
    }
  else
    {
      network->text = gnome_canvas_item_new (GNOME_CANVAS_GROUP (network),
					     gnome_canvas_text_get_type (),
					     "text", name,
					     "font", "fixed",
					     "x", 0.0,
					     "y", 3.0,
					     "fill_color", network->text_color,
					     "anchor", GTK_ANCHOR_NORTH,
					     NULL);
    }
  D_FUNC_END;
}
void
gxsnmp_network_set_length (GXsnmp_network *network, gdouble length)
{
  GnomeCanvasPoints    *points;

  D_FUNC_START;
  /* FIXME: if the item is selected and the select box is visable resize it.
   */
  network->length = length;
  points = gnome_canvas_points_new (2);
  points->coords[0] = -network->length/2;
  points->coords[2] = network->length/2;
  points->coords[1] = -1.0;
  points->coords[3] = -1.0;

  gnome_canvas_item_set (network->line, "points", points, NULL);
  points->coords[1] = 0.0;
  points->coords[3] = 0.0;
  gnome_canvas_item_set (network->highlight, "points", points, NULL);
  points->coords[1] = 1.0;
  points->coords[3] = 1.0;
  gnome_canvas_item_set (network->shadow, "points", points, NULL);
  gnome_canvas_points_free (points);
}

/*******************************************************************************
**
**  Public function to create a new widget
**
**  This is the function to call to add a network to the map.  The returned
**  widget may be a gxsnmp_network object, or may be an object derived from
**  type gxsnmp_network.
**
**  The general strategy here is to use plugins.  For instance, we might
**  have a plugin that implements a widget to represent an ethernet.
**
**  Each plugin will register two items ... the type of the item, and
**  a subroutine to decide whether or not to handle the item.
**
**  The plugin's decision as to whether or not to represent the network may
**  be based on any of the contents of the network structure.
**
**  Since a gxsnmp_network widget contains map-specific information, it will
**  be necessary to create a separate widget for each map.  The widget
**  will contain a pointer to the network structure, and the network structure
**  will contain a glist of all widgets that refer to it.
**
**  Thus, when a change is made to a network through the network structure, the
**  change can be easily propagated to all of the map widgets.
**
**  It is the responsibility of the calling routine to add this widget to
**  the correct map, and to gtk_widget_show() it.
**
*******************************************************************************/

GXsnmp_map_item *
gxsnmp_network_new (DB_graph * graph)
{
  GXsnmp_network * network;

  D_FUNC_START;
  d_print (DEBUG_OBJECTS, "New network object.\n");
  g_return_val_if_fail (graph != NULL, NULL);

/*
**  Here, we will run through the plugin list, asking each plugin if it
**  wants to represent this network. If someone answers up, call the new()
**  method in that plugin, which should return a map_item that we can return.
**
*/

/* FIXME:  Write me */

/*
**  None of the plugins replied, so we'll just use the default.
**  Actually, there is no reason why this shouldn't be a plugin also.
*/

  network = GXSNMP_NETWORK (gxsnmp_network_default_new (graph));
  D_FUNC_END;
  return GXSNMP_MAP_ITEM (network);
}
/****************************************************************************
 * This g_hook callback function is invoked every time a network object is
 * changed. It runs through the graph list for the network and emits the
 * changed signal to all of the GXsnmp_network item.
 ***************************************************************************/
static void
network_object_updated_cb (G_sqldb_table *table, gpointer row, 
			   G_sqldb_cb_type type, gpointer data)
{
  DB_network       *dbn;
  DB_graph         *dbg;
  GXsnmp_map_item  *map_item;
  GList            *gl;
  D_FUNC_START;
  dbn = (DB_network *)row;
  d_print (DEBUG_DUMP, "Update %s\n", dbn->name);
  gl = dbn->DB_graphs;
  while (gl)
    {
      dbg = (DB_graph *)gl->data;
      if (dbg->type != DB_GRAPH_NETWORK)
	{
	  d_print (DEBUG_DUMP, "Invoked with a non network object.\n");
	  D_FUNC_END;
	  return;
        }
      g_assert (dbg->application != NULL);
      map_item = GXSNMP_MAP_ITEM (dbg->application);
      gtk_signal_emit_by_name (GTK_OBJECT (map_item), "changed", NULL);
      gl = gl->next;
    }
  D_FUNC_END;
}
/****************************************************************************
 * This g_hook callback function is invoked every time a graph object is
 * added.
 ***************************************************************************/
static void
graph_object_added_cb (G_sqldb_table *table, gpointer row,
		       G_sqldb_cb_type type, gpointer data)
{
  DB_graph     *dbg;
  dbg = (DB_graph *) row;
  D_FUNC_START;
  if (dbg->type != DB_GRAPH_NETWORK)
    {
      d_print (DEBUG_TRACE, "Invoked with a non network object.\n");
      D_FUNC_END;
      return;
    }
  gxsnmp_network_new (dbg);
  D_FUNC_END;
}
/****************************************************************************
 * This g_hook callback function is invoked every time a graph object is
 * changed. It emits the changed signal to that particular graph
 ***************************************************************************/
static void
graph_object_updated_cb (G_sqldb_table *table, gpointer row,
			 G_sqldb_cb_type type, gpointer data)
{
  DB_graph          *dbg;
  GXsnmp_map_item   *map_item;
  D_FUNC_START;
  dbg = (DB_graph *)row;
  if (dbg->type != DB_GRAPH_NETWORK)
    {
      d_print (DEBUG_TRACE, "Invoked with a non network object.\n");
      D_FUNC_END;
      return;
    }
  g_assert (dbg->application != NULL);
  map_item = GXSNMP_MAP_ITEM (dbg->application);
  gtk_signal_emit_by_name (GTK_OBJECT (map_item), "changed", NULL);
  D_FUNC_END;
}
/****************************************************************************
 * This g_hook callback function is invoked every time a graph object is
 * deleted from the database. It destroys the corresponding map_item.
 ***************************************************************************/
static void
graph_object_deleted_cb (G_sqldb_table *table, gpointer row,
			 G_sqldb_cb_type type, gpointer data)
{
  DB_graph         *dbg;
  GXsnmp_map_item  *map_item;

  D_FUNC_START;
  g_return_if_fail (row != NULL);
  dbg = (DB_graph *)row;
  if (dbg->type != DB_GRAPH_NETWORK)
    {
      d_print (DEBUG_TRACE, "Invoked with a non network object.\n");
      D_FUNC_END;
      return;
    }
  if (dbg->application)
    {
      map_item = GXSNMP_MAP_ITEM (dbg->application);
      if (map_item)
	gtk_signal_emit_by_name (GTK_OBJECT (map_item), "destroy", NULL);
    }
  D_FUNC_END;
}
/***************************************************************************
 * Signal handler for the "changed" signal
 *
 * This signal handler is invoked whenever something elsewhere in the gxsnmp
 * mes^H^H^Hsystem changes the underlying data structure owned by this 
 * map_item. The response here is to rebuild and redisplay the network.
 ***************************************************************************/
static void
network_changed (GXsnmp_map_item *item, gpointer data)
{
  GXsnmp_network   *network;
  DB_graph         *graph;
  D_FUNC_START;

  network = GXSNMP_NETWORK (item);
  g_return_if_fail (item->DB_graph != NULL);
  graph = item->DB_graph;
  if (!network->text_color)
    network->text_color = "black";
  if (graph->DB_network->name)
    gxsnmp_network_set_display_name (network, graph->DB_network->name);
  else
    gxsnmp_network_set_display_name (network, "(unnamed)");
  D_FUNC_END;
}

/* EOF */
