/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * filename: xerror.c                                                      *
 *                                                                         *
 * UTIL C-source: Medical Image Conversion Utility                         *
 *                                                                         *
 * purpose      : error display routines                                   *
 *                                                                         *
 * project      : (X)MedCon by Erik Nolf                                   *
 *                                                                         *
 * Note         : This code gets linked in (X)MedCon library with X-support*
 *                                                                         *
 * Functions    : XMdcFatalErrorKill()   - Quit program with fatal error   *
 *                XMdcDisplayDialog()    - Display a dialog window         *
 *                XMdcDisplayWarn()      - Display a  warning              *
 *                XMdcDisplayMesg()      - Display a  message              *
 *                XMdcDisplayErr()       - Display an error                *
 *                XMdcDisplayFatalErr()  - Display a  fatal error          *
 *                XMdcLogHandler()       - The Glib log output handler     *
 *                XMdcCreateLogConsole() - Build glib log window           *
 *                XMdcShowLogConsole()   - Display glib log window         *
 *                XMdcCleanLogConsole()  - Clear logs buffer from window   *
 *                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
 */

/*
   Copyright (C) 1997-2026 by Erik Nolf

   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, 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 Place - Suite 330, Boston, MA 02111-1307, USA.  */

/****************************************************************************
                              H E A D E R S
****************************************************************************/

#include "m-depend.h"

#include <stdio.h>
#include <time.h>
#ifdef LIBMDC_HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include "xmedcon.h"

/****************************************************************************
                              D E F I N E S
****************************************************************************/

static GtkWidget *wconsole = NULL;
static GtkWidget *wlogs = NULL;

/****************************************************************************
                            F U N C T I O N S
****************************************************************************/

void XMdcFatalErrorKill(GtkWidget *button, int *code)
{
  exit(-*code);
}

void *XMdcDisplayDialog(int code, char *windowtitle, char *info)
{
  GtkWidget *dialog;
  GtkWidget *label;
  GtkWidget *button;
  GtkWidget *content_area;

  /* gdk_beep(); */

  dialog =  gtk_dialog_new();

  content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));

  if (code != MDC_OK) {
    g_signal_connect(dialog, "destroy",
                       G_CALLBACK(XMdcFatalErrorKill), &code);
  }else{
    g_signal_connect(dialog, "destroy",
                       G_CALLBACK(gtk_widget_destroy), NULL);
  }

  gtk_window_set_title(GTK_WINDOW(dialog), windowtitle);
  gtk_container_set_border_width(GTK_CONTAINER(dialog), 0);
  
  label = gtk_label_new(info);
  gtk_widget_set_margin_start(label, 20);
  gtk_widget_set_margin_end(label, 20);
  gtk_widget_set_margin_top(label, 10);
  gtk_widget_set_margin_bottom(label, 10);
  gtk_box_pack_start(GTK_BOX(content_area), label, TRUE, TRUE, 0);
  gtk_widget_show(label);

  button = gtk_dialog_add_button(GTK_DIALOG(dialog), "OK", GTK_RESPONSE_OK);
  if (code != MDC_OK) {
    g_signal_connect(button, "clicked",
                       G_CALLBACK(XMdcFatalErrorKill), &code);
  }else{
    g_signal_connect_swapped(button, "clicked",
                              G_CALLBACK(gtk_widget_destroy),
                              dialog);
  }
  gtk_widget_show(button);

  XMdcRunDialog(dialog);

  XMdcUpdateDrawing();

  return(dialog);
}

void *XMdcDisplayWarn(char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  vsprintf(errmsg, fmt, args);
  va_end(args);

  return(XMdcDisplayDialog(MDC_OK,"Warning",errmsg));
}


void *XMdcDisplayMesg(char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  vsprintf(errmsg, fmt, args);
  va_end(args);

  return(XMdcDisplayDialog(MDC_OK,"Message",errmsg));
}


void *XMdcDisplayErr(char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  vsprintf(errmsg, fmt, args);
  va_end(args);

  return(XMdcDisplayDialog(MDC_OK,"Error",errmsg));
}

void XMdcDisplayFatalErr(int code, char *fmt, ...)
{
  va_list args;

  va_start(args, fmt);
  vsprintf(errmsg, fmt, args);
  va_end(args);

  XMdcDisplayDialog(code, "Fatal Error", errmsg);

}

void XMdcLogHandler(const gchar *domain, GLogLevelFlags level,
                    const gchar *message, gpointer user_data)
{
  GtkTextBuffer *buffer;
  time_t t;
  char *logmsg, timestr[32];

  time(&t);
  strftime(timestr,32,"%b %d %H:%M:%S",localtime(&t));

  switch (level) {
    case G_LOG_LEVEL_DEBUG:
      logmsg = g_strdup_printf("DEBUG   **: %s ## %s\n", timestr, message);
      break;
    case G_LOG_LEVEL_MESSAGE:
      logmsg = g_strdup_printf("MESSAGE **: %s ## %s\n", timestr, message);
      break;
    case G_LOG_LEVEL_WARNING:
      logmsg = g_strdup_printf("WARNING **: %s ## %s\n", timestr, message);
      break;
    case G_LOG_LEVEL_ERROR:
      logmsg = g_strdup_printf("ERROR   **: %s ## %s\n", timestr, message);
      break;
    default:
      logmsg = g_strdup_printf("REMARK  **: %s ## %s\n", timestr, message);
  }

  if (logmsg == NULL) return;

  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(wlogs));
  gtk_text_buffer_insert_at_cursor(buffer, logmsg, -1); 
  g_free(logmsg);

}


void XMdcCreateLogConsole(void)
{
  GtkWidget *vbox, *hbox;
  GtkWidget *scrolled_window;
  GtkWidget *button;
  GtkWidget *separator;
  char *str;

  if (wconsole != NULL) return;

  wconsole = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_size_request(wconsole, 650, 350);

  g_signal_connect(wconsole, "destroy",
                     G_CALLBACK(gtk_widget_destroy), NULL);
  g_signal_connect(wconsole, "delete_event",
                     G_CALLBACK(XMdcHandlerToHide), NULL);

  str = g_strdup_printf("%s Console Logs",MDC_PRGR);
  if (str != NULL) {
    gtk_window_set_title(GTK_WINDOW(wconsole),str);
    g_free(str);
  }

  vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
  gtk_container_add(GTK_CONTAINER(wconsole),vbox);
  gtk_widget_show(vbox);

  scrolled_window = gtk_scrolled_window_new(NULL, NULL);
  gtk_box_pack_start(GTK_BOX(vbox),scrolled_window,TRUE,TRUE,0);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
                                 GTK_POLICY_AUTOMATIC,
                                 GTK_POLICY_AUTOMATIC);
  gtk_widget_show(scrolled_window);

  wlogs = gtk_text_view_new();
  gtk_text_view_set_editable(GTK_TEXT_VIEW(wlogs),FALSE);
  gtk_widget_set_name(wlogs, "TextView");
  gtk_container_add(GTK_CONTAINER(scrolled_window),wlogs);
  gtk_widget_show(wlogs);

  separator = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
  gtk_box_pack_start(GTK_BOX(vbox),separator,FALSE,TRUE,0);
  gtk_widget_show(separator);

  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
  gtk_container_set_border_width(GTK_CONTAINER(hbox),0);
  gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0);
  gtk_widget_show(hbox);


  button = gtk_button_new_with_label("Clear");
  g_signal_connect(button, "clicked",
                     G_CALLBACK(XMdcClearLogConsole),NULL);
  gtk_box_pack_start(GTK_BOX(hbox),button,TRUE,TRUE,2);
  gtk_widget_show(button);

  button = gtk_button_new_with_label("Close");
  g_signal_connect_swapped(button, "clicked",
                            G_CALLBACK(gtk_widget_hide),
                            wconsole);
  gtk_box_pack_start(GTK_BOX(hbox),button,TRUE,TRUE,2);
  gtk_widget_show(button);

  g_log_set_handler(MDC_PRGR,G_LOG_LEVEL_MASK,XMdcLogHandler,NULL);

}

void XMdcShowLogConsole(void)
{
  if (wconsole == NULL) XMdcCreateLogConsole();

  gtk_widget_show(wconsole);

}

void XMdcClearLogConsole(void)
{
  GtkTextBuffer *new_buffer = gtk_text_buffer_new(NULL);

  gtk_text_view_set_buffer(GTK_TEXT_VIEW(wlogs),new_buffer);

}
