/*
**  $Id: host_list.c,v 1.89 2000/07/23 00:55:29 remlali Exp $
**  GXSNMP -- An SNMP management application
**
**  This program is free software; you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation; either version 2 of the License, or
**  (at your option) any later version.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this program; if not, write to the Free Software
**  Foundation, Inc.,  59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
**
**  Host list UI specific functions
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <gnome.h>
#include "host_list.h"
#include "main.h"
#include "host_dialog.h"
#include "gxsnmp_map.h"
#include "gxsnmp_window.h"

#include "dbapi.h"
#include "gxsnmp/gxsnmp_dbapi.h"

#include "debug.h"

extern gxsnmp *app_info;

/****************************************************************************
 * Static data 
 ***************************************************************************/
#define HOST_CLIST_COLUMNS 4
static gchar *host_clist_titles[] = {
  N_("Display Name"), N_("DNS Name"), N_("Contact"), N_("Last Modification")
};
static gint  host_clist_title_widths[] = { 15, 15, 20, 10 };

/****************************************************************************
 * Forward declarations and callback functions  
 ***************************************************************************/
static void      host_list_class_init     (GXsnmp_host_listClass     *klass);
static void      host_list_init           (GXsnmp_host_list          *dialog);
static void      list_refresh_cb          (G_sqldb_table             *table,
                                           gpointer                   row,
                                           G_sqldb_cb_type            type,
                                           gpointer                   data);
static void      list_refresh_row         (GXsnmp_host_list          *dialog,
                                           DB_host                   *dbh);
static void      list_delete_cb           (GtkWidget                 *widget,
                                           gpointer                   data);
static void      list_edit_cb             (GtkWidget                 *widget,
                                           gpointer                   data);
static void      list_add_cb              (GtkWidget                 *widget,
                                           gpointer                   data);
static void      list_dialog_cb           (GnomeDialog               *dialog,
					   gint                       button,
                                           gpointer                   data);
static void      list_select_row_cb       (GtkWidget                 *widget,
                                           gint                       row,
                                           gint                       column,
                                           GdkEventButton            *event,
                                           gpointer                   data);
/****************************************************************************
 * gxsnmp_host_list_get_type()
 ***************************************************************************/
GtkType
gxsnmp_host_list_get_type ()
{
  static GtkType list_type = 0;
  if (!list_type)
    {
      GtkTypeInfo list_info = 
      {
	"GXsnmp_host_list",
	sizeof (GXsnmp_host_list),
	sizeof (GXsnmp_host_listClass),
	(GtkClassInitFunc) host_list_class_init,
	(GtkObjectInitFunc) host_list_init,
	/* reserved 1 */ NULL,
	/* reserved 2 */ NULL,
	(GtkClassInitFunc) NULL,
      };
      list_type =gtk_type_unique(gnome_dialog_get_type(), &list_info);
    }
  return list_type;
}
/****************************************************************************
 * Class init
 ***************************************************************************/
static void
host_list_class_init (GXsnmp_host_listClass *klass)
{
}
/****************************************************************************
 * Widget init
 ***************************************************************************/
static void
host_list_init (GXsnmp_host_list *dialog)
{
  GtkWidget *hbox;
  GtkWidget *vbox;
  GtkWidget *add;
  gint      i, c_width, c_height;
  gint      z;
  D_FUNC_START;
  hbox = gtk_hbox_new (FALSE, 2);
  gtk_box_pack_start (GTK_BOX (GNOME_DIALOG(dialog)->vbox), 
		      hbox, TRUE, TRUE, 0);
  c_width  = gdk_string_width (hbox->style->font, "xW") / 2;
  c_height = hbox->style->font->ascent +
	     hbox->style->font->descent;
  vbox = gtk_vbox_new (FALSE, 2);
  gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
  dialog->scrolled = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (dialog->scrolled),
				  GTK_POLICY_AUTOMATIC,
				  GTK_POLICY_ALWAYS);
  gtk_box_pack_start (GTK_BOX (vbox), dialog->scrolled, TRUE, TRUE, 0);
  dialog->clist = gtk_clist_new_with_titles(HOST_CLIST_COLUMNS, 
					    host_clist_titles);
  gtk_clist_set_selection_mode (GTK_CLIST (dialog->clist),
				GTK_SELECTION_BROWSE);
  gtk_clist_column_titles_passive (GTK_CLIST (dialog->clist));
  z = 0;
  for (i = 0; i < HOST_CLIST_COLUMNS; i++)
    {
      z += host_clist_title_widths[i] + 4;
      gtk_clist_set_column_width (GTK_CLIST (dialog->clist), i,
				  c_width * host_clist_title_widths[i]);
    }
  gtk_widget_set_usize (vbox, (z * c_width) + 10, c_height * 20);
  gtk_container_add (GTK_CONTAINER (dialog->scrolled), dialog->clist);

  vbox = gtk_vbutton_box_new ();
  gtk_button_box_set_layout (GTK_BUTTON_BOX (vbox), GTK_BUTTONBOX_START);
  gtk_button_box_set_child_size (GTK_BUTTON_BOX (vbox), 50, 20);
  gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);

  d_print (DEBUG_TRACE, "Setting up buttons.");
  dialog->dele_button = gtk_button_new_with_label (_("Delete host"));
  gtk_box_pack_end (GTK_BOX (vbox), dialog->dele_button, FALSE, FALSE, 0);
  dialog->edit_button = gtk_button_new_with_label (_("Edit host"));
  gtk_box_pack_end (GTK_BOX (vbox), dialog->edit_button, FALSE, FALSE, 0);
  add = gtk_button_new_with_label (_("Add host"));
  gtk_box_pack_end (GTK_BOX (vbox), add, FALSE, FALSE, 0);
  /* Signals */
  gtk_signal_connect (GTK_OBJECT (dialog->edit_button), "clicked", 
		      GTK_SIGNAL_FUNC(list_edit_cb), dialog);
  gtk_signal_connect (GTK_OBJECT (dialog->dele_button), "clicked", 
		      GTK_SIGNAL_FUNC(list_delete_cb), dialog);
  gtk_signal_connect (GTK_OBJECT (add), "clicked", 
		      GTK_SIGNAL_FUNC(list_add_cb), dialog);
  gtk_signal_connect (GTK_OBJECT (dialog->clist), "select_row",
		      GTK_SIGNAL_FUNC(list_select_row_cb), dialog);
  /* Show the whole mess */
  gtk_widget_show_all (hbox);
  /* Append buttons for close and help */
  gnome_dialog_append_buttons (GNOME_DIALOG (dialog),
                               GNOME_STOCK_BUTTON_CLOSE,
                               GNOME_STOCK_BUTTON_HELP,
                               NULL);
  gtk_signal_connect (GTK_OBJECT(dialog), "clicked",
		      GTK_SIGNAL_FUNC(list_dialog_cb), NULL);

  D_FUNC_END;
}
/****************************************************************************
 * Callback function to refresh the entire widget contents.
 ***************************************************************************/
static void
list_refresh_cb (G_sqldb_table *table, gpointer row, G_sqldb_cb_type type,
		 gpointer data)
{
  GXsnmp_host_list     *dialog;
  GtkCList             *clist;
  GList                *gl;
  D_FUNC_START;
  g_return_if_fail (data != NULL);
  dialog = GXSNMP_HOST_LIST (data);
  clist  = GTK_CLIST (dialog->clist);
  gtk_clist_freeze (clist);
  gtk_clist_clear (clist);
  gtk_signal_handler_block_by_data (GTK_OBJECT (clist), dialog);
  gl = g_sqldb_table_list (host_sqldb);
  d_print (DEBUG_TRACE, "Refreshing the clist.\n");
  while (gl)
    {
      if (gl->data)
	list_refresh_row (dialog, (DB_host *)gl->data);
      gl = gl->next;
    }
  d_print (DEBUG_TRACE, "Clist is built.\n");
  gl = g_sqldb_table_list (host_sqldb);
  if (gl)
    {
      d_print (DEBUG_DUMP, "Selecting host.");
      dialog->selected_host = (DB_host *)gl->data;
      gtk_widget_set_sensitive (dialog->edit_button, TRUE);
      gtk_widget_set_sensitive (dialog->dele_button, TRUE);
    }
  else
    {
      gtk_widget_set_sensitive (dialog->edit_button, FALSE);
      gtk_widget_set_sensitive (dialog->dele_button, FALSE);
    }
  gtk_signal_handler_unblock_by_data (GTK_OBJECT (clist), dialog);
  gtk_clist_thaw (clist);
  D_FUNC_END;
}
static void
list_refresh_row (GXsnmp_host_list *dialog, DB_host *dbh)
{
  GtkCList  *clist;
  gchar     *entry[4];
  gint      row;
  D_FUNC_START;
  g_return_if_fail (dbh != NULL);
  clist = GTK_CLIST (dialog->clist);
  entry[0] = dbh->name;
  entry[1] = dbh->dns_name;
  entry[2] = dbh->contact;
  entry[3] = dbh->modified;
  row = gtk_clist_append (clist, entry);
  gtk_clist_set_row_data (clist, row, GINT_TO_POINTER (dbh->rowid));
  D_FUNC_END;
}
static void
list_delete_cb (GtkWidget *widget, gpointer data)
{
  GXsnmp_map          *map_canvas;
  GXsnmp_host_list    *dialog;
  DB_host             *dbh;
  GtkWidget           *dialog_widget;
  D_FUNC_START;
  dialog = GXSNMP_HOST_LIST (data);
  dbh    = dialog->selected_host;
  g_return_if_fail (dbh != NULL);
  host_delete(dbh);
  host_destroy(dbh);
  D_FUNC_END;
}
static void
list_edit_cb (GtkWidget *widget, gpointer data)
{
  GXsnmp_map          *map_canvas;
  GXsnmp_host_list    *dialog;
  DB_host             *dbh;
  GtkWidget           *dialog_widget;
  D_FUNC_START;
  dialog = GXSNMP_HOST_LIST (data);
  dbh    = dialog->selected_host;
  g_return_if_fail (dbh != NULL);
  if (!gxsnmp_dialog_check ("edit_host", dbh))
    {
      map_canvas = gxsnmp_window_get_current_map
		     (GXSNMP_WINDOW (app_info->window));
      if (map_canvas)
	{
	  dialog_widget = gxsnmp_host_dialog_new (dbh, 
						  map_canvas->x1,
						  map_canvas->y1);
	}
      else
	{
	  dialog_widget = gxsnmp_host_dialog_new (dbh, 
						  0,
						  0);
	}
      if (dialog_widget)
	gxsnmp_dialog_add (dialog_widget, "edit_host", dbh,
			   g_strdup_printf ("Edit host '%s'", dbh->name));
    }
  D_FUNC_END;
}
static void
list_add_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)
    {
      dialog_widget = gxsnmp_host_dialog_new (NULL, 
					      map_canvas->x1,
					      map_canvas->y1);
    }
  else
    {
      dialog_widget = gxsnmp_host_dialog_new (NULL, 
					      0,
					      0);
    }
  if (dialog_widget)
    gxsnmp_dialog_add (dialog_widget, "add_host", NULL,
                       g_strdup ("Add a new host"));
  D_FUNC_END;
}
static void
list_dialog_cb (GnomeDialog *dialog, gint button, gpointer data)
{
  gchar   *tmp;

  if (button == 0)
    {
      gnome_dialog_close (GNOME_DIALOG (dialog));
    }
  else if (button == 1)
    {
      tmp = gnome_help_file_find_file ("gxsnmp", "host-list.html");
      if (tmp)
	{
	  gnome_help_goto (0, tmp);
	  g_free (tmp);
	}
      else
	{
	  /* Tell user no help is available at this time. */
	}
    }
  D_FUNC_END;
}
static void
list_select_row_cb (GtkWidget *widget, gint row, gint column,
		    GdkEventButton *event, gpointer data)
{
  GXsnmp_host_list    *dialog;
  GtkCList            *clist;
  guint                rowid;
  DB_host             *dbh;
  D_FUNC_START;
  dialog = GXSNMP_HOST_LIST (data);
  clist  = GTK_CLIST(widget);
  rowid = GPOINTER_TO_INT (gtk_clist_get_row_data (clist, row));
  if (rowid)
    {
      /* assignment intended. */
      if (!(dbh = g_sqldb_row_find (host_sqldb, "_rowid", &rowid)))
	{
	  g_warning ("list_select_row_cb: unable to locate network with "
		     "the rowid %d", rowid);
	  dialog->selected_host = NULL;
	  gtk_widget_set_sensitive (dialog->dele_button, FALSE);
	  gtk_widget_set_sensitive (dialog->edit_button, FALSE);
	  D_FUNC_END;
	  return;
	}
      dialog->selected_host = dbh;
      gtk_widget_set_sensitive (dialog->dele_button, TRUE);
      gtk_widget_set_sensitive (dialog->edit_button, TRUE);
    }
  else
    {
      fprintf(stderr,"no selected rowid\n");
      dialog->selected_host = NULL;
      gtk_widget_set_sensitive (dialog->dele_button, FALSE);
      gtk_widget_set_sensitive (dialog->edit_button, FALSE);
    }
  D_FUNC_END;
}
/****************************************************************************
 * Public API
 ***************************************************************************/
GtkWidget *
gxsnmp_host_list_new (gpointer data)
{
  GXsnmp_host_list  *dialog;
  D_FUNC_START;
  dialog = gtk_type_new (gxsnmp_host_list_get_type ());
  list_refresh_cb (host_sqldb, NULL, G_SQLDB_CB_UPDATE, dialog);
  D_FUNC_END;
  return GTK_WIDGET (dialog);
}

/* EOF */
