#include <time.h>
#include <signal.h>
#ifdef HAVE_IMLIB
# include <Imlib.h>
#endif
#include <gtk/gtk.h>
#include <gdk/gdkrgb.h>
#if defined(__MSW__)
# include <gdk/gdkwin32.h>
# define HAVE_WIN32
#else
# include <gdk/gdkx.h>
# define HAVE_X
#endif

#include "guiutils.h"
#include "conmsg.h"
#include "pulist.h"
#include "cdialog.h"
#include "csd.h"
#include "fsd.h"
#include "fb.h"
#include "progressdialog.h"
#include "pdialog.h"
#include "fprompt.h"

#include "endeavour.h"
#include "edvcb.h"
#include "config.h"


#ifdef HAVE_IMLIB
gpointer	imlib_handle;
#endif

edv_core_struct	*edv_core;


#define ATOI(s)         (((s) != NULL) ? atoi(s) : 0)
#define ATOL(s)         (((s) != NULL) ? atol(s) : 0)
#define ATOF(s)         (((s) != NULL) ? atof(s) : 0.0f)
#define STRDUP(s)       (((s) != NULL) ? g_strdup(s) : NULL)

#define MAX(a,b)        (((a) > (b)) ? (a) : (b))
#define MIN(a,b)        (((a) < (b)) ? (a) : (b))
#define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))
#define STRLEN(s)       (((s) != NULL) ? strlen(s) : 0)
#define STRISEMPTY(s)   (((s) != NULL) ? (*(s) == '\0') : TRUE)


int main(int argc, char *argv[])
{
	gboolean initialized_gtk = FALSE;
	const gchar *s;
	gint err_rtn = 0;
	gboolean	show_stdout_dialog = TRUE,
			show_stderr_dialog = TRUE;
	edv_core_struct *core_ptr;

	/* Reset globals */
#ifdef HAVE_IMLIB
	imlib_handle = NULL;
#endif
	edv_core = NULL;

	/* Handle arguments */
	if(argc > 1)
	{
	    gint i;
	    const gchar *arg;

	    for(i = 1; i < argc; i++)
	    {
		arg = argv[i];
		if(STRISEMPTY(arg))
		    continue;

		/* Help? */
		if(!g_strcasecmp(arg, "--help") ||
		   !g_strcasecmp(arg, "-help") ||
		   !g_strcasecmp(arg, "--h") ||
		   !g_strcasecmp(arg, "-h") ||
		   !g_strcasecmp(arg, "-?")
		)
		{
		    g_print(PROG_HELP_MESG);
		    return(0);
		}
		/* Version? */
		else if(!g_strcasecmp(arg, "--version") ||
			!g_strcasecmp(arg, "-version")
		)
		{
		    g_print(
			PROG_NAME_FULL " "
#if defined(PROG_LANGUAGE_SPANISH)
"La Versión"
#elif defined(PROG_LANGUAGE_FRENCH)
"La Version"
#elif defined(PROG_LANGUAGE_GERMAN)
"Ausführung"
#elif defined(PROG_LANGUAGE_ITALIAN)
"La Versione"
#elif defined(PROG_LANGUAGE_DUTCH)
"Uitvoering"
#elif defined(PROG_LANGUAGE_PORTUGUESE)
"A Versão"
#elif defined(PROG_LANGUAGE_NORWEGIAN)
"Versjon"
#else
"Version"
#endif
			" " PROG_VERSION "\n"
		    );
		    g_print(PROG_COPYRIGHT);
		    return(0);
		}
		/* No stdout dialog? */
		else if(!g_strcasecmp(arg, "--no-stdout-dialog") ||
			!g_strcasecmp(arg, "-no-stdout-dialog") ||
			!g_strcasecmp(arg, "--no_stdout_dialog") ||
			!g_strcasecmp(arg, "-no_stdout_dialog")
		)
		{ 
		    show_stdout_dialog = FALSE;
		}
		/* No stderr dialog? */
		else if(!g_strcasecmp(arg, "--no-stderr-dialog") ||
			!g_strcasecmp(arg, "-no-stderr-dialog") ||
			!g_strcasecmp(arg, "--no_stderr_dialog") ||
			!g_strcasecmp(arg, "-no_stderr_dialog")
		)
		{
		    show_stderr_dialog = FALSE;
		}
	    }
	}


	/* Set up time zone */
	tzset();

	/* Set up signal callbacks */
#ifdef SIGHUP
	signal(SIGHUP, EDVSignalCB);
#endif
#ifdef SIGINT
	signal(SIGINT, EDVSignalCB);
#endif
#ifdef SIGTERM
	signal(SIGTERM, EDVSignalCB);
#endif
#ifdef SIGQUIT
	signal(SIGQUIT, EDVSignalCB);
#endif
#ifdef SIGSEGV
	signal(SIGSEGV, EDVSignalCB);
#endif
#ifdef SIGUSR1
	signal(SIGUSR1, EDVSignalCB);
#endif
#ifdef SIGUSR2
	signal(SIGUSR2, EDVSignalCB);
#endif
#ifdef SIGPIPE
	signal(SIGPIPE, EDVSignalCB);
#endif


	/* Check if the GTK library version is 1.2.10 or newer, if
	 * not then print warning
	 */
	s = gtk_check_version(1, 2, 10);
	if(!STRISEMPTY(s))
	    g_printerr("%s\n", s);

	/* Need to initialize GTK? */
	if(!initialized_gtk)
	{
	    /* Set GTK locale */
            gtk_set_locale();

	    /* Initialize GTK */
	    if(!gtk_init_check(&argc, &argv))
	    {
		g_printerr("Unable to initialize GTK.\n");
		return(1);
	    }

	    /* Initialize GDK RGB Buffers */
	    gdk_rgb_init();

	    initialized_gtk = TRUE;
	}

#ifdef HAVE_IMLIB
	/* Initialize Imlib */
	imlib_handle = Imlib_init(GDK_DISPLAY());
#endif  /* HAVE_IMLIB */

	/* Initialize Dialogs */
	ConMsgInit(PROG_NAME_FULL, 0, 0, show_stdout_dialog, show_stderr_dialog);
	CDialogInit();
	FileBrowserInit();
	CSDInit();
	FSDInit();
	FPromptInit();
	PDialogInit();
	ProgressDialogInit();

	/* Create Core */
	edv_core = core_ptr = EDVNew(argc, argv, &err_rtn);
	if(core_ptr == NULL)
	    return(err_rtn);

	/* Enter GTK main loop */
	gtk_main();

	/* Save the configuration and delete the Core */
	edv_core = NULL;
	EDVDelete(core_ptr, TRUE);
	core_ptr = NULL;

	/* Shutdown Dialogs */
	ProgressDialogShutdown();
	PDialogShutdown();
	FPromptShutdown();
	FSDShutdown();
	CSDShutdown();
	FileBrowserShutdown();
	CDialogShutdown();
	ConMsgShutdown();

	return(0);
}
