/***************************************************************************************
 *
 * error.h is part of SimpleSkyCam.
 *
 *****************************************************************************************/

#ifndef BUILD_WINDOWS
#include <execinfo.h>
#endif

#include <string>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include "gui.h"
#include "error.h"
#include "configuration.h"

extern GtkBuilder *_builder_;						// work around for threads

gboolean errormessage_thread (gpointer data) {
	struct ErrorMessage *em = (struct ErrorMessage*) data;
	GtkWidget *window = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_),
								   em->window));

	if (window == NULL) window = GTK_WIDGET(gtk_builder_get_object (GTK_BUILDER(_builder_),
																	"window-main"));

	GtkWidget *dialog;
	dialog = gtk_message_dialog_new(GTK_WINDOW(window),
			 GTK_DIALOG_DESTROY_WITH_PARENT,
			 GTK_MESSAGE_ERROR,
			 GTK_BUTTONS_OK,
			 "%s", em->message);
	gtk_window_set_title(GTK_WINDOW(dialog), em->title);
	gtk_dialog_run(GTK_DIALOG(dialog));
	gtk_widget_destroy(dialog);

	free (em);

	return false;
};


void errormessage_display (char *window, char *title, char *fmt,...) {
	struct ErrorMessage *em = (struct ErrorMessage *) malloc (sizeof (struct ErrorMessage));

	va_list args;
	char buffer[ERRORMSG_LEN];

	va_start (args, fmt);
	vsnprintf (buffer, (ERRORMSG_LEN-1), fmt, args);
	va_end (args);
	buffer[ERRORMSG_LEN-1] = 0;
	strncpy(em->title, title, ERRORMSG_LEN); 	em->title[ERRORMSG_LEN-1] = 0;
	strncpy(em->message, buffer, ERRORMSG_LEN);	em->message[ERRORMSG_LEN-1] = 0;
	strncpy(em->window, window, ERRORMSG_LEN);	em->window[ERRORMSG_LEN-1] = 0;

	gdk_threads_add_idle(errormessage_thread, em);
};


/*
 * print error message and the backtrace
 */
#define SIZE 100
void errorexit (char *fmt,...) {
	//
	// error message
	va_list args;
	char text[4096];

	va_start (args, fmt);
	vsnprintf (text, 4096, fmt, args);
	va_end (args);

	printf ("***************************\n");
	printf ("          ERROR\n");
	printf ("***************************\n");
	printf ("%s", text);

#ifndef BUILD_WINDOWS
	//
	// backtrace
	int j, nptrs;
	void *buffer[SIZE];
	char **s;

	nptrs = backtrace(buffer, SIZE);
	if ((s = (char**) backtrace_symbols(buffer, nptrs)) == NULL) {
		for (j = 0; j < nptrs; j++) printf ("%-5d %p\n", j, buffer[j]);
	}
	else {
		for (j = 0; j < nptrs; j++) printf ("%-5d %s\n", j, s[j]);
	}
#endif
	exit (-1);
}



