/* -*- Mode: C -*-
 *  $Id: menus.c,v 1.64 1999/10/07 09:10:35 jochen 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.
 *
 *  The following code implements the main menu and toolbar for the
 *  application.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gnome.h>
#include "main.h"
#include "menus.h"
#include "plugins.h"
#include "database_dialog.h"
#include "snmp_dialog.h"
#include "host_dialog.h"
#include "host_list.h"
#include "rmon_panel.h"
#include "network_dialog.h"
#include "network_list.h"
#include "map_dialog.h"
#include "gxsnmp_window.h"
#include "gxsnmp_map.h" 
#include "gxsnmp_host.h"
#include "gxsnmp_network.h"
#include "wire_host.h"

#include "debug.h"

extern gxsnmp * app_info;

/******************************************************************************
**
**  Handles for the popup menus
**
******************************************************************************/

static GtkWidget * map_popup_menu;
GtkWidget        * host_popup_menu;
GtkWidget        * network_popup_menu;

/******************************************************************************
**
**  Stuff to support the "dialogs" window
**
******************************************************************************/

typedef struct _GXsnmp_dialog
{
  GtkWidget * dialog;            /* Widget handle for an open dialog */
  gpointer    dialog_data;	 /* Pointer to data structure being edited */
  gchar	    * dialog_type;	 /* Name assigned to this dialog */
  gchar     * dialog_title;      /* Name to display in 'dialogs' menu */
  gchar     * dialog_menu_path;  /* Saved menu path for later delete */
}
GXsnmp_dialog;

static GList * dialogs = NULL;

static void dialog_activate_cb          (GtkWidget * widget, gpointer data);
static void dialog_destroy_cb		(GtkWidget * widget, gpointer data);

/******************************************************************************
**
**  Menu callback functions (really just wrappers to the real functions)
**
******************************************************************************/

static void file_new_map_cb		(GtkWidget * widget, gpointer data);
static void file_new_window_cb		(GtkWidget * widget, gpointer data);
static void file_print_cb 		(GtkWidget * widget, gpointer data);
static void file_close_cb		(GtkWidget * widget, gpointer data);
static void file_exit_cb		(GtkWidget * widget, gpointer data);

static void edit_undo_cb		(GtkWidget * widget, gpointer data);
static void edit_redo_cb		(GtkWidget * widget, gpointer data);

static void config_database_cb		(GtkWidget * widget, gpointer data);
static void config_oldconfig_cb	        (GtkWidget * widget, gpointer data);
static void config_snmp_cb		(GtkWidget * widget, gpointer data);

static void map_enable_grid_cb  	(GtkWidget * widget, gpointer data);
static void map_snap_to_grid_cb 	(GtkWidget * widget, gpointer data);

static void tools_add_host_cb   	(GtkWidget * widget, gpointer data);
static void tools_edit_host_cb		(GtkWidget * widget, gpointer data);
static void tools_delete_host_cb   	(GtkWidget * widget, gpointer data);
static void tools_add_network_cb   	(GtkWidget * widget, gpointer data);
static void tools_delete_network_cb	(GtkWidget * widget, gpointer data);

static void window_host_list_cb		(GtkWidget * widget, gpointer data);
static void window_network_list_cb      (GtkWidget * widget, gpointer data);
static void window_rmon_cb         	(GtkWidget * widget, gpointer data);
static void window_events_list_cb       (GtkWidget * widget, gpointer data);
static void window_summary_cb		(GtkWidget * widget, gpointer data);
static void window_map_list_cb		(GtkWidget * widget, gpointer data);

static void snmp_set_mib_cb		(GtkWidget * widget, gpointer data);
static void snmp_get_mib_cb             (GtkWidget * widget, gpointer data);
static void snmp_monitor_mib_cb         (GtkWidget * widget, gpointer data);
static void snmp_mib_editor_cb		(GtkWidget * widget, gpointer data);

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

static void map_popup_add_host_cb       (GtkWidget * widget, gpointer data);
static void map_popup_add_network_cb    (GtkWidget * widget, gpointer data);
static void map_popup_add_group_cb      (GtkWidget * widget, gpointer data);

static void host_popup_edit_cb          (GtkWidget * widget, gpointer data);
static void host_popup_delete_cb        (GtkWidget * widget, gpointer data);
static void host_popup_query_cb         (GtkWidget * widget, gpointer data);
static void host_popup_browse_cb        (GtkWidget * widget, gpointer data);
static void host_popup_wire_cb		(GtkWidget * widget, gpointer data);

static void network_popup_edit_cb       (GtkWidget * widget, gpointer data);
static void network_popup_delete_cb     (GtkWidget * widget, gpointer data);

static void map_group_expand_cb         (GtkWidget * widget, gpointer data);
static void map_group_collapse_cb       (GtkWidget * widget, gpointer data);
static void map_group_delete_cb         (GtkWidget * widget, gpointer data);

static void user_host_menu_cb           (GtkWidget * widget, gpointer data);
static void user_net_menu_cb            (GtkWidget * widget, gpointer data);
/*******************************************************************************
**
**  The main menu structure for the application
**
*******************************************************************************/

/*
**  The "New" submenu of the "File" menu
*/

static GnomeUIInfo new_menu[] = { 
  { GNOME_APP_UI_ITEM, N_("Map"), NULL, file_new_map_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Window"), NULL, file_new_window_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  APPMENU_FILE_NEW_MAP,
  APPMENU_FILE_NEW_WINDOW
};

/*
**  The "File" menu
*/

static GnomeUIInfo file_menu[] = {
  { GNOME_APP_UI_SUBTREE, N_("New"), NULL, new_menu, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_NEW, 0, 0, NULL },
  { GNOME_APP_UI_SEPARATOR },
  { GNOME_APP_UI_ITEM, N_("Print..."), NULL, file_print_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PRINT, 'P', 
    GDK_CONTROL_MASK, NULL },
  { GNOME_APP_UI_SEPARATOR },
  { GNOME_APP_UI_ITEM, N_("Close"), NULL, file_close_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_CLOSE, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Exit"), NULL, file_exit_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_EXIT, 'X', 
    GDK_CONTROL_MASK, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  APPMENU_FILE_NEW,
  APPMENU_FILE_SEPERATOR1,
  APPMENU_FILE_PRINT,
  APPMENU_FILE_SEPERATOR2,
  APPMENU_FILE_CLOSE,
  APPMENU_FILE_EXIT
};

/*
**  The "Edit" menu
*/

static GnomeUIInfo edit_menu[] = {
  { GNOME_APP_UI_ITEM, N_("Undo"), NULL, edit_undo_cb, NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Redo"), NULL, edit_redo_cb, NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  APPMENU_EDIT_UNDO,
  APPMENU_EDIT_REDO
};

/*
**  The "Configure" menu
*/

static GnomeUIInfo config_menu[] = {
  { GNOME_APP_UI_ITEM, N_("Database"), 
    N_("Configure and select the database engine to use."), 
    config_database_cb, NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Properties"), NULL, config_oldconfig_cb, NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("SNMP"), NULL, config_snmp_cb, NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  APPMENU_CONFIG_DATABASE,
  APPMENU_CONFIG_OLDCONFIG,
  APPMENU_CONFIG_SNMP,
  APPMENU_CONFIG_CONVERT
};

/*
**  The "Map" menu
*/

static GnomeUIInfo map_menu[] = {
  { GNOME_APP_UI_TOGGLEITEM, N_("Enable Grid"),
    N_("Toggle the visability of the grid on/off"), map_enable_grid_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_TOGGLEITEM, N_("Snap to grid"),
    N_("Enable alignment on the grid."), map_snap_to_grid_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  APPMENU_MAP_ENABLE_GRID,
  APPMENU_MAP_SNAP_TO_GRID,
};

/*
**  The "Tools" menu
*/

static GnomeUIInfo tools_menu[] = {
  { GNOME_APP_UI_ITEM, N_("Add host..."), 
    N_("Add a new host node to the map(s)"), tools_add_host_cb, NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 'A', GDK_MOD1_MASK,
    NULL },
  { GNOME_APP_UI_ITEM, N_("Delete Host..."),
    N_("Delete a host from the database and all maps"), tools_delete_host_cb, 
    NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 'D', GDK_MOD1_MASK,
    NULL },
  { GNOME_APP_UI_ITEM, N_("Add Network..."), NULL, tools_add_network_cb, 
    NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Delete Network..."), NULL, tools_delete_network_cb, 
    NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  APPMENU_TOOLS_ADD_HOST,
  APPMENU_TOOLS_DELETE_HOST,
  APPMENU_TOOLS_ADD_NETWORK,
  APPMENU_TOOLS_DELETE_NETWORK
};

/*
**  The "Window" menu
*/

static GnomeUIInfo window_menu[] = {
  { GNOME_APP_UI_ITEM, N_("Host List..."), 
    N_("Open up the list of all known host nodes."), window_host_list_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 'L', 
    GDK_MOD1_MASK, NULL },
  { GNOME_APP_UI_ITEM, N_("Network List..."), 
    N_("Open up the list of all known networks."), window_network_list_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 'N', 
    GDK_MOD1_MASK, NULL },
  { GNOME_APP_UI_ITEM, N_("RMON..."), NULL, window_rmon_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 'R', 
    GDK_MOD1_MASK, NULL },
  { GNOME_APP_UI_ITEM, N_("Events List..."), NULL, window_events_list_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 'V', 
    GDK_MOD1_MASK, NULL },
  { GNOME_APP_UI_ITEM, N_("Summary..."), NULL, window_summary_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 'S', 
    GDK_MOD1_MASK, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  APPMENU_WINDOW_HOST_LIST,
  APPMENU_WINDOW_NETWORK_LIST,
  APPMENU_WINDOW_RMON,
  APPMENU_WINDOW_EVENTS_LIST,
  APPMENU_WINDOW_SUMMARY
};
 
/*
** The "Plugins" menu
*/

static GnomeUIInfo plugin_menu[] = {
  { GNOME_APP_UI_ENDOFINFO }
};

/*
** The "Dialogs" menu
*/

static GnomeUIInfo dialog_menu[] = {
  { GNOME_APP_UI_ENDOFINFO }
};

/*
**  The "SNMP Functions" menu
*/

static GnomeUIInfo snmp_menu[] = {
  { GNOME_APP_UI_ITEM, N_("SNMP Set..."), NULL, snmp_set_mib_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("SNMP Get..."), NULL, snmp_get_mib_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Monitor Mib..."), NULL, snmp_monitor_mib_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL},
  { GNOME_APP_UI_ITEM, N_("Mib Editor..."), NULL, snmp_mib_editor_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 'M', 
    GDK_MOD1_MASK, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  APPMENU_SNMP_SET_MIB,
  APPMENU_SNMP_GET_MIB,
  APPMENU_SNMP_MONITOR_MIB,
  APPMENU_SNMP_MIB_EDITOR
};

/*
**  The "Help" menu
*/

static GnomeUIInfo help_menu[] = {
  { GNOME_APP_UI_ITEM, N_("About GXSNMP"), 
    N_("Information about this program."), help_about_cb, NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_ABOUT, 'A', GDK_CONTROL_MASK,
    NULL },
  GNOMEUIINFO_SEPARATOR,
  GNOMEUIINFO_HELP ("gxsnmp"),
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  APPMENU_HELP_ABOUT
};

/*
**  The main menu
*/

static GnomeUIInfo gxsnmp_menu[] = {
  { GNOME_APP_UI_SUBTREE, N_("_File"), NULL, file_menu, NULL, NULL, 
    GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL },
  { GNOME_APP_UI_SUBTREE, N_("_Edit"), NULL, edit_menu, NULL, NULL, 
    GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL },
  { GNOME_APP_UI_SUBTREE, N_("_Configure"), NULL, config_menu, NULL, NULL,
    GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL },
  { GNOME_APP_UI_SUBTREE, N_("_Map"), NULL, map_menu, NULL, NULL,
    GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL },
  { GNOME_APP_UI_SUBTREE, N_("_Tools"), NULL, tools_menu, NULL, NULL,
    GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL },
  { GNOME_APP_UI_SUBTREE, N_("_Windows"), NULL, window_menu, NULL, NULL,
    GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL },
  { GNOME_APP_UI_SUBTREE, N_("_Dialogs"), NULL, dialog_menu, NULL, NULL,
    GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL },
  { GNOME_APP_UI_SUBTREE, N_("_Plugins"), NULL, plugin_menu, NULL, NULL,
    GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL },
  { GNOME_APP_UI_SUBTREE, N_("_SNMP Functions"), NULL, snmp_menu, NULL, NULL,
    GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL },
  { GNOME_APP_UI_SUBTREE, N_("_Help"), NULL, help_menu, NULL, NULL,
    GNOME_APP_PIXMAP_NONE, NULL, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  APPMENU_FILE,
  APPMENU_EDIT,
  APPMENU_CONFIG,
  APPMENU_MAP,
  APPMENU_TOOLS,
  APPMENU_WINDOWS,
  APPMENU_DIALOGS,
  APPMENU_PLUGINS,
  APPMENU_SNMP,
  APPMENU_HELP
};

/*******************************************************************************
**
**  The main toolbar, gnome style.  We use all the same callbacks.
**
*******************************************************************************/

static GnomeUIInfo gxsnmp_toolbar[] = {
  { GNOME_APP_UI_ITEM, N_("Add Host"),
    N_("Add a new host to the database."), tools_add_host_cb, 
    NULL, NULL, 
    GNOME_APP_PIXMAP_FILENAME, "gxsnmp/add_host.xpm", 
    'A', GDK_MOD1_MASK, NULL },
  { GNOME_APP_UI_ITEM, N_("Edit Host"),
    N_("Edit an existing host."), tools_edit_host_cb,
    NULL, NULL,
    GNOME_APP_PIXMAP_FILENAME, "gxsnmp/edit_host.xpm",                   
    0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Delete Host"),
    N_("Delete a host from the database."), tools_delete_host_cb, 
    NULL, NULL, 
    GNOME_APP_PIXMAP_FILENAME, "gxsnmp/del_host.xpm", 
    0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Host List"),
    N_("Open the list of known hosts."), window_host_list_cb, 
    NULL, NULL, 
    GNOME_APP_PIXMAP_FILENAME, "gxsnmp/host_list.xpm", 
    0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Add Network"),
    N_("Add a new network to the map/database."), tools_add_network_cb, 
    NULL, NULL, 
    GNOME_APP_PIXMAP_FILENAME, "gxsnmp/add_net.xpm", 
    0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Delete Network"),
    N_("Delete a network from the map/database."), tools_delete_network_cb,
    NULL, NULL, 
    GNOME_APP_PIXMAP_FILENAME, "gxsnmp/del_net.xpm", 
    0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Network List"),
    N_("Open the list of known networks."), window_network_list_cb, 
    NULL, NULL, 
    GNOME_APP_PIXMAP_FILENAME, "gxsnmp/net_list.xpm", 
    0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Event Browser"), 
    N_("Open the event list."), window_events_list_cb,
    NULL, NULL, 
    GNOME_APP_PIXMAP_FILENAME, "gxsnmp/page.xpm", 
    0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Map List"),
    N_("Open the map list."), window_map_list_cb,
    NULL, NULL,
    GNOME_APP_PIXMAP_FILENAME, "gxsnmp/map_list.xpm",
    0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  APPTOOLBAR_ADD_HOST,
  APPTOOLBAR_EDIT_HOST,
  APPTOOLBAR_DELETE_HOST,
  APPTOOLBAR_HOST_LIST,
  APPTOOLBAR_ADD_NETWORK,
  APPTOOLBAR_DELETE_NETWORK,
  APPTOOLBAR_NETWORK_LIST,
  APPTOOLBAR_EVENT_LIST
};

/******************************************************************************
**
**  The map popup menu
**
******************************************************************************/

static GnomeUIInfo map_popup[] = {
  { GNOME_APP_UI_ITEM, N_("Add Host"), NULL, map_popup_add_host_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Add Network"), NULL, map_popup_add_network_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Add Group"), NULL, map_popup_add_group_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  MAP_POPUP_ADD_HOST,
  MAP_POPUP_ADD_NETWORK,
  MAP_POPUP_ADD_GROUP
};

/******************************************************************************
**
**  The host popup menu
**
******************************************************************************/

static GnomeUIInfo host_popup[] = {
  { GNOME_APP_UI_ITEM, N_("Edit Host"), NULL, host_popup_edit_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Delete Host"), NULL, host_popup_delete_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Query Host"), NULL, host_popup_query_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Browse MIB"), NULL, host_popup_browse_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Wire Host"), NULL, host_popup_wire_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  HOST_POPUP_EDIT,
  HOST_POPUP_DELETE,
  HOST_POPUP_QUERY,
  HOST_POPUP_BROWSE,
  HOST_POPUP_WIRE
};

/******************************************************************************
**
**  The network popup menu
**
******************************************************************************/

static GnomeUIInfo network_popup[] = {
  { GNOME_APP_UI_ITEM, N_("Edit Network"), NULL, network_popup_edit_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Delete Network"), NULL, network_popup_delete_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};

enum {
  NETWORK_POPUP_EDIT,
  NETWORK_POPUP_DELETE
};
/****************************************************************************
 * The map group popup menu 
 ***************************************************************************/
static GnomeUIInfo map_group_popup[] = {
  { GNOME_APP_UI_ITEM, N_("Expand Group"), NULL, map_group_expand_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Collapse Group"), NULL, map_group_collapse_cb,
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Delete Group"), NULL, map_group_delete_cb, 
    NULL, NULL, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO }
};
enum {
  MAP_GROUP_EXPAND,
  MAP_GROUP_COLLAPSE,
  MAP_GROUP_DELETE
};

/******************************************************************************
**
**  Subroutine to create all of the menus, greying out all functions that 
**  are not yet implemented.
**
******************************************************************************/

void 
menu_create (GtkWidget * main_window)
{
  user_menu  *new_entry;
  GSList     *gsl;
  GnomeUIInfo   * menu;

  D_FUNC_START;
  g_return_if_fail (main_window != NULL);

  gnome_app_create_menus_with_data (GNOME_APP (main_window), gxsnmp_menu, 
				      main_window);
  gnome_app_create_toolbar (GNOME_APP (main_window), gxsnmp_toolbar);

  map_popup_menu     = gnome_popup_menu_new (map_popup);
  host_popup_menu    = gnome_popup_menu_new (host_popup);
  network_popup_menu = gnome_popup_menu_new (network_popup);

  gsl = app_info->current_config.menu.hostsmd;
  while (gsl)
    {
      new_entry = (user_menu *)gsl->data;

      menu                  = g_malloc0 (2 * sizeof(GnomeUIInfo));
      menu->type            = GNOME_APP_UI_ITEM;
      menu->label           = g_strdup (new_entry->item);
      menu->hint            = NULL;
      menu->moreinfo        = user_host_menu_cb;
      menu->user_data       = NULL;
      menu->unused_data     = NULL;
      menu->pixmap_type     = GNOME_APP_PIXMAP_STOCK;
      menu->pixmap_info     = GNOME_STOCK_MENU_BLANK;
      menu->accelerator_key = 0;
      (menu + 1)->type      = GNOME_APP_UI_ENDOFINFO;

      gxsnmp_add_to_host_popup(menu);

      gtk_object_set_user_data (GTK_OBJECT(menu->widget), 
				g_strdup (new_entry->command));
      gsl = gsl->next;
    }

  gtk_check_menu_item_set_state (GTK_CHECK_MENU_ITEM
				 (map_menu[APPMENU_MAP_SNAP_TO_GRID].widget), 
				 TRUE);
  gtk_widget_set_sensitive (gxsnmp_menu[APPMENU_DIALOGS].widget, FALSE);

  gtk_widget_set_sensitive (new_menu[APPMENU_FILE_NEW_WINDOW].widget, FALSE);
  
  gtk_widget_set_sensitive (file_menu[APPMENU_FILE_PRINT].widget, FALSE);
  gtk_widget_set_sensitive (file_menu[APPMENU_FILE_CLOSE].widget, FALSE);
  
  gtk_widget_set_sensitive (edit_menu[APPMENU_EDIT_UNDO].widget, FALSE);
  gtk_widget_set_sensitive (edit_menu[APPMENU_EDIT_REDO].widget, FALSE);
  gtk_widget_set_sensitive (config_menu[APPMENU_CONFIG_DATABASE].widget, FALSE);
  gtk_widget_set_sensitive (map_menu[APPMENU_MAP_ENABLE_GRID].widget, FALSE);

  gtk_widget_set_sensitive (tools_menu[APPMENU_TOOLS_DELETE_HOST].widget,
			    FALSE);
  gtk_widget_set_sensitive (tools_menu[APPMENU_TOOLS_DELETE_NETWORK].widget,
			    FALSE);
  
  gtk_widget_set_sensitive (snmp_menu[APPMENU_SNMP_MIB_EDITOR].widget,
			    FALSE);
  
  gtk_widget_set_sensitive (gxsnmp_toolbar[APPTOOLBAR_EDIT_HOST].widget,
			    FALSE);
  gtk_widget_set_sensitive (gxsnmp_toolbar[APPTOOLBAR_DELETE_HOST].widget,
                            FALSE);

  gtk_widget_set_sensitive (gxsnmp_toolbar[APPTOOLBAR_DELETE_NETWORK].widget,
                            FALSE);
  D_FUNC_END;
}
/****************************************************************************
 * 
 * Simple routine to set the state of the snap to grid menu 
 * I'm sure there is a better way to do this.... GAM
 */
void
menu_set_snap_state (gboolean state)
{
  D_FUNC_START;
  gtk_signal_handler_block_by_func 
    (GTK_OBJECT (map_menu[APPMENU_MAP_SNAP_TO_GRID].widget), 
     map_snap_to_grid_cb, app_info->window);
  gtk_check_menu_item_set_state(GTK_CHECK_MENU_ITEM
				 (map_menu[APPMENU_MAP_SNAP_TO_GRID].widget),
				state);
  gtk_signal_handler_unblock_by_func 
    (GTK_OBJECT (map_menu[APPMENU_MAP_SNAP_TO_GRID].widget), 
     map_snap_to_grid_cb, app_info->window);
  D_FUNC_END;
}

/******************************************************************************
**
**  Subroutines to create the popup menus, and pop them up when selected.
**
**  Pass the GdkEventButton event to the menu popup, so that the menu popup
**  can recover the current mouse position.
**
******************************************************************************/

gint
menu_raise_map_popup (GdkEventButton *event, gpointer data)
{
  D_FUNC_START;
  gnome_popup_menu_do_popup (map_popup_menu, NULL, NULL, event, event);
  D_FUNC_END;
  return TRUE;
}

gint
menu_raise_host_popup (GdkEventButton *event, gpointer data)
{
  D_FUNC_START;
  gnome_popup_menu_do_popup (host_popup_menu, NULL, NULL, event, data);
  D_FUNC_END;
  return TRUE;
}

gint
menu_raise_network_popup (GdkEventButton *event, gpointer data)
{
  D_FUNC_START;
  gnome_popup_menu_do_popup (network_popup_menu, NULL, NULL, event, data);
  D_FUNC_END;
  return TRUE;
}

/******************************************************************************
**
**  Dialog management
**
**  In the GXSNMP dialog convention, only one dialog may exist for any
**  unique combination of dialog_data and dialog_type.
**
**  Example:  You right-click on a host and select edit.  This causes a 
**  dialog of type "edit_host" to be created against the DB_host value
**  of that entry.  With the edit dialog still open, you once again
**  right-click on the same host and select edit.  Instead of a second
**  edit window being opened, the original edit window is instead popped
**  to the top of the window. 
**
**  The External API:
**
**  gxsnmp_dialog_check  -- Looks for an existing dialog of type dialog_type
**			    and data pointer dialog_data.  If found, the
**			    corresponding widget is popped to the top of the
**			    window, and the subroutine returns TRUE. 
**			    Otherwise, the subroutine returns FALSE.
**
**  gxsnmp_dialog_add   --  Once the uniqueness of a dialog is verified by 
**			    calling gxsnmp_dialog_check, the dialog creation
**			    routine may create the desired dialog, and call
**			    gxsnmp_dialog_add to register it in the dialog
**			    list. 
**
******************************************************************************/

gboolean
gxsnmp_dialog_check (gchar	* dialog_type,
		     gpointer     dialog_data)
{
  GList         * gl;
  GXsnmp_dialog * dialog;
  D_FUNC_START;
  gl = dialogs;
  while (gl)
    {
      dialog = (GXsnmp_dialog *)gl->data;
      if (!strcmp(dialog->dialog_type, dialog_type) && /* If user is already */
          (dialog->dialog_data == dialog_data))    /* running this dialog */
        {                                          /* against this data item */
          gtk_widget_hide (dialog->dialog);  /* then pop the existing dialog */
          gtk_widget_show (dialog->dialog);  /* to the top of the window */
	  DPRT ("gxsnmp_dialog_check: pop existing dialog to top.");
	  D_FUNC_END;
          return TRUE;
        }
      gl = gl->next;
    }
  D_FUNC_END;
  return FALSE;
}

void     
gxsnmp_dialog_add (GtkWidget * dialog,
		   gchar     * dialog_type,
	           gpointer    dialog_data,
	           gchar     * dialog_title)
{
  GXsnmp_dialog * dialog_struct;
  gchar		* path;
  GnomeUIInfo   * menu;
  gchar		* title;
  D_FUNC_START;
  dialog_struct               = g_new (GXsnmp_dialog, 1);
  if (! (dialog_struct))
    {
      DPRT ("gxsnmp_dialog_add: failed to allocate memory for the dialog"
	    " structure. This can't be good...");
      D_FUNC_END;
      return;
    }
  dialog_struct->dialog       = dialog;
  dialog_struct->dialog_data  = dialog_data;
  dialog_struct->dialog_type  = dialog_type;
  dialog_struct->dialog_title = dialog_title;

  gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
                      (GtkSignalFunc) dialog_destroy_cb, dialog_struct);

  dialogs = g_list_append (dialogs, dialog_struct);
  if (g_list_length (dialogs) >= 1)
    gtk_widget_set_sensitive (gxsnmp_menu[APPMENU_DIALOGS].widget, TRUE);
  title = g_strdup_printf ("GXSNMP -- %s", gettext(dialog_title));
  gtk_window_set_title (GTK_WINDOW (dialog), title);
  g_free (title);

  gnome_dialog_set_parent (GNOME_DIALOG (dialog), 
			   GTK_WINDOW (app_info->window));

  path                  = g_strdup_printf ("%s/", gettext("_Dialogs"));
  menu 			= g_new0 (GnomeUIInfo, 2);
  if (!menu)
    {
      DPRT ("gxsnmp_dialog_add: Eeek! No memory for the menu struct?");
      g_warning ("gxsnmp_dialog_add: memory allocation failed for the "
		 "menu struct.");
      D_FUNC_END;
      return;
    }
  menu->label           = g_strdup (dialog_title);
  menu->type            = GNOME_APP_UI_ITEM;
  menu->hint            = NULL;
  menu->moreinfo        = dialog_activate_cb;  /* Activation callback */
  menu->user_data       = dialog;              /* Widget for callback */
  menu->unused_data     = NULL;
  menu->pixmap_type     = 0;
  menu->pixmap_info     = NULL;
  menu->accelerator_key = 0;
  (menu + 1)->type        = GNOME_APP_UI_ENDOFINFO;
  gnome_app_insert_menus (GNOME_APP (app_info->window), path, menu);

  dialog_struct->dialog_menu_path = 
			g_strdup_printf ("%s/%s", gettext("_Dialogs"), gettext(dialog_title));
  D_FUNC_END;
  gtk_widget_show (dialog);
}

/*
**  dialog_activate_cb is invoked when the user selects a dialog from the
**  dialog menu 
*/

static void
dialog_activate_cb (GtkWidget * widget, gpointer data)
{
  GtkWidget * dialog;
  D_FUNC_START;
  g_return_if_fail (data != NULL);
  dialog = GTK_WIDGET (data);
  gdk_window_show  (dialog->window);	/* Pop the selected dialog */
  gdk_window_raise (dialog->window);  	/* to the top of the window */
  D_FUNC_END;
}

/*
**  dialog_destroy_cb is invoked when a dialog object is destroyed.  It removes
**  the dialog from the dialog list, and removes  the corresponding menu item.
*/

static void
dialog_destroy_cb (GtkWidget * dialog, gpointer data)
{
  GXsnmp_dialog * dialog_struct;
  D_FUNC_START;
  g_return_if_fail (data != NULL);
  dialog_struct = (GXsnmp_dialog *) data;
  DPRT1 ("dialog_destroy_cb: destroy --", dialog_struct->dialog_type);
  DPRT1 ("dialog_destroy_cb:         --", dialog_struct->dialog_title);
  gnome_app_remove_menus (GNOME_APP (app_info->window), 
			  dialog_struct->dialog_menu_path, 1);

  dialogs = g_list_remove (dialogs, dialog_struct);
  g_free (dialog_struct->dialog_title);
  g_free (dialog_struct->dialog_menu_path);
  if (g_list_length (dialogs) == 0)
    gtk_widget_set_sensitive (gxsnmp_menu[APPMENU_DIALOGS].widget, FALSE);
  D_FUNC_END;
}	

/******************************************************************************
**
** Plugin menu functions
**
******************************************************************************/

static GList  *plugin_menus      = NULL;      /* List of menus */

/* 
 * Add a new menu
 */
gboolean
add_menu_entry (menu_entry *menu, gboolean enabled)
{
  D_FUNC_START;
  g_return_val_if_fail (menu != NULL, FALSE);

  plugin_menus = g_list_append (plugin_menus, menu);
  D_FUNC_END;
  return TRUE;
}

/*
 * Enable/Disable a menu item
 */
void 
set_menu_entry_state (menu_entry *entry, gboolean state)
{
  D_FUNC_START;
  g_return_if_fail (entry != NULL);
  D_FUNC_END;
}

/*
 * Unregister a menu
 */
void 
remove_menu_entry (menu_entry *entry)
{
  D_FUNC_START;
  g_return_if_fail (entry != NULL);

  g_free (entry);
  D_FUNC_END;
}


/******************************************************************************
****
****  CALLBACK FUNCTIONS BEGIN HERE
****
******************************************************************************/
 
/******************************************************************************
**
**  Callback functions for the "File" menu
**
******************************************************************************/

static void
file_new_map_cb (GtkWidget *widget, gpointer data)
{
  GtkWidget   *dialog_widget;
  D_FUNC_START;
  if (gxsnmp_dialog_check ("new_map", NULL))
    {
      DPRT ("file_new_map_cb: only add one map at a time...");
      g_warning ("Only one map should be added at a time.");
      D_FUNC_END;
      return;
    }
  dialog_widget = gxsnmp_map_dialog_new (NULL);
  if (dialog_widget)
    gxsnmp_dialog_add (dialog_widget, "new_map", NULL, 
		       g_strdup ("New Map"));
  D_FUNC_END;
}

static void
file_new_window_cb (GtkWidget *widget, gpointer data)
{
/* FIXME:  Unimplemented */
}

static void
file_print_cb (GtkWidget *widget, gpointer data)
{
/* FIXME:  Unimplemented */
}

static void
file_close_cb (GtkWidget *widget, gpointer data)
{
/* FIXME:  Unimplemented */
}

static void
file_exit_cb (GtkWidget *widget, gpointer data)
{
  D_FUNC_START;
  quit_app ();
  D_FUNC_END;
}

/*******************************************************************************
**
**  Callback functions for the "Edit" menu
**
*******************************************************************************/

static void
edit_undo_cb (GtkWidget *widget, gpointer data)
{
/* FIXME: Unimplemented */
}

static void
edit_redo_cb (GtkWidget *widget, gpointer data)
{
/* FIXME: Unimplemented */
}

/******************************************************************************
**
**  Callback functions for the "Configure" menu
**
******************************************************************************/

static void
config_database_cb (GtkWidget * widget, gpointer data)
{
  open_database_dialog ();
};

static void
config_oldconfig_cb (GtkWidget *widget, gpointer data)
{
  open_config_panel ();
}

static void config_snmp_cb (GtkWidget * widget, gpointer data)
{
  GtkWidget  * dialog_widget;
  D_FUNC_START;
  if (gxsnmp_dialog_check ("snmp_config", NULL)) /* Dialog already open? */
    return;                                      /* Yes - One at a time only */

  dialog_widget = gxsnmp_snmp_dialog_new (NULL);

  if (dialog_widget)
    gxsnmp_dialog_add (dialog_widget, "snmp_config", NULL,
                       g_strdup ("SNMP Configuration"));
  D_FUNC_END;
}

/****************************************************************************
**
**  Callback functions for the "Map" menu
**
****************************************************************************/

static void
map_enable_grid_cb (GtkWidget *widget, gpointer data)
{
/* FIXME: Unimplemented */
}

static void
map_snap_to_grid_cb (GtkWidget *widget, gpointer data)
{
  D_FUNC_START;
  toggle_snap_menu_cb(widget, data);
  D_FUNC_END;
}

/*******************************************************************************
**
**  Callback functions for the "Tools" menu
**
*******************************************************************************/

static void
tools_add_host_cb           (GtkWidget *widget, gpointer data)
{
  D_FUNC_START;
  map_popup_add_host_cb (widget, data);
  D_FUNC_END;
}

static void
tools_edit_host_cb           (GtkWidget *widget, gpointer data)
{
  /* FIXME: unimplemented */
}

static void
tools_delete_host_cb (GtkWidget *widget, gpointer data)
{
  /* FIXME: unimplemented */
}

static void
tools_add_network_cb (GtkWidget *widget, gpointer data)
{
  D_FUNC_START;
  map_popup_add_network_cb (widget, data);
  D_FUNC_END;
}

static void
tools_delete_network_cb (GtkWidget *widget, gpointer data)
{
/* FIXME: Unimplemented */
}

/****************************************************************************
**
**  Callback functions for the "Window" menu
**
*****************************************************************************/

static void
window_host_list_cb (GtkWidget *widget, gpointer data)
{
  GtkWidget   *dialog_widget;
  D_FUNC_START;
  if (gxsnmp_dialog_check ("host_list", NULL))
    return;
  dialog_widget = gxsnmp_host_list_new (NULL);
  if (dialog_widget)
    gxsnmp_dialog_add (dialog_widget, "host_list", NULL, 
		       g_strdup ("Host List"));
  D_FUNC_END;
}

static void
window_network_list_cb (GtkWidget *widget, gpointer data)
{
  GtkWidget   *dialog_widget;
  D_FUNC_START;
  if (gxsnmp_dialog_check ("network_list", NULL))
    return;
  dialog_widget = gxsnmp_network_list_new (NULL);
  if (dialog_widget)
    gxsnmp_dialog_add (dialog_widget, "network_list", NULL, 
		       g_strdup ("Network List"));
  D_FUNC_END;
}

static void
window_rmon_cb (GtkWidget *widget, gpointer data)
{
  GtkWidget   *dialog_widget;
  D_FUNC_START;
  if (gxsnmp_dialog_check ("rmon_panel", NULL))
    return;
  dialog_widget = gxsnmp_rmon_panel_new (NULL);
  if (dialog_widget)
    gxsnmp_dialog_add (dialog_widget, "rmon_panel", NULL, 
		       g_strdup ("RMON"));
  D_FUNC_END;
}

static void
window_events_list_cb (GtkWidget *widget, gpointer data)
{
  D_FUNC_START;
  open_event_panel ();
  D_FUNC_END;
}

static void
window_summary_cb (GtkWidget *widget, gpointer data)
{
  open_summary_dialog ();
}

static void
window_map_list_cb (GtkWidget *widget, gpointer data)
{
  GtkWidget  * dialog_widget;
  GXsnmp_map * map    = NULL;
  DB_map     * DB_map = NULL;
  D_FUNC_START;
  if (gxsnmp_dialog_check ("map_list", NULL))
    return;

  map = gxsnmp_window_get_current_map (GXSNMP_WINDOW (app_info->window));

  if (map)
    DB_map = map->DB_map;
  
  dialog_widget = gxsnmp_map_dialog_new (DB_map);

  if (dialog_widget)
    gxsnmp_dialog_add (dialog_widget, "map_list", NULL,
                       g_strdup ("Map List"));

  D_FUNC_END;
}



/****************************************************************************
 *
 *  Callback functions for the "Plugins" menu
 *
 ***************************************************************************/
/****************************************************************************
 * 'Helper' functions for dynamic popup menus..
 ***************************************************************************/

/**************************************************************************
 *
 *  This sucks rocks!!!!
 *
 *  Apparently, there is no easy way to extend a gnome popup list.
 *  It looks like you have to duplicate all the popup functions and hope
 *  they don't change, as the connect function is taken from gnome and the
 *  marshal function from us... Did they really oversee the need to extend
 *  a popup??? I can't believe this!!!
 *
 *************************************************************************/

static void
popup_connect_func (GnomeUIInfo *uiinfo, gchar *signal_name,
                    GnomeUIBuilderData *uibdata)
{
 
/* This doesn't seem to get used, at all... */

  g_assert (uibdata->is_interp);

  gtk_object_set_data (GTK_OBJECT (uiinfo->widget),
                       "gnome-popup-menu:toplevel_menushell_key",
                       host_popup_menu);

  gtk_signal_connect_full (GTK_OBJECT (uiinfo->widget), signal_name,
                           NULL,
                           uibdata->relay_func,
                           uiinfo->moreinfo,
                           uibdata->destroy_func,
                           FALSE,
                           FALSE);
}

typedef void (* ActivateFunc) (GtkObject *object, gpointer data);

static GtkWidget*
get_toplevel(GtkWidget* menuitem)
{
  return gtk_object_get_data (GTK_OBJECT (menuitem),
                              "gnome-popup-menu:toplevel_menushell_key");
}

static void
popup_marshal_func (GtkObject *object, gpointer data, guint n_args, GtkArg *args)
{
  ActivateFunc func;
  gpointer user_data;

  func = (ActivateFunc) data;
  user_data = gtk_object_get_data
    (GTK_OBJECT (get_toplevel(GTK_WIDGET (object))),
     "gnome_popup_menu_do_popup_user_data");

  gtk_object_set_data (GTK_OBJECT (GTK_WIDGET (object)->parent),
                       "popup_active_item", object);
  if (func)
    (* func) (object, user_data);
}


void
gxsnmp_add_to_host_popup (GnomeUIInfo *menu)
{
  GnomeUIBuilderData uibdata;

  D_FUNC_START;

  uibdata.connect_func  = popup_connect_func;
  uibdata.data          = NULL;
  uibdata.is_interp     = TRUE;
  uibdata.relay_func    = popup_marshal_func;
  uibdata.destroy_func  = NULL;

  gnome_app_fill_menu_custom (GTK_MENU_SHELL (host_popup_menu), 
			      menu, &uibdata, NULL, FALSE, 0);
  D_FUNC_END;
}

void
gxsnmp_add_to_net_popup (GnomeUIInfo *menu)
{
  GnomeUIBuilderData uibdata;

  D_FUNC_START;

  uibdata.connect_func  = popup_connect_func;
  uibdata.data          = NULL;
  uibdata.is_interp     = TRUE;
  uibdata.relay_func    = popup_marshal_func;
  uibdata.destroy_func  = NULL;

  gnome_app_fill_menu_custom (GTK_MENU_SHELL (network_popup_menu), 
			      menu, &uibdata, NULL, FALSE, 0);
  D_FUNC_END;
}

/*****************************************************************************
**
**  Callback functions for the "SNMP Functions" menu
**
*****************************************************************************/

static void
snmp_set_mib_cb (GtkWidget *widget, gpointer data)
{
  D_FUNC_START;
  open_set_panel ();
  D_FUNC_END;
}

static void
snmp_get_mib_cb (GtkWidget *widget, gpointer data)
{
  D_FUNC_START;
  open_get_panel ();
  D_FUNC_END;
}

static void 
snmp_monitor_mib_cb (GtkWidget *widget, gpointer data)
{
  D_FUNC_START;
  open_monitor_panel ();
  D_FUNC_END;
}

static void
snmp_mib_editor_cb (GtkWidget *widget, gpointer data)
{
/* FIXME: unimplemented */
}  

/*******************************************************************************
**
**  Callback functions for the "Help" menu
**
*******************************************************************************/

static void
help_about_cb (GtkWidget *widget, gpointer data)
{
  open_about_panel ();
}

/******************************************************************************
**
**  Callback functions for the "map" popup
**
**  The way we add a new host is to allocate a DB_host object, with the      
**  rowid set to zero, which means "This is a new object that is not in the
**  database", then call gxsnmp_host_dialog_new() on the object.
**  The host dialog will take things from there.
**
**  The mouse X and Y location at button press time were saved for us by
**  gxsnmp_map in x1 and y1.  These are also passed to the host_dialog_new()
**  routine so that objects added to the map are added at the mouse
**  location.
**
******************************************************************************/
static void
map_popup_add_host_cb (GtkWidget * widget, gpointer data)
{
  GXsnmp_map * map_canvas;
  gchar      * timestamp;
  GtkWidget  * dialog_widget;
  D_FUNC_START;
  if (gxsnmp_dialog_check ("add_host", NULL))   /* Dialog already open? */
    return;					/* Yes - One at a time only */

  timestamp = db_timestamp ();
  map_canvas = gxsnmp_window_get_current_map 
				(GXSNMP_WINDOW (app_info->window));
  if (!map_canvas)
    {
      DPRT ("map_popup_add_host_cb: No map canvas, create the dialog.");
      dialog_widget = gxsnmp_host_dialog_new (NULL, 0, 0);
    }
  else
    {
      DPRT ("map_popup_add_host_cb: valid map canvas.");
      dialog_widget = gxsnmp_host_dialog_new (NULL, map_canvas->x1, 
					      map_canvas->y1);
    }
  if (dialog_widget)
    gxsnmp_dialog_add (dialog_widget, "add_host", NULL,
                       g_strdup ("Add a new host"));
  D_FUNC_END;
}
/****************************************************************************
 * -- Add a new Network
 ***************************************************************************/
static void
map_popup_add_network_cb (GtkWidget * widget, gpointer data)
{
  GXsnmp_map   *map_canvas;
  gchar        *timestamp;
  GtkWidget    *dialog_widget;
  D_FUNC_START;
  if (gxsnmp_dialog_check ("add_network", NULL))
    return;
  timestamp = db_timestamp ();

  map_canvas = gxsnmp_window_get_current_map(GXSNMP_WINDOW (app_info->window));
  if (map_canvas)
    {
      dialog_widget = gxsnmp_network_dialog_new (NULL, 
						 map_canvas->x1,
						 map_canvas->y1);
    }
  else
    {
      dialog_widget = gxsnmp_network_dialog_new (NULL, 0, 0);
    }
  if (dialog_widget)
    gxsnmp_dialog_add (dialog_widget, "add_network", NULL, 
		       g_strdup (_("Add a new network")));
					     
  D_FUNC_END;
}
static void
map_popup_add_group_cb (GtkWidget *widget, gpointer data)
{
}
/******************************************************************************
**
**  Callback functions for the "host" popup
**
******************************************************************************/

static void
host_popup_edit_cb (GtkWidget * widget, gpointer data)
{
  GXsnmp_map      * map_canvas;
  GXsnmp_map_item * item;
  DB_host         * dbh;
  GtkWidget	  * dialog_widget;
  D_FUNC_START;
  g_return_if_fail (GXSNMP_IS_HOST (data));
  item = GXSNMP_MAP_ITEM (data);
  g_return_if_fail (item->DB_graph != NULL);
  g_return_if_fail (item->DB_graph->type == DB_GRAPH_HOST);
  dbh = item->DB_graph->DB_host;
  g_return_if_fail (dbh != NULL);

  map_canvas = gxsnmp_window_get_current_map
                                (GXSNMP_WINDOW (app_info->window));

  if (!gxsnmp_dialog_check ("edit_host", dbh))
    {
      dialog_widget = gxsnmp_host_dialog_new (dbh, map_canvas->x1, 
						   map_canvas->y1);
      if (dialog_widget)
        gxsnmp_dialog_add (dialog_widget, "edit_host", dbh,
		           g_strdup_printf ("Edit host '%s'", dbh->name));
    }
  D_FUNC_END;
}

static void
host_popup_delete_cb (GtkWidget * widget, gpointer data)
{
  GXsnmp_map      * map_canvas;
  GXsnmp_map_item * item;
  DB_host         * dbh;
  GtkWidget       * dialog_widget;
  D_FUNC_START;
  g_return_if_fail (GXSNMP_IS_HOST (data));
  item = GXSNMP_MAP_ITEM (data);
  g_return_if_fail (item->DB_graph != NULL);
  g_return_if_fail (item->DB_graph->type == DB_GRAPH_HOST);
  dbh = item->DB_graph->DB_host;
  g_return_if_fail (dbh != NULL);
  host_delete(dbh);
  host_destroy(dbh);
  D_FUNC_END;
}

static void
host_popup_query_cb (GtkWidget * widget, gpointer data)
{
  D_FUNC_START;
  g_warning ("FIXME: This should bring up a dialog of the 'system' mib.");
  D_FUNC_END;
}

static void
host_popup_browse_cb (GtkWidget *widget, gpointer data)
{
  GXsnmp_map_item * item;
  DB_host         * dbh;
  GtkWidget	  * dialog_widget;
  D_FUNC_START;
  g_return_if_fail (GXSNMP_IS_HOST (data));
  item = GXSNMP_MAP_ITEM (data);
  g_return_if_fail (item->DB_graph != NULL);
  g_return_if_fail (item->DB_graph->type == DB_GRAPH_HOST);
  dbh = item->DB_graph->DB_host;
  g_return_if_fail (dbh != NULL);
  if (gxsnmp_dialog_check ("mib_browser", dbh))
    return;
  dialog_widget = gxsnmp_browser_new (dbh);
  if (dialog_widget)
    gxsnmp_dialog_add (dialog_widget, "mib_browser", dbh, 
		       g_strdup ("MIB Browser"));
  D_FUNC_END;
}

static void
host_popup_wire_cb (GtkWidget * widget, gpointer data)
{
  GXsnmp_host * host;
  GXsnmp_map  * map;
  D_FUNC_START;
  g_return_if_fail (GXSNMP_IS_HOST (data));
  host = GXSNMP_HOST (data);
  map  = gxsnmp_window_get_current_map (GXSNMP_WINDOW (app_info->window));
  wire_host (host, map);
  D_FUNC_END;
}


/******************************************************************************
**
**  Callback functions for the "network" popup
**
******************************************************************************/
static void
network_popup_edit_cb (GtkWidget * widget, gpointer data)
{
  GXsnmp_map      * map_canvas;
  GXsnmp_map_item * item;
  DB_network      * dbn;
  GtkWidget       * dialog_widget;
  D_FUNC_START;
  g_return_if_fail (GXSNMP_IS_NETWORK (data));
  item = GXSNMP_MAP_ITEM (data);
  g_return_if_fail (item->DB_graph != NULL);
  g_return_if_fail (item->DB_graph->type == DB_GRAPH_NETWORK);
  dbn = item->DB_graph->DB_network;
  g_return_if_fail (dbn != NULL);
  map_canvas = gxsnmp_window_get_current_map
                                (GXSNMP_WINDOW (app_info->window));
  if (!gxsnmp_dialog_check ("edit_network", dbn))
    {
      dialog_widget = gxsnmp_network_dialog_new (dbn, 
						 map_canvas->x1,
						 map_canvas->y1);
      if (dialog_widget)
        gxsnmp_dialog_add (dialog_widget, "edit_network", dbn,
                           g_strdup_printf ("Edit network '%s'", dbn->name));
    }
  D_FUNC_END;
} 

static void
network_popup_delete_cb (GtkWidget * widget, gpointer data)
{
  GXsnmp_map      * map_canvas;
  GXsnmp_map_item * item;
  DB_network      * dbn;
  GtkWidget       * dialog_widget;
  D_FUNC_START;
  g_return_if_fail (GXSNMP_IS_NETWORK (data));
  item = GXSNMP_MAP_ITEM (data);
  g_return_if_fail (item->DB_graph != NULL);
  g_return_if_fail (item->DB_graph->type == DB_GRAPH_NETWORK);
  dbn = item->DB_graph->DB_network;
  g_return_if_fail (dbn != NULL);
  network_delete(dbn);
  network_destroy(dbn);
  D_FUNC_END;
} 

/****************************************************************************
 * Callbacks for the user menu entries
 ***************************************************************************/
static void
user_host_menu_cb (GtkWidget * widget, gpointer data)
{
  char            * command;
  GXsnmp_map_item * item;
  DB_host         * dbh;
  DB_interface    * dbi;
  GList           * gl;
  GtkWidget	  * dialog_widget;
  char            * ptr;
  char              buffer[1025];
  int               index, i;

  D_FUNC_START;
  g_return_if_fail (GXSNMP_IS_HOST (data));
  item = GXSNMP_MAP_ITEM (data);
  g_return_if_fail (item->DB_graph != NULL);
  g_return_if_fail (item->DB_graph->type == DB_GRAPH_HOST);
  dbh = item->DB_graph->DB_host;
  g_return_if_fail (dbh != NULL);
  if (!(gl = dbh->DB_interfaces))
    return;
  dbi = (DB_interface *)gl->data;
  if (!dbi->address)
    return;

  command = gtk_object_get_user_data(GTK_OBJECT(widget));

  index = 0;
  while(*command)
    {
      if((ptr = strchr(command, '%')))
        {
	  if((i = MIN(ptr - command, 1024 - index)))
	    g_memmove(&(buffer[index]), command, i);
	  index += i;
	  command = ptr + 1;
	  switch (*command)
            {
              case 'h':
		if((i = MIN(strlen(dbh->name), 1024 - index)))
		  g_memmove(&(buffer[index]), dbh->name, i);
		index += i;
		break;
              case 'n':
		if((i = MIN(strlen(dbh->dns_name), 1024 - index)))
		  g_memmove(&(buffer[index]), dbh->dns_name, i);
		index += i;
		break;
	      case 'a':
		if((i = MIN(strlen(dbi->address), 1024 - index)))
		  g_memmove(&(buffer[index]), dbi->address, i);
		index += i;
		break;
	      case 'm':
		if((i = MIN(strlen(dbi->netmask), 1024 - index)))
		  g_memmove(&(buffer[index]), dbi->netmask, i);
		index += i;
		break;
	      case 'i':
		if((i = MIN(strlen(dbi->name), 1024 - index)))
		  g_memmove(&(buffer[index]), dbi->name, i);
		index += i;
		break;
	      default:
		break;
	    }
	  command++;
	}
      else
	{
	  if((i = MIN(strlen(command), 1024 - index)))
	    g_memmove(&(buffer[index]), command, i);
	  index += i;
	  command="";
	}
    }

  buffer[index]=0;
  gnome_execute_shell(NULL, buffer);
  D_FUNC_END;
}

static void
user_net_menu_cb (GtkWidget * widget, gpointer data)
{
  D_FUNC_START;
  g_warning ("FIXME: this needs to be written.");
  D_FUNC_END;
}

/****************************************************************************
 * Callbacks for the map group popup
 ***************************************************************************/
static void
map_group_expand_cb (GtkWidget *widget, gpointer data)
{
}
static void
map_group_collapse_cb (GtkWidget *widget, gpointer data)
{
}
static void 
map_group_delete_cb (GtkWidget *widget, gpointer data)
{
}
/* 
 * I have no idea where else to put this..
 */
void
notice_dlg (char *msg, ...)
{
  va_list ap;
  gchar   buf[1024];
  
  va_start (ap, msg);
  vsnprintf (buf, sizeof(buf), msg, ap);
  va_end (ap);

  gtk_widget_show (gnome_message_box_new (buf, "info",
                                          GNOME_STOCK_BUTTON_OK, NULL));
}

/* EOF */
