/* $Id: error_dialog.c,v 1.1.1.1 2005/09/10 17:36:41 renaud Exp $
 *
 * Copyright (C) 2004 by Intevation GmbH
 * Author(s):
 * Thomas Arendsen Hein <thomas@intevation.de>
 * Jan-Oliver Wagner <jan@intevation.de>
 *
 * This program is free software under the GNU GPL (>=v2)
 * Read the file COPYING coming with the software for details.
 *
 * In addition, as a special exception, Intevation GmbH gives
 * permission to link the code of this program with the OpenSSL
 * library (or with modified versions of OpenSSL that use the same
 * license as OpenSSL), and distribute linked combinations including
 * the two. You must obey the GNU General Public License in all
 * respects for all of the code used other than OpenSSL. If you
 * modify this file, you may extend this exception to your version
 * of the file, but you are not obligated to do so. If you do not
 * wish to do so, delete this exception statement from your version.
 */

#include <includes.h>
#include <stdarg.h>

#include "globals.h"
#include "error_dialog.h"
#include "nessus_i18n.h"

#ifdef USE_GTK
#include <gtk/gtk.h>
#endif

#define DIALOG_TYPE_INFO 0
#define DIALOG_TYPE_WARNING 1
#define DIALOG_TYPE_ERROR 2

#define DIALOG_NORMAL 0
#define DIALOG_AND_WAIT 1


void
show_dialog_std(type, wait, fmt, ap)
  int type;
  int wait;
  char *fmt;
  va_list ap;
{
  fprintf(stderr, "*** ");
  switch(type)
  {
    case DIALOG_TYPE_INFO:
      fprintf(stderr, _("Info: "));
      break;
    case DIALOG_TYPE_WARNING:
      fprintf(stderr, _("Warning: "));
      break;
    default: /* DIALOG_TYPE_ERROR  or other */
      fprintf(stderr, _("Error: "));
  }
  vfprintf(stderr, fmt, ap);
  fprintf(stderr, "\n");
  if(wait == DIALOG_AND_WAIT)
  {
    fprintf(stderr, _("Press <Enter> to continue ...\n"));
    getchar();
  }
}


#ifdef USE_GTK
void
show_dialog_gtk_close(dialog, response_id, dialog_running)
  GtkDialog *dialog;
  gint response_id;
  gboolean *dialog_running;
{
  gtk_widget_destroy(GTK_WIDGET(dialog));
  *dialog_running = FALSE;
}

void
show_dialog_gtk_popup(type, wait, error_text)
  int type;
  int wait;
  char *error_text;
{
  void *context_window = arg_get_value(MainDialog, "CONTEXT");
  GtkWindow *window;
  GtkWidget *dialog;
  int messagetype;
  static gboolean dialog_running = FALSE;

  while(dialog_running)
    gtk_main_iteration_do(TRUE);

  if(context_window)
    window = GTK_WINDOW(context_window);
  else
  {
    window = NULL;
    wait = DIALOG_AND_WAIT;
  }

  /*
   * XXX
   * Always wait. This can be removed if other windows are created
   * using a common function which sets "dialog_running", too.
   */
  wait = DIALOG_AND_WAIT;

  switch(type)
  {
    case DIALOG_TYPE_INFO:
      messagetype = GTK_MESSAGE_INFO;
      break;
    case DIALOG_TYPE_WARNING:
      messagetype = GTK_MESSAGE_WARNING;
      break;
    default: /* DIALOG_TYPE_ERROR  or other */
      messagetype = GTK_MESSAGE_ERROR;
  }

  /* create the user dialog */
  dialog = gtk_message_dialog_new(window, 0, messagetype,
      wait == DIALOG_AND_WAIT ? GTK_BUTTONS_OK : GTK_BUTTONS_CLOSE,
      "%s", error_text);

  if(wait == DIALOG_AND_WAIT)
  {
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
  }
  else
  {
    dialog_running = TRUE;
    gtk_widget_show(dialog);
    g_signal_connect(dialog, "response",
	G_CALLBACK(show_dialog_gtk_close),
	&dialog_running);
  }
}

void
show_dialog_gtk_log(type, error_text)
  int type;
  char *error_text;
{
  GtkWidget *textview = arg_get_value(MainDialog, "MSGLOGTEXT");
  GtkWidget *scrolledwin = arg_get_value(MainDialog, "MSGLOGSCROLL");
  GtkTextBuffer *log;
  GtkTextIter iter;
  GtkAdjustment *vadjust;
  char *msgtype;

  if(!textview || !scrolledwin)
    return;

  switch(type)
  {
    case DIALOG_TYPE_INFO:
      msgtype = _("Info: ");
      break;
    case DIALOG_TYPE_WARNING:
      msgtype = _("Warning: ");
      break;
    default: /* DIALOG_TYPE_ERROR  or other */
      msgtype = _("Error: ");
  }

  /* submit the message to the log */
  log = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
  gtk_text_buffer_get_end_iter(log, &iter);
  gtk_text_buffer_insert(log, &iter, msgtype, -1);
  gtk_text_buffer_get_end_iter(log, &iter);
  gtk_text_buffer_insert(log, &iter, error_text, -1);
  gtk_text_buffer_get_end_iter(log, &iter);
  gtk_text_buffer_insert(log, &iter, "\n", -1);

  vadjust = gtk_scrolled_window_get_vadjustment(
      GTK_SCROLLED_WINDOW(scrolledwin));
  gtk_adjustment_set_value(vadjust, vadjust->upper - 1);
}

void
show_dialog_gtk(type, wait, fmt, ap)
  int type;
  int wait;
  char *fmt;
  va_list ap;
{
  char *error_text = g_strdup_vprintf(fmt, ap);

  show_dialog_gtk_log(type, error_text);
  show_dialog_gtk_popup(type, wait, error_text);
  g_free(error_text);
}
#endif


void
show_dialog(type, wait, fmt, ap)
  int type;
  int wait;
  char *fmt;
  va_list ap;
{
#ifdef USE_GTK
  if(!F_quiet_mode)
    show_dialog_gtk(type, wait, fmt, ap);
  else
#endif /* USE_GTK */
    show_dialog_std(type, wait, fmt, ap);
}

/*
 * functions called by the application
 */

void
show_error(char *fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  show_dialog(DIALOG_TYPE_ERROR, DIALOG_NORMAL, fmt, ap);
  va_end(ap);
}

void
show_warning(char *fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  show_dialog(DIALOG_TYPE_WARNING, DIALOG_NORMAL, fmt, ap);
  va_end(ap);
}

void
show_info(char *fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  show_dialog(DIALOG_TYPE_INFO, DIALOG_NORMAL, fmt, ap);
  va_end(ap);
}


void
show_error_and_wait(char *fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  show_dialog(DIALOG_TYPE_ERROR, DIALOG_AND_WAIT, fmt, ap);
  va_end(ap);
}

void
show_warning_and_wait(char *fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  show_dialog(DIALOG_TYPE_WARNING, DIALOG_AND_WAIT, fmt, ap);
  va_end(ap);
}

void
show_info_and_wait(char *fmt, ...)
{
  va_list ap;

  va_start(ap, fmt);
  show_dialog(DIALOG_TYPE_INFO, DIALOG_AND_WAIT, fmt, ap);
  va_end(ap);
}
