#include <ctype.h>
#include <signal.h>
#include <support.h>

#include "global.h"
#include "clipbrd.h"
#include "comm.h"
#include "debug.h"
#include "edit.h"
#include "error.h"
#include "event.h"
#include "file.h"
#include "find.h"
#include "fontsel.h"
#include "icon.h"
#include "kurzel.h"
#include "makro.h"
#include "memory.h"
#include "menu.h"
#include "options.h"
#include "poslist.h"
#include "printer.h"
#include "projekt.h"
#include "rsc.h"
#include "set.h"
#include "text.h"
#include "umbruch.h"
#include "version.h"
#include "window.h"

typedef struct
{
	LONG	bla[12];		/* interessiert qed nicht */
	WORD 	version;		/* z.B. $0201 ist V2.1 */
	WORD	release;		/* 0=alpha..3=release */
} AESVARS;

typedef struct
{
	LONG		config_status;
	VOID		*dosvars;
	AESVARS	*aesvars;
} MAGX_COOKIE;

GLOBAL WORD check_magx(VOID)
{
	LONG	v;
	WORD	version = 0;

	if (getcookie('MagX', &v))
		version = ((MAGX_COOKIE *)v)->aesvars->version;
	return version;
}

VOID cdecl handleTerm(WORD sig)
{
	abortProg = TRUE;
}

LOCAL BOOLEAN init_all(WORD argc, UBYTE *argv[])
{
	WORD		i, x;
	LONG		y;
	PATH		str;
	POSENTRY	*arglist = NULL;
	BOOLEAN	murx = FALSE;
		
	init_global();
	if (debug & DBG_INIT)
		Debug("qed: init_global done.\n");

	if (!init_resource())
		return FALSE;
	if (desk.g_w < 80 * sys_wchar || desk.g_h < 23 * sys_hchar)
	{
		note(1, SCREEN);
		return FALSE;
	}
	if (debug & DBG_INIT)
		Debug("qed: init_resource done.\n");
		
	init_file();
	if (debug & DBG_INIT)
		Debug("qed: init_file done.\n");

	init_window();
	if (debug & DBG_INIT)
		Debug("qed: init_window done.\n");

	init_icon();
	if (debug & DBG_INIT)
		Debug("qed: init_icon done.\n");

	init_memory();
	if (debug & DBG_INIT)
		Debug("qed: init_memory done.\n");

	init_edit();
	if (debug & DBG_INIT)
		Debug("qed: init_edit done.\n");

	init_makro ();
	if (debug & DBG_INIT)
		Debug("qed: init_makro done.\n");

	init_marken();
	if (debug & DBG_INIT)
		Debug("qed: init_makren done.\n");

	init_printer ();
	if (debug & DBG_INIT)
		Debug("qed: init_printer done.\n");

	init_projekt ();
	if (debug & DBG_INIT)
		Debug("qed: init_projekt done.\n");

	init_default_var();
	if (debug & DBG_INIT)
		Debug("qed: init_default_var done.\n");

	option_load(&arglist);
	if (debug & DBG_INIT)
		Debug("qed: option_load done.\n");

	init_mydials();
	if (debug & DBG_INIT)
		Debug("qed: init_mydials done.\n");

	font_change();

	init_clipbrd();
	if (debug & DBG_INIT)
		Debug("qed: init_clipbrd done.\n");

	init_comm();
	if (debug & DBG_INIT)
		Debug("qed: init_com done.\n");
	
	if (argc > 1)
	{
#if 1
		if (debug)
		{
			if (debug > DBG_GEN)
				i = 3;			/* --debug x berspringen */
			else
				i = 2;
		}
		else
#endif
			i = 1;
		while (i < argc)
		{
			/* WorkAround fr Thing, MagXDesk, die quoted Dateinamen in ' liefern! */
			if (murx)
			{
				strcat(str, " ");
				strcat(str, argv[i]);
				str[strlen(str)-1] = EOS;		/* letztes ' lschen */
				murx = FALSE;
			}
			else if (argv[i][0] == '\'')
			{
				strcpy(str, argv[i]+1);
				murx = TRUE;
			}
			else
				strcpy(str, argv[i]);
			i++;
			x = 0;
			y = 0;
			if ((i < argc) && isdigit(argv[i][0]))		/* next: Ziffer? -> Zeile */
			{
				y = max(0, atol(argv[i]) - 1);
				i++;
				if ((i < argc) && isdigit(argv[i][0]))	/* next: Ziffer? -> Spalte */
				{
					x = max(0, atoi(argv[i]) - 1);
					i++;
				}
			}
			if (!murx)
			{
				if (debug & DBG_ARG)
					Debug("qed: arglist= %s, %d, %ld\n", str, x, y);
				insert_poslist(&arglist, str, x, y);
			}
		}
	}

	menu_icheck(menu, MOEINF, !overwrite);
	menu_icheck(menu, MOOVERW, overwrite);

	wind_update(BEG_UPDATE);
	menu_bar(menu, TRUE);

	open_poslist(arglist);
	delete_poslist(&arglist);
	if (debug & DBG_ARG)
		Debug("qed: arglist done.\n");

	wind_update(END_UPDATE);
	return TRUE;
}

GLOBAL WORD main(WORD argc, UBYTE *argv[])
{
	UBYTE	s[128];
	PATH	path;
	WORD	i, d;
	UBYTE	menu_str[20];

	Pdomain(1);
	if ((argc > 1) && (strncmp(argv[1], "--debug", 7) == 0))
	{
		debug = DBG_GEN;
		if (isdigit(argv[1][7]))						/* folgt Level ? */
			debug |= atoi(argv[1]+7);
	}
	else
		debug = 0;

	if (debug)
	{
		DebugInit(Con, NULL);
/*		DebugInit(Datei, "i:\\qed.log");*/
		Debug("qed: started (Debug-Level: %d)...\n", debug);
	}

	if (debug & DBG_ARG)
	{
		WORD	i;
	
		Debug("qed: argc= %d\n", argc);
		for (i = 0; i < argc; i++)
			Debug("qed: argv[%d]= %s\n", i, argv[i]);
	}

	gl_apid = appl_init();
	if (debug & DBG_INIT)
		Debug("qed: gl_apid= %d\n", gl_apid);

	if (gl_apid < 0)
		exit(1);

	gem = _GemParBlk.global[0];
	if (debug & DBG_INIT)
		Debug("qed: gem= 0x%X\n", gem);
		
	magx = check_magx();
	if (debug & DBG_INIT)
		Debug("qed: magx= 0x%X\n", magx);

	return_code = 0;

	if (gem >= 0x400)
	{
		strcpy(menu_str, "  qed ");
		strcat(menu_str, ProgrammVersion);
		menu_register(gl_apid, menu_str);
	}

	signal(SIGINT, SIG_IGN);
	signal(SIGSYS, SIG_IGN);
	signal(SIGTERM, handleTerm);
	signal(SIGQUIT, handleTerm);
	signal(SIGHUP, handleTerm);

	if (appl_xgetinfo(12, &i, &d, &d, &d) && (i&8)==8)	/* gibts AP_TERM */
		shel_write(9, 1, 1, 0L, 0L);		/* wir knnen es! */

	/* Startverzeichnis von qed ermitteln. */
	shel_read(path, s);
	if (path[0] != EOS)
		file_splitt(path, app_path, NULL);
	else
		get_path(app_path, 0);

	if (debug & DBG_INIT)
		Debug("qed: app_path= %s\n", app_path);

	if (init_all(argc, argv))
	{
		set_mouse(ARROW, NULL);

		if (debug & DBG_INIT)
			Debug("qed: enter event loop...\n");

		hndl_events();
		if (debug & DBG_INIT)
			Debug("qed: event loop leaved.\n");
		menu_bar(NULL, FALSE);

		term_comm();
		if (debug & DBG_INIT)
			Debug("qed: term_comm done.\n");
		term_file();
		if (debug & DBG_INIT)
			Debug("qed: term_file done.\n");
		term_window();
		if (debug & DBG_INIT)
			Debug("qed: term_window done.\n");
	}
	term_resource();
	if (debug & DBG_INIT)
		Debug("qed: term_resource done.\n");
	term_global();
	if (debug & DBG_INIT)
		Debug("qed: term_global done.\n");
	appl_exit();

	if (debug)
	{
		Debug("qed: finished.\n");
		DebugExit();
	}
	return return_code;
}
