/*
 * $Id: events.c,v 1.16 1999/05/11 14:50:01 gregm 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 events & alarms manager.
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gnome.h>
#include <sys/types.h>
#include "main.h"
#include "events.h"

extern gxsnmp *app_info;
/*
 * Local functions
 */

static void     event_close_button_cb        (GtkWidget   *widget,
					      gpointer    data);
static void     event_refresh_button_cb      (GtkWidget   *widget,
					      gpointer    data);
static gint     event_panel_delete_cb        (GtkWidget   *widget,
					      GdkEvent    *e,
					      gpointer    data);
static void     fill_event_panel             (void);
static void     update_event_panel           (app_event    *event);

enum {
  EVENT_ID_IDX,
    EVENT_LV_IDX,
    EVENT_ST_IDX,
    EVENT_TS_IDX,
    EVENT_DS_IDX
};
/*
 * Local Variables
 */
static gchar *titles[] =
{
  N_("Event ID"),
  N_("Category"),
  N_("Status"),
  N_("Timestamp"),
  N_("Summary")
};

static int         col_sizes[ELEMENTS(titles)];
static event_panel *ev_panel = NULL;
static GList       *event_list = NULL;
/*
 * Menus 
 */
static GnomeUIInfo file_menu[] = {
  { GNOME_APP_UI_ITEM, N_("Save"), NULL,
    NULL, NULL, NULL, 
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_SAVE, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Save as..."), NULL, 
    NULL, NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_SEPARATOR },
  { GNOME_APP_UI_ITEM, N_("Print"), NULL,
    NULL, NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_PRINT, 0, 0, NULL },
  { GNOME_APP_UI_SEPARATOR },
  { GNOME_APP_UI_ITEM, N_("Close"), NULL, event_close_button_cb, 
    NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ITEM, N_("Exit"), NULL,
    NULL, NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO },
};

static GnomeUIInfo edit_menu[] = {
  { GNOME_APP_UI_ITEM, N_("Filter..."), NULL,
    NULL, NULL, NULL,
    GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BLANK, 0, 0, NULL },
  { GNOME_APP_UI_ENDOFINFO },
};

static GnomeUIInfo event_panel_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_ENDOFINFO },
};

static void 
create_panel()
{
  GtkWidget   *button;
  GtkWidget   *scrolled;
  GtkWidget   *w_frame;
  GtkWidget   *vbox;
  GtkWidget   *bar;
  GtkWidget   *table;
  GtkWidget   *button_box;
  GtkWidget   *pixmap;
  int          i, tmp, w_size;
  gint        char_size;

  ev_panel = (event_panel *)g_malloc (sizeof (event_panel));
  ev_panel->window = gnome_app_new ("GXSNMP", _("Events"));

  gtk_signal_connect (GTK_OBJECT (ev_panel->window),
		      "delete_event",
		      GTK_SIGNAL_FUNC (event_panel_delete_cb),
		      NULL);

  vbox = gtk_vbox_new (FALSE, 4);
  table = gtk_table_new (3, 3, FALSE);
  gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 3);
  tmp = gdk_text_width (vbox->style->font, "1", 1);
  tmp = tmp * 18;
  w_size = 0;
  char_size = gdk_string_width (table->style->font, "xW") / 2;
  for (i=0; i< ELEMENTS (titles); i++)
    {
      titles[i] = strdup(gettext(titles[i]));
      col_sizes[i] = strlen (titles[i]) * char_size;
    }
  ev_panel->clist =  gtk_clist_new_with_titles (ELEMENTS (titles), titles);
  gtk_object_set_data (GTK_OBJECT (ev_panel->window), "event_clist", 
		       ev_panel->clist);
  gtk_clist_column_titles_passive (GTK_CLIST (ev_panel->clist));
  for (i = 0; i < ELEMENTS (titles); i++)
    {
      gtk_clist_set_column_width (GTK_CLIST (ev_panel->clist), 
				  i, (col_sizes[i] + (col_sizes[i] / 2)));
      w_size += (col_sizes[i] + (col_sizes[i] / 2));
    }

  gtk_clist_set_selection_mode (GTK_CLIST (ev_panel->clist), 
				GTK_SELECTION_BROWSE);
  scrolled = gtk_scrolled_window_new (NULL, NULL);

  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), 
			GTK_POLICY_ALWAYS, 
			GTK_POLICY_AUTOMATIC);
  gtk_container_add (GTK_CONTAINER (scrolled), ev_panel->clist);
  gtk_table_attach (GTK_TABLE (table), scrolled, 0, 1, 0, 4,
		    GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 2, 1);
  bar = gtk_vseparator_new ();
  gtk_table_attach (GTK_TABLE (table), bar, 1, 2, 0, 4,
		    GTK_FILL, GTK_FILL | GTK_EXPAND, 2, 1);
  button = gtk_button_new_with_label (_("Acknowledge"));
  gtk_object_set_data (GTK_OBJECT (ev_panel->window), "ack_button", button);
  gtk_widget_set_sensitive (button, FALSE);
  gtk_table_attach (GTK_TABLE (table), button, 
		    2, 3, 0, 1,
		    GTK_FILL | GTK_SHRINK, GTK_SHRINK, 1, 1);
  button = gtk_button_new_with_label (_("Delete"));
  gtk_object_set_data (GTK_OBJECT (ev_panel->window), "del_button", button);
  gtk_widget_set_sensitive (button, FALSE);
 /*
   * FIXME: need a way to determine the size of the buttons
   */
  w_size += (90 * 2);
  gtk_table_attach (GTK_TABLE (table), button,
		    2, 3, 1, 2,
		    GTK_FILL | GTK_SHRINK, GTK_SHRINK, 1, 1);
  bar = gtk_hseparator_new ();
  gtk_box_pack_start (GTK_BOX (vbox), bar, FALSE, FALSE, 2);
  w_frame = gtk_frame_new (NULL);
  gtk_container_border_width (GTK_CONTAINER (w_frame), 2);
  gtk_box_pack_start (GTK_BOX (vbox), w_frame, FALSE, FALSE, 1);
  button_box = gtk_hbutton_box_new ();
  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_border_width (GTK_CONTAINER (button_box), 2);
  gtk_container_add (GTK_CONTAINER (w_frame), button_box);

  button = gnome_stock_button (GNOME_STOCK_BUTTON_CLOSE);
  gtk_signal_connect (GTK_OBJECT (button), "clicked",
		      GTK_SIGNAL_FUNC (event_close_button_cb),
		      NULL);
  gtk_container_add (GTK_CONTAINER (button_box), button);
  pixmap = gnome_stock_pixmap_widget (ev_panel->window,
				      GNOME_STOCK_PIXMAP_REFRESH);
  button = gnome_pixmap_button (pixmap, _("Refresh"));
  gtk_signal_connect (GTK_OBJECT (button), "clicked", 
		      GTK_SIGNAL_FUNC (event_refresh_button_cb),
		      NULL);
  gtk_container_add (GTK_CONTAINER (button_box), button);

  gnome_app_set_contents (GNOME_APP (ev_panel->window), vbox);
  gnome_app_create_menus (GNOME_APP (ev_panel->window), 
			  event_panel_menu);
  gtk_widget_set_usize (ev_panel->window, w_size, 200);
  gtk_widget_show_all (ev_panel->window);
}

/* 
 * Callback wrapper functions
 */
static void
event_close_button_cb (GtkWidget *widget, gpointer data)
{
  hide_event_panel ();
}

static void
event_refresh_button_cb (GtkWidget *widget, gpointer data)
{
  reset_event_panel ();
}

static gint
event_panel_delete_cb (GtkWidget *widget, GdkEvent *e, gpointer data)
{
  destroy_event_panel();
  return TRUE;
}

/*
 * List management functions.
 */

static void
fill_event_panel ()
{
  GList     *item;
  app_event *data;

  if (g_list_length <= 0)
      return;
  else
    {
      item = g_list_first (event_list);
      while (item)
	{
	  data = (app_event *)item->data;
	  if (data)
	    update_event_panel (data);
	  item = g_list_next (item);
	}
    }

}

int
add_event (app_event *event)
{
  app_event  *cp;

  cp = (app_event *)g_malloc (sizeof (app_event));
  memcpy (cp, event, sizeof (app_event));
  cp->eventid = (g_list_length (event_list)) + 1;
  event_list = g_list_append (event_list, cp);
  update_event_panel (cp);
  return 1;
}

int 
remove_event (int eventid)
{
  GList     *item;
  app_event *data;

  item = g_list_first (event_list);
  while (item)
    {
      data = (app_event *)item->data;
      if (data)
	if ( (data->eventid) == eventid)
	  {
	    event_list = g_list_remove (event_list, data);
	    g_free (data);
	    return 1;
	  }
      item = g_list_next (item);
    }
  return -1;
}

/*
 * Exported standard panel functions.
 */
void 
open_event_panel ()
{
  if (!ev_panel)
    create_panel ();
  else
    if (!GTK_WIDGET_VISIBLE (ev_panel->window))
      gtk_widget_show (ev_panel->window);
  reset_event_panel ();
}

void 
destroy_event_panel ()
{
  if (ev_panel)
    {
      gtk_widget_destroy (ev_panel->window);
      g_free (ev_panel);
      ev_panel = NULL;
    }
}

void 
hide_event_panel ()
{
  if (ev_panel)
    {
      if (GTK_WIDGET_VISIBLE (ev_panel->window))
	{
	  gtk_widget_hide (ev_panel->window);
	}
    }
}

void 
reset_event_panel ()
{
  /* do any refresh of the panel that is needed, this is called when
   * the panel is opened.
   */
  gtk_clist_clear (GTK_CLIST (ev_panel->clist));
  fill_event_panel ();
}

/*
 * misc functions
 */
static void
update_event_panel (app_event *event)
{
  char    t_buf[80];
  gchar    *list_item[ELEMENTS(titles)];

  if (ev_panel)
    {
      if (GTK_WIDGET_VISIBLE (ev_panel->window))
	{
	  snprintf (t_buf, sizeof (t_buf), "%d", event->eventid);
	  list_item[EVENT_ID_IDX] = g_strdup (t_buf);
	  switch (event->category)
	    {
	    case GX_EVENT_INFO:
	      list_item[EVENT_LV_IDX] = g_strdup (_("Informative"));
	      break;
	    case GX_EVENT_WARN:
	      list_item[EVENT_LV_IDX] = g_strdup (_("Warning"));
	      break;
	    case GX_EVENT_ALRM:
	      list_item[EVENT_LV_IDX] = g_strdup (_("Alarm"));
	      break;
	    default:
	      list_item[EVENT_LV_IDX] = g_strdup ("");
	      break;
	    }
	  list_item[EVENT_ST_IDX] = g_strdup ("");
	  list_item[EVENT_TS_IDX] = g_strdup (ctime (&event->timestamp));
	  list_item[EVENT_DS_IDX] = g_strdup (event->description);
	  gtk_clist_append (GTK_CLIST (ev_panel->clist), list_item);
	}
    }
}
/*
 * Alarm panel
 */

/* EOF */
