/*
 * $Id: browser.c,v 1.1 1999/04/05 22:09:42 jochen Exp $
 * GXSNMP - An snmp managment 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 mib browser panel.
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "main.h"
#include "structs.h"
#include "protos.h"

static void       create_browser_panel          (void);
static void       build_mib_tree                (void);
static void       fill_combo_list               (void);
static void       combo_foreach_func            (void        *key, 
						 void        *val, 
						 void        *data);
static void       close_browser_cb              (GtkWidget   *widget,
						 gpointer    data);
static void       first_button_cb               (GtkWidget   *widget,
						 gpointer    data);
static void       next_button_cb                (GtkWidget   *widget,
						 gpointer    data);
static void       get_button_cb                 (GtkWidget   *widget,
						 gpointer    data);
static void       put_button_cb                 (GtkWidget   *widget,
						 gpointer    data);
static gint       panel_delete_cb               (GtkWidget   *widget,
						 GdkEvent    *e,
						 gpointer    data);
static void       cb_tree_changed               (GtkTree     *tree);
static void       refresh_mib_tree              (hosts       *host);

extern gxsnmp *app_info;
static GList  *cbitems = NULL;

#ifdef UCD_SNMP
extern struct module *module_head;

static char * 
module_name (int modid )
{
  struct module *mp;
  char *cp;
  
  for ( mp=module_head ; mp ; mp=mp->next )
    if ( mp->modid == modid )
      return(mp->name);
  return(NULL);
}
#endif

hosts *
get_browser_host ()
{
  char *host;

  host = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(app_info->brows_panel->mib_host)->entry));
  if (app_info->host_hash)
    return g_hash_table_lookup(app_info->host_hash, host);
  else
    return NULL;
}

static void
fill_combo_list ()
{
  if (app_info->host_hash)
    g_hash_table_foreach (app_info->host_hash, combo_foreach_func, NULL);
  if (cbitems != NULL)
    gtk_combo_set_popdown_strings (GTK_COMBO (app_info->brows_panel->mib_host),
				   cbitems);
}

static void
combo_foreach_func (void *key, void *val, void *data)
{
  cbitems = g_list_append (cbitems, (char *)key);
}

static void
getoid (struct tree *snmptree, char *buffer)
{
  *buffer = 0;
  if (snmptree->parent)
    getoid (snmptree->parent, buffer);
  sprintf(buffer + strlen (buffer), ".%ld", snmptree->subid);
}

static void
getlabel (struct tree *snmptree, char *buffer)
{
  *buffer = 0;
  if (snmptree->parent)
    getlabel (snmptree->parent, buffer);
  sprintf (buffer + strlen (buffer), ".%s", snmptree->label);
}

/*
 * Get the list of the enumerated values for this object.
 *
 * This is the (up, down, testing... etc stuff)
 */
static void
get_enums (struct tree *snmptree)
{
  struct enum_list  *elist;
  char              buf[80];
  if (snmptree->enums)
    {
      elist = snmptree->enums;
      sprintf (buf, _("\nAvailable values\n"));
      gtk_text_insert (GTK_TEXT (app_info->brows_panel->mib_desc), NULL,
		       &(app_info->brows_panel->mib_desc)->style->black,
		       NULL, buf, strlen(buf));
      while (elist)
	{
	  sprintf (buf, "%s (%d)\n", elist->label, elist->value);
	  gtk_text_insert (GTK_TEXT (app_info->brows_panel->mib_desc), NULL,
			   &(app_info->brows_panel->mib_desc)->style->black,
			   NULL, buf, -1);
	  elist = elist->next;
	}
    }
}

static void 
cb_tree_changed(GtkTree* tree) 
{
  GList       *selected;
  GtkTreeItem *selected_item;
  gint        nb_selected;
  guint       length;
  struct tree *snmptree;
  char        *buffer;
  char        oidbuf[1024];

  selected    = tree->selection;
  nb_selected = g_list_length(selected);
  if (nb_selected != 1) 
    return;
      
  selected_item = GTK_TREE_ITEM(selected->data);
      
  snmptree = gtk_object_get_user_data(GTK_OBJECT(selected_item));

  gtk_text_set_point(GTK_TEXT (app_info->brows_panel->mib_desc),0);
  length = gtk_text_get_length(GTK_TEXT (app_info->brows_panel->mib_desc));
  gtk_text_forward_delete(GTK_TEXT (app_info->brows_panel->mib_desc),length);
  switch (snmptree->type)
    {
    case 1:
      buffer = _("Object ID");
      break;
    case 2:
      buffer = _("String");
      break;
    case 3:
      buffer = _("Integer");
      break;
    case 4:
      buffer = _("Network Address");
      break;
    case 5:
      buffer = _("IP Address");
      break;
    case 6:
      buffer = _("Counter");
      break;
    case 7:
      buffer = _("Gauge");
      break;
    case 8:
      buffer = _("TimeTicks");
      break;
    case 9:
      buffer = _("Opaque");
      break;
    case 10:
      buffer = _("NULL");
      break;
    case 11:
      buffer = _("Counter64");
      break;
    case 12:
      buffer = _("Bitstring");
      break;
    case 13:
      buffer = _("NSAP Address");
      break;
    case 14:
      buffer = _("Unsigned Integer");
      break;
    default:
      buffer = _("Unknown");
    }
  gtk_entry_set_text (GTK_ENTRY (app_info->brows_panel->mib_type), buffer);
  getoid (snmptree, oidbuf);

  gtk_entry_set_text (GTK_ENTRY (app_info->brows_panel->mib_oid), oidbuf);
  getlabel (snmptree, oidbuf);
  gtk_entry_set_text (GTK_ENTRY (app_info->brows_panel->mib_label), oidbuf);
  if (snmptree->description) 
    {
      gtk_text_insert (GTK_TEXT (app_info->brows_panel->mib_desc), NULL, 
		       &(app_info->brows_panel->mib_desc)->style->black, 
		       NULL, snmptree->description, strlen
		       (snmptree->description));
    }
  get_enums (snmptree);
  gtk_text_thaw (GTK_TEXT (app_info->brows_panel->mib_desc));
  gtk_widget_set_sensitive (GTK_WIDGET (app_info->brows_panel->nbutton), 
			    FALSE);
}

static void 
create_tree_item(GtkWidget* parent, struct tree *snmptree) 
{
  char buffer[255];
  GtkWidget *item, *tree;   

  while (snmptree) 
    {
      gtk_main_iteration_do(FALSE); /* keep the UI from locking up */
      if (snmptree->label)
	sprintf(buffer,"%s (%ld)", snmptree->label, snmptree->subid);
      else
	sprintf(buffer,"(%ld)", snmptree->subid);
      item = gtk_tree_item_new_with_label(buffer);
      gtk_tree_append(GTK_TREE(parent), item);
      gtk_object_set_user_data(GTK_OBJECT(item), (gpointer)snmptree);
      gtk_widget_show(item);

      if (snmptree->child_list) 
	{  
	  tree = gtk_tree_new();
	  gtk_signal_connect(GTK_OBJECT(tree), "selection_changed",
			     (GtkSignalFunc)cb_tree_changed,
			     (gpointer)NULL);
	  create_tree_item(tree, snmptree->child_list);
	  gtk_tree_item_set_subtree(GTK_TREE_ITEM(item), tree);
	}
      snmptree = snmptree->next_peer;
    }
}
/*
 * Moved this here cause with the cmu snmp lib at least it takes a few
 * seconds for the window to appear, so we'll build the window, show it,
 * stick a watch cursor up, build and insert the tree, and restore the
 * normal cursor.
 */
static void
build_mib_tree ()
{
  GtkWidget           *root_item;
  GtkWidget           *root_subtree;

  update_statusbar (_("Constructing the mib tree."));
  root_item = gtk_tree_item_new_with_label (".");
  gtk_tree_append (GTK_TREE (app_info->brows_panel->root), root_item);
  gtk_object_set_user_data (GTK_OBJECT (root_item), (gpointer)Mib);
  gtk_widget_show (root_item);
  root_subtree = gtk_tree_new();
  gtk_signal_connect (GTK_OBJECT (root_subtree), "selection_changed",
		      GTK_SIGNAL_FUNC (cb_tree_changed),
		      NULL);
  create_tree_item (root_subtree, Mib);
  gtk_tree_item_set_subtree (GTK_TREE_ITEM (root_item), root_subtree);
  gtk_tree_item_expand (GTK_TREE_ITEM (root_item));
  update_statusbar (_("Mib tree built."));
  gtk_widget_set_sensitive (GTK_WIDGET (app_info->brows_panel->root), TRUE);
}
static void
create_browser_panel ()
{
  GtkWidget    *frame;
  GtkWidget    *vbox;
  GtkWidget    *hbox;
  GtkWidget    *right_box;
  GtkWidget    *left_box;
  GtkWidget    *hscroll;
  GtkWidget    *vscroll;
  GtkWidget    *label;
  GtkWidget    *table;
  GtkWidget    *scrolled_window;
  GtkWidget    *button_box;
  GtkWidget    *pixmap;
  GtkWidget    *bar;
  GtkWidget    *button;
  hosts        *host;

  app_info->brows_panel = (browser_panel *)g_malloc (sizeof (browser_panel));
  app_info->brows_panel->window = gnome_app_new ("GXSNMP", _("Mib Browser"));
  gtk_signal_connect (GTK_OBJECT (app_info->brows_panel->window),
		      "delete_event",
		      GTK_SIGNAL_FUNC (panel_delete_cb),
		      NULL);
/*  host = get_current_host (GTK_WIDGET (app_info->brows_panel)); */
  vbox = gtk_vbox_new (FALSE, 4);
  gnome_app_set_contents (GNOME_APP (app_info->brows_panel->window), vbox);

  frame = gtk_frame_new (NULL);
  gtk_container_border_width (GTK_CONTAINER (frame), 2);
  gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 1);
  vbox = gtk_vbox_new (FALSE, 2);
  gtk_container_border_width (GTK_CONTAINER (vbox), 4);
  gtk_container_add (GTK_CONTAINER (frame), vbox);
  hbox = gtk_hbox_new (FALSE, 2);
  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
  left_box = gtk_vbox_new (FALSE, 2);
  gtk_box_pack_start (GTK_BOX (hbox), left_box, TRUE, TRUE, 0);
  right_box = gtk_vbox_new (FALSE, 2);
  gtk_box_pack_start (GTK_BOX (hbox), right_box, FALSE, FALSE, 2);

  frame = gtk_frame_new (NULL);
  gtk_box_pack_start (GTK_BOX (right_box), frame, FALSE, FALSE, 0);
  table = gtk_table_new ( 5, 2, FALSE);
  gtk_container_add (GTK_CONTAINER (frame), table);
  label = gtk_label_new (_("Object Type"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
		    GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
  app_info->brows_panel->mib_type = gtk_entry_new ();
  gtk_entry_set_editable (GTK_ENTRY (app_info->brows_panel->mib_type), FALSE);
  gtk_table_attach (GTK_TABLE (table), app_info->brows_panel->mib_type,
		    1, 2, 0, 1,
		    GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
  label = gtk_label_new (_("OID"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
		    GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
  app_info->brows_panel->mib_oid = gtk_entry_new ();
  gtk_entry_set_editable (GTK_ENTRY (app_info->brows_panel->mib_oid), FALSE);
  gtk_table_attach (GTK_TABLE (table), app_info->brows_panel->mib_oid, 
		    1, 2, 1, 2,
		    GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
  label = gtk_label_new (_("Label"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
		    GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
  app_info->brows_panel->mib_label = gtk_entry_new ();
  gtk_entry_set_editable (GTK_ENTRY (app_info->brows_panel->mib_label), FALSE);
  gtk_table_attach (GTK_TABLE (table), app_info->brows_panel->mib_label,
		    1, 2, 2, 3, 
		    GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
  label = gtk_label_new (_("Value"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
		    GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
  app_info->brows_panel->mib_value = gtk_entry_new ();
  gtk_table_attach (GTK_TABLE (table), app_info->brows_panel->mib_value,
		    1, 2, 3, 4,
		    GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
  label = gtk_label_new (_("Host"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5,
		    GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
  app_info->brows_panel->mib_host = gtk_combo_new ();
  if (app_info->host_hash == NULL)
    {
      gtk_entry_set_text (GTK_ENTRY (GTK_COMBO 
				     (app_info->brows_panel->mib_host)->entry),
			  "<none>");
    }
  else
    {
      if (host)
	gtk_entry_set_text (GTK_ENTRY (GTK_COMBO
			    (app_info->brows_panel->mib_host)->entry),
			    host->hl_snmp.name);
    }
  gtk_table_attach (GTK_TABLE (table), app_info->brows_panel->mib_host,
		    1, 2, 4, 5,
		    GTK_EXPAND | GTK_SHRINK | GTK_FILL, GTK_SHRINK, 2, 2);
  gtk_widget_show (app_info->brows_panel->mib_host);

  gtk_widget_show (table);

  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
  gtk_box_pack_start (GTK_BOX (left_box), scrolled_window, TRUE, TRUE, 0);
  gtk_widget_set_usize (GTK_WIDGET (scrolled_window), 250, 250);
  gtk_widget_show (scrolled_window);

  app_info->brows_panel->root = gtk_tree_new ();
  gtk_tree_set_selection_mode (GTK_TREE (app_info->brows_panel->root), 
			       GTK_SELECTION_SINGLE);
  gtk_container_add (GTK_CONTAINER (scrolled_window), 
		     app_info->brows_panel->root);
  gtk_signal_connect(GTK_OBJECT(app_info->brows_panel->root),
                     "selection_changed",
                     (GtkSignalFunc)cb_tree_changed,
                     (gpointer)NULL);
  gtk_widget_set_sensitive (GTK_WIDGET (app_info->brows_panel->root), FALSE);
  gtk_widget_show (app_info->brows_panel->root);

  label = gtk_label_new (_("Description"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.1);
  gtk_box_pack_start (GTK_BOX (right_box), label, FALSE, FALSE, 0);
  gtk_widget_show (label);

  table = gtk_table_new (2, 2, FALSE);
  gtk_table_set_row_spacing (GTK_TABLE (table), 0, 2);
  gtk_table_set_col_spacing (GTK_TABLE (table), 0, 2);
  gtk_box_pack_start (GTK_BOX (right_box), table, FALSE, TRUE, 0);
  app_info->brows_panel->mib_desc = gtk_text_new (NULL, NULL);
  gtk_text_set_editable (GTK_TEXT (app_info->brows_panel->mib_desc), FALSE);
  gtk_widget_set_usize (GTK_WIDGET (app_info->brows_panel->mib_desc), 
			350, 200);
  GTK_TEXT(app_info->brows_panel->mib_desc)->line_wrap = FALSE;
  gtk_table_attach_defaults (GTK_TABLE (table), 
			     app_info->brows_panel->mib_desc, 0, 1, 0, 1);
  gtk_widget_show (app_info->brows_panel->mib_desc);
  hscroll = gtk_hscrollbar_new (GTK_TEXT 
				(app_info->brows_panel->mib_desc)->hadj);
  gtk_table_attach (GTK_TABLE (table), hscroll, 0, 1, 1, 2,
		    GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (hscroll);
  vscroll = gtk_vscrollbar_new (GTK_TEXT 
				(app_info->brows_panel->mib_desc)->vadj);
  gtk_table_attach (GTK_TABLE (table), vscroll, 1, 2, 0, 1,
		    GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  gtk_widget_show (vscroll);
  gtk_widget_show (table);
  bar = gtk_hseparator_new ();
  gtk_box_pack_start (GTK_BOX (right_box), bar, FALSE, FALSE, 0);
  gtk_widget_show (bar);
  frame = gtk_frame_new (NULL);
  gtk_box_pack_start (GTK_BOX (right_box), frame, FALSE, FALSE, 0);
  gtk_widget_show (frame);
  button_box = gtk_hbutton_box_new ();
  gtk_container_border_width (GTK_CONTAINER (button_box), 2);
  gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), 
			     GTK_BUTTONBOX_SPREAD);
  gtk_button_box_set_spacing (GTK_BUTTON_BOX (button_box), 2);
  gtk_button_box_set_child_size (GTK_BUTTON_BOX (button_box), 85, 20);
  gtk_container_add (GTK_CONTAINER (frame), button_box);
  gtk_widget_show (button_box);
  /* 
     Get and put current mib buttons
  */
  app_info->brows_panel->fbutton = gtk_button_new_with_label (_("First"));
  gtk_signal_connect (GTK_OBJECT (app_info->brows_panel->fbutton), "clicked",
		      GTK_SIGNAL_FUNC (first_button_cb),
		      NULL);
  gtk_container_add (GTK_CONTAINER (button_box), 
		     app_info->brows_panel->fbutton);
  gtk_widget_show (app_info->brows_panel->fbutton);
  app_info->brows_panel->nbutton = gtk_button_new_with_label (_("Next"));
  gtk_signal_connect (GTK_OBJECT (app_info->brows_panel->nbutton), "clicked",
		      GTK_SIGNAL_FUNC (next_button_cb),
		      NULL);
  gtk_container_add (GTK_CONTAINER (button_box),
		     app_info->brows_panel->nbutton);
  gtk_widget_set_sensitive (app_info->brows_panel->nbutton, FALSE);
  gtk_widget_show (app_info->brows_panel->nbutton);
  app_info->brows_panel->gbutton = gtk_button_new_with_label (_("Get"));
  gtk_signal_connect (GTK_OBJECT (app_info->brows_panel->gbutton), "clicked",
		      GTK_SIGNAL_FUNC (get_button_cb),
		      NULL);
  gtk_container_add (GTK_CONTAINER (button_box), 
		     app_info->brows_panel->gbutton);
  gtk_widget_set_sensitive (app_info->brows_panel->gbutton, FALSE);
  gtk_widget_show (app_info->brows_panel->gbutton);
  app_info->brows_panel->pbutton = gtk_button_new_with_label (_("Put"));
  gtk_signal_connect (GTK_OBJECT (app_info->brows_panel->pbutton), "clicked",
		      GTK_SIGNAL_FUNC (put_button_cb),
		      NULL);
  gtk_container_add (GTK_CONTAINER (button_box), 
		     app_info->brows_panel->pbutton);
  gtk_widget_show (app_info->brows_panel->pbutton);
  /*
    ----------------
  */
  bar = gtk_hseparator_new ();
  gtk_box_pack_start (GTK_BOX (vbox), bar, FALSE, FALSE, 0);
  gtk_widget_show (bar);
  frame = gtk_frame_new (NULL);
  gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
  gtk_widget_show (frame);
  button_box = gtk_hbutton_box_new ();
  gtk_container_border_width (GTK_CONTAINER (button_box), 2);
  gtk_button_box_set_layout (GTK_BUTTON_BOX (button_box), 
			     GTK_BUTTONBOX_SPREAD);
  gtk_button_box_set_spacing (GTK_BUTTON_BOX (button_box), 2);
  gtk_button_box_set_child_size (GTK_BUTTON_BOX (button_box), 85, 20);
  gtk_container_add (GTK_CONTAINER (frame), button_box);
  gtk_widget_show (button_box);
  button = gnome_stock_button (GNOME_STOCK_BUTTON_CLOSE);
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
		      GTK_SIGNAL_FUNC (close_browser_cb),
		      NULL);
  gtk_container_add (GTK_CONTAINER (button_box), button);
  gtk_widget_show (button);
  pixmap = gnome_stock_pixmap_widget (app_info->brows_panel->window, 
				      GNOME_STOCK_PIXMAP_REFRESH);
  app_info->brows_panel->rbutton = gnome_pixmap_button (pixmap,
							      _("Refresh"));
  gtk_signal_connect (GTK_OBJECT (app_info->brows_panel->rbutton), "clicked",
		      GTK_SIGNAL_FUNC (refresh_mib_tree),
		      NULL);
  if (host)
    if (app_info->current_host == NULL)
      gtk_widget_set_sensitive (GTK_WIDGET (app_info->brows_panel->rbutton),
				FALSE);
  gtk_container_add (GTK_CONTAINER (button_box),
		     app_info->brows_panel->rbutton);
  gtk_widget_show_all (app_info->brows_panel->window);
}

static void
close_browser_cb (GtkWidget *widget, gpointer data)
{
  hide_browser_panel ();
}

static void
first_button_cb (GtkWidget *widget, gpointer data)
{
  hosts        *host;
  GList        *sel;
  GtkTreeItem  *sel_item;
  struct tree  *snmptree;
  char         oidbuf[1024];
  GSList       *objs;
  SNMP_OBJECT  *obj;

  objs = NULL;

  if ( (host = get_browser_host()))
    {
      sel = GTK_TREE (app_info->brows_panel->root)->selection;
      if ( (g_list_length (sel)) != 1)
	return;
      sel_item = GTK_TREE_ITEM (sel->data);
      snmptree = gtk_object_get_user_data (GTK_OBJECT (sel_item));
      getoid (snmptree, oidbuf);

      host->hl_snmp.magic = host;
      host->hl_snmp.time_callback = update_mib_timeout;
      host->hl_snmp.done_callback = update_mib_value;

      g_pdu_add_name(&objs, oidbuf, SNMP_NULL, NULL);
      obj = (SNMP_OBJECT *)objs->data;
      host->root_length = obj->id_len;
      memcpy(host->root, obj->id,
             host->root_length * sizeof(gulong));
      g_async_getnext(&host->hl_snmp, objs);

    }
  else
    {
      g_print ("No host selected?\n");
    }
  return;
}
static void
get_button_cb (GtkWidget *widget, gpointer data)
{
  hosts        *host;
  GSList       *objs;

  objs = NULL;
  if ( (host = get_browser_host()))
    {
      host->hl_snmp.magic = host;
      host->hl_snmp.time_callback = update_mib_timeout;
      host->hl_snmp.done_callback = update_mib_value;
      g_pdu_add_oid(&objs, host->name, host->name_length, SNMP_NULL, NULL);
      g_async_get(&host->hl_snmp, objs);
    }
  else
    {
      g_print ("No host selected?\n");
    }
  return;
}

static void
next_button_cb (GtkWidget *widget, gpointer data)
{
  hosts        *host;
  GSList       *objs;

  objs = NULL;
  if ( (host = get_browser_host()))
    {
      host->hl_snmp.magic = host;
      host->hl_snmp.time_callback = update_mib_timeout;
      host->hl_snmp.done_callback = update_mib_value;
      g_pdu_add_oid(&objs, host->name, host->name_length, SNMP_NULL, NULL);
      g_async_getnext(&host->hl_snmp, objs);
      gtk_widget_set_sensitive (GTK_WIDGET (app_info->brows_panel->nbutton),
				FALSE);
    }
}

static void
put_button_cb (GtkWidget *widget, gpointer data)
{
  hosts        *host;
  GList        *sel;
  GtkTreeItem  *sel_item;
  struct tree  *snmptree;
  char         *value;
  guint32      val;
  GSList       *objs;

  objs = NULL;
  if ( (host = get_browser_host()))
    {
      sel = GTK_TREE (app_info->brows_panel->root)->selection;
      if ( (g_list_length (sel)) != 1)
	return;
      sel_item = GTK_TREE_ITEM (sel->data);
      snmptree = gtk_object_get_user_data (GTK_OBJECT (sel_item));

      host->hl_snmp.magic = host;
      host->hl_snmp.time_callback = update_mib_timeout;
      host->hl_snmp.done_callback = update_mib_value;
      value = gtk_entry_get_text(GTK_ENTRY (app_info->brows_panel->mib_value));

      switch(snmptree->type)
	{
        case 3:
	case 6:
	case 7:
	case 8:
	case 14:
          val = atoi(value);
          g_pdu_add_oid(&objs, host->name, host->name_length, 
                        SNMP_INTEGER, &val);
          g_async_set(&host->hl_snmp, objs);
          break;
	case 0:
	case 2:
	case 12:
          g_pdu_add_oid(&objs, host->name, host->name_length, 
                        SNMP_OCTETSTR, value);
          g_async_set(&host->hl_snmp, objs);
          break;
	}
    }
  else
    {
      g_print ("No host selected?\n");
    }
  return;
}

static gint 
panel_delete_cb (GtkWidget *widget, GdkEvent *e, gpointer data)
{
  gtk_widget_destroy (app_info->brows_panel->window);
  g_free (app_info->brows_panel);
  app_info->brows_panel = NULL;
  return TRUE;
}

/*
 * This would be called when dynamic mib loading unloading is implemented.
 */
static void
refresh_mib_tree (hosts *host)
{
}

/*
 * snmp callback
 */
gboolean
update_mib_value (host_snmp *host, void *magic, SNMP_PDU *spdu, GSList *objs)
{
  char    buf[1024];
  int     i;
  struct _SNMP_OBJECT *obj;
  hosts   *myhost;

  myhost = (hosts *) magic;

  obj = objs->data;
  if (memcmp(myhost->root, obj->id, myhost->root_length * sizeof(gulong)))
    {
      update_statusbar ("End of current tree.");
      gtk_widget_set_sensitive (GTK_WIDGET (app_info->brows_panel->nbutton),
				FALSE);
    }
  else
    {
      myhost->name_length = obj->id_len;
      memcpy(myhost->name, obj->id, 
	     myhost->name_length * sizeof(gulong));
      g_snmp_printf (buf, sizeof(buf), objs->data);

      gtk_entry_set_text (GTK_ENTRY (app_info->brows_panel->mib_value),
			  buf);
      buf[0] = 0;
      for (i = 0; i < myhost->name_length; i++)
	sprintf (buf + strlen (buf), ".%ld", myhost->name[i]);
      gtk_entry_set_text (GTK_ENTRY (app_info->brows_panel->mib_oid),
			  buf);
      gtk_widget_set_sensitive (GTK_WIDGET (app_info->brows_panel->nbutton),
				TRUE);
      gtk_widget_set_sensitive (GTK_WIDGET (app_info->brows_panel->gbutton),
				TRUE);
      sprintf (buf, _("SNMP query to node \"%s\" finished."),
	       host->name);
      update_statusbar (buf);
    }
  return TRUE;
}

/*
 * timeout callback
 */
void
update_mib_timeout (host_snmp *host, void *magic)
{
  return;
}

/*
 * Stuff for the combo box in the panel to select hosts
 */
void
browser_add_host (char *host)
{
  cbitems = g_list_append (cbitems, host);
  gtk_combo_set_popdown_strings (GTK_COMBO (app_info->brows_panel->mib_host),
				 cbitems);
  gtk_entry_set_text (GTK_ENTRY (GTK_COMBO 
				 (app_info->brows_panel->mib_host)->entry),
		      host);
}

void
browser_remove_host (char *host)
{
  cbitems = g_list_remove (cbitems, host);
  gtk_combo_set_popdown_strings (GTK_COMBO (app_info->brows_panel->mib_host),
				 cbitems);
}

/*
 * Standard panel functions 
 */

void 
open_browser_panel ()
{
  hosts   *host;

/*  host = get_current_host (NULL); */
  if(app_info->brows_panel == NULL)
    {
      create_browser_panel ();
      build_mib_tree ();
      fill_combo_list ();
      refresh_mib_tree (host);
      return;
    }
  if (!GTK_WIDGET_VISIBLE (app_info->brows_panel->window))
    {
      gtk_widget_show (app_info->brows_panel->window);
      refresh_mib_tree (host);
    }
}

void
destroy_browser_panel ()
{
  if (app_info->brows_panel)
    {
      gtk_widget_destroy (app_info->brows_panel->window);
      g_free (app_info->brows_panel);
      app_info->brows_panel = NULL;
    }
}

void 
hide_browser_panel ()
{
  if (app_info->brows_panel)
    {
      if (GTK_WIDGET_VISIBLE (app_info->brows_panel->window))
	{
	  gtk_widget_hide (app_info->brows_panel->window);
	}
    }
}

void
reset_browser_panel ()
{
  
}
/* EOF */
