#include <support.h>

#include "global.h"
#include "av.h"
#include "ausgabe.h"
#include "clipbrd.h"
#include "edit.h"
#include "error.h"
#include "file.h"
#include "find.h"
#include "fontsel.h"
#include "icon.h"
#include "kurzel.h"
#include "makro.h"
#include "memory.h"
#include "obj.h"
#include "poslist.h"
#include "printer.h"
#include "projekt.h"
#include "rsc.h"
#include "se.h"
#include "set.h"
#include "text.h"
#include "version.h"
#include "window.h"
#include "winlist.h"
#include "options.h"

LOCAL UBYTE	buffer[MAX_LINE_LEN];

/*
 * Autosave
*/
GLOBAL BOOLEAN as_text, as_prj;
GLOBAL BOOLEAN as_text_ask, as_prj_ask;
GLOBAL WORD 	as_text_min, as_prj_min;


GLOBAL VOID autosave_options(VOID)
{
	UBYTE	s[10];
	WORD	antw;

	select_objc(autosave, ASTEXT, as_text);
	itoa(as_text_min, s, 10);
	objc_setstring(autosave, ASTMIN, s);
	select_objc(autosave, ASTASK, as_text_ask);

	select_objc(autosave, ASPROJ, as_prj);
	itoa(as_prj_min, s, 10);
	objc_setstring(autosave, ASPMIN, s);
	select_objc(autosave, ASPASK, as_prj_ask);

	antw = handle_dial(autosave, ASTMIN);
	if (antw == ASOK)
	{
		as_text = get_select(autosave, ASTEXT);
		objc_getstring(autosave, ASTMIN, s);
		as_text_min = atoi(s);
		if (as_text_min == 0)
			as_text = FALSE;
		if (as_text_min > 59)
			as_text_min = 59;
		as_text_ask = get_select(autosave, ASTASK);

		as_prj = get_select(autosave, ASPROJ);
		objc_getstring(autosave, ASPMIN, s);
		as_prj_min = atoi(s);
		if (as_prj_min == 0)
			as_prj = FALSE;
		if (as_prj_min > 59)
			as_prj_min = 59;
		as_prj_ask = get_select(autosave, ASPASK);

		do_all_icon(ALL_TYPES, DO_AUTOSAVE);
	}
}


/*
 * Globale Optionen
*/
GLOBAL BOOLEAN		clip_on_disk, wind_cycle, use_dial_3d, f_to_desk;
GLOBAL WORD			transfer_size, bin_line_len;
GLOBAL BOOLEAN		save_opt, overwrite, blinking_cursor, ctrl_mark_mode;
GLOBAL PATH			helpprog;


LOCAL VOID do_avopen(WINDOWP window)
{
	send_avwinopen(window->handle);
}

LOCAL VOID do_avclose(WINDOWP window)
{
	send_avwinclose(window->handle);
}

GLOBAL VOID global_options(VOID)
{
	WORD		antw, edit_obj;
	UBYTE 	s[13];
	BOOLEAN	old_cycle, new_cycle, quit = FALSE;
	DIALINFO	dial;
	FSEL		fsel = {"", "*.*"};
	PATH		n = "", newhelpprog;

	old_cycle = wind_cycle;
	select_objc(globalop, OASAVE, save_opt);
	disable_objc(globalop, OCLIP, (clip_dir[0] == EOS));
	select_objc(globalop, OCLIP, clip_on_disk);
	select_objc(globalop, OWINDOW, wind_cycle);
	select_objc(globalop, OBLINK, blinking_cursor);
	select_objc(globalop, OCTRL, ctrl_mark_mode);
	select_objc(globalop, O3D, use_dial_3d);
	select_objc(globalop, OTODESK, f_to_desk);
	itoa(transfer_size,s,10);
	objc_setstring(globalop, OTRANS, s);
	itoa(bin_line_len, s, 10);
	objc_setstring(globalop, OBINLEN, s);
	if (helpprog[0] != EOS)
		file_name(helpprog, s, FALSE);
	else
		strcpy(s, "");
	objc_setstring(globalop, OHELPNAME, s);
	strcpy(newhelpprog, helpprog);

	open_dial(globalop, &dial);
	dial_draw(&dial);
	edit_obj = OTRANS;
	do
	{
		antw = dial_do(&dial, &edit_obj) & 0x7FFF;
		switch (antw)
		{
			case OHELP :
				close_dial(&dial);
				if (helpprog[0] != EOS)
				{
					set_fsel_path(helpprog);
					file_name(helpprog, n, FALSE);
				}
				strcpy(fsel.name, n);
				if (select_file(&fsel, n, STRING(FINDHPSTR)))
				{
					strcpy(newhelpprog, n);
					file_name(newhelpprog, n, FALSE);
					objc_setstring(globalop, OHELPNAME, n);
				}
				open_dial(globalop, &dial);
				select_objc(globalop, antw, FALSE);
				dial_draw(&dial);
				break;
			default:
				quit = TRUE;
				break;
		}
	}
	while (!quit);
	select_objc(globalop, antw, FALSE);
	dial_end(&dial);
	if (antw == GOOK)
	{
		save_opt = get_select(globalop, OASAVE);
		if (clip_dir[0] != EOS)
			clip_on_disk = get_select(globalop, OCLIP);
		new_cycle = get_select(globalop, OWINDOW);
		if (old_cycle && !new_cycle)						/* war an, nun aus */
		{
			do_all_window(CLASS_ALL, do_avclose);
			wind_cycle = new_cycle;
		}
		if (new_cycle && !old_cycle)						/* nun an, war aus */
		{
			wind_cycle = new_cycle;
			do_all_window(CLASS_ALL, do_avopen);
		}
		blinking_cursor = get_select(globalop, OBLINK);
		ctrl_mark_mode = get_select(globalop, OCTRL);
		use_dial_3d = get_select(globalop, O3D);
		f_to_desk = get_select(globalop, OTODESK);
		objc_getstring (globalop, OTRANS, s);
		transfer_size = atoi(s);
		if (transfer_size == 0)
			transfer_size = 1;
		objc_getstring(globalop, OBINLEN, s);
		bin_line_len = atoi(s);
		if (bin_line_len < 1) 
			bin_line_len = 1;
		if (bin_line_len > MAX_LINE_LEN) 
			bin_line_len = MAX_LINE_LEN;
		strcpy(helpprog, newhelpprog);
	}
}

/*
 * Klammerpaare
*/
GLOBAL UBYTE	klammer_auf[11],
					klammer_zu[11];

GLOBAL VOID	klammer_options(VOID)
{
	WORD	antw;
	UBYTE	s1[11], s2[11];
	
	objc_setstring(klammer, KPAUF, klammer_auf);
	objc_setstring(klammer, KPZU, klammer_zu);
	antw = handle_dial(klammer, KPAUF);
	if (antw == KPOK)
	{
		objc_getstring(klammer, KPAUF, s1);
		objc_getstring(klammer, KPZU, s2);
		if (strlen(s1) == strlen(s2))
		{
			strcpy(klammer_auf, s1);
			strcpy(klammer_zu, s2);
		}
		else
			note(1, KLAMMERERR);
	}
}



/*
 * Lokale Optionen
*/
GLOBAL UBYTE		muster_str[MUSTER_ANZ][MUSTER_LEN+1];
GLOBAL LOCOPT		loc_opt[MUSTER_ANZ];
GLOBAL WORD			loc_opt_anz;

LOCAL WORD 			local_option;
LOCAL BOOLEAN		krz_changed = FALSE;
LOCAL WORD			selected_muster;
LOCAL LOCOPT		bak_loc_opt[MUSTER_ANZ];
LOCAL UBYTE 		bak_muster_str[MUSTER_ANZ][MUSTER_LEN+1];

LOCAL VOID option_fill(VOID)
{
	UBYTE 	s[10], str[13] = "";
	LOCOPTP	lo;

	lo = &loc_opt[local_option];

	select_objc(localop, OTAB, lo->tab);
	itoa(lo->tabsize,s,10);
	objc_setstring(localop, OTABSIZE, s);
	select_objc(localop, OEINRUCK, lo->einruecken);
	objc_setstring(localop, OWORT, lo->wort_str);
	select_objc(localop, OUMBRUCH, lo->umbrechen);
	select_objc(localop, OFORMLOAD, lo->format_by_load);
	select_objc(localop, OFORMPASTE, lo->format_by_paste);
	objc_setstring(localop, OUMBTEXT, lo->umbruch_str);
	itoa(lo->lineal_len,s,10);
	select_objc(localop, OBACKUP, lo->backup);
	objc_setstring(localop, OEXT, lo->backup_ext);
	objc_setstring(localop, OLINEAL, s);
	if (lo->kurzel[0] != EOS)
		file_name(lo->kurzel, str, FALSE);
	else
		strcpy(str, STRING(KURZELSTR));
	fill_ptext(localop, OKURZELNAME, str);
	select_objc(localop, OSHOWEND, lo->show_end);
}

LOCAL VOID option_get(VOID)
{
	UBYTE 	s[20];
	WORD		help;
	LOCOPTP	lo;

	lo = &loc_opt[local_option];
	lo->tab = get_select(localop, OTAB);
	objc_getstring (localop, OTABSIZE, s);
	if (*s)
	{
		help = atoi(s);
		if (help < 1 || help > 50)
			help = 3;
	}
	else
		help = 3;
	lo->tabsize = help;
	lo->umbrechen = get_select(localop, OUMBRUCH);
	lo->einruecken = get_select(localop, OEINRUCK);
	objc_getstring(localop, OUMBTEXT, lo->umbruch_str);
	str2set(lo->umbruch_str,lo->umbruch_set);
	lo->format_by_load = get_select(localop, OFORMLOAD);
	lo->format_by_paste = get_select(localop, OFORMPASTE);
	lo->backup = get_select(localop, OBACKUP);
	objc_getstring(localop, OEXT, lo->backup_ext);
	objc_getstring(localop, OLINEAL, s);
	if (*s)
	{
		help = atoi(s);
		if (help < 3 || help > MAX_LINE_LEN) 
			help = 65;
	}
	else
		help = 65;
	lo->lineal_len = help;
	objc_getstring(localop, OWORT, lo->wort_str);
	str2set(lo->wort_str,lo->wort_set);
	lo->show_end = get_select(localop, OSHOWEND);
}

LOCAL BOOLEAN option_changed(VOID)
{
	UBYTE 	s[40];
	WORD		help;
	LOCOPTP lo;

	lo = &loc_opt[local_option];
	if (lo->tab != get_select(localop, OTAB)) return TRUE;
	objc_getstring (localop, OTABSIZE, s);
	if (*s)
	{
		help = atoi(s);
		if (help<1 || help>50) help = 3;
	}
	else
		help = 3;
	if (lo->tabsize != help)
		return TRUE;
	if (lo->umbrechen != get_select(localop, OUMBRUCH))
		return TRUE;
	if (lo->einruecken != get_select(localop, OEINRUCK))
		return TRUE;
	objc_getstring(localop, OUMBTEXT, s);
	if (strcmp(lo->umbruch_str,s))
		return TRUE;
	str2set(lo->umbruch_str,lo->umbruch_set);
	if (lo->format_by_load != get_select(localop, OFORMLOAD))
		return TRUE;
	if (lo->format_by_paste != get_select(localop, OFORMPASTE))
		return TRUE;
	objc_getstring(localop, OLINEAL, s);
	if (*s)
	{
		help = atoi(s);
		if (help<3 || help>200) help = 65;
	}
	else
		help = 65;
	if (lo->lineal_len != help)
		return TRUE;
	objc_getstring(localop, OWORT, s);
	if (strcmp(lo->wort_str,s))
		return TRUE;
	str2set(lo->wort_str,lo->wort_set);

	objc_getstring(localop, OEXT, s);
	if (strcmp(lo->backup_ext, s))
		return TRUE;
	if (lo->backup != get_select(localop, OBACKUP))
		return TRUE;

	if (krz_changed)
	{
		krz_changed = FALSE;
		return TRUE;
	}
	if (lo->show_end != get_select(localop, OSHOWEND))
		return TRUE;
	return FALSE;
}


LOCAL VOID config_muster(VOID)
{
	DIALINFO	dial;
	BOOLEAN	quit = FALSE;
	WORD		i, antw;
	UBYTE 	str[MUSTER_LEN+1];

	if (option_changed() && note(1,APPLAYCH)==2)
		return;
	option_get();

	/* Daten fr Abbruch retten */
	memcpy(bak_loc_opt, loc_opt, (short) sizeof(LOCOPT) * MUSTER_ANZ);
	memcpy(bak_muster_str, muster_str, MUSTER_ANZ * (MUSTER_LEN+1));

	selected_muster = -1;
	disable_objc(muster, DMDELETE, TRUE);
	disable_objc(muster, DMCHANGE, TRUE);
	disable_objc(muster, DMNEW, (loc_opt_anz == MUSTER_ANZ));

	for (i=1; i<loc_opt_anz; i++)
	{
		objc_setstring(muster, DM1 + i - 1, muster_str[i]);
		do_flags(muster, DM1 + i - 1, SELECTABLE);
	}
	for (; i<MUSTER_ANZ; i++)
	{
		objc_setstring(muster,DM1 + i - 1, STRING(FREESTR));
		disable_objc(muster, DM1 + i - 1, TRUE);
	}

	open_dial(muster, &dial);
	dial_draw(&dial);
	do
	{
		antw = dial_do(&dial, NULL) & 0x7FFF;
		if (antw >= DM1 && antw <= DM9)
		{
			if (antw == selected_muster)
			{
				select_objc(muster, selected_muster, FALSE);
				selected_muster = -1;
				disable_objc(muster, DMNEW, FALSE);
				disable_objc(muster, DMDELETE, TRUE);
				disable_objc(muster, DMCHANGE, TRUE);
			}
			else
			{
				select_objc(muster, selected_muster, FALSE);
				selected_muster = antw;
				select_objc(muster, selected_muster, TRUE);

				disable_objc(muster, DMNEW, TRUE);
				disable_objc(muster, DMDELETE, FALSE);
				disable_objc(muster, DMCHANGE, FALSE);
			}
			dial_draw(&dial);
		}
		else
		{
			switch (antw)
			{
				case DMNEW: 							/* Neues Dateimuster eingeben */
					objc_setstring(musterchg, DMCTEXT, "");
					if (handle_dial(musterchg, DMCTEXT) == DMCOK)
					{
						WORD	i;

						objc_getstring(musterchg, DMCTEXT, str);
						i = loc_opt_anz;
						if ((str[0] != EOS) && (i < MUSTER_ANZ))
						{
							objc_setstring(muster, DM1 + i - 1, str);
							disable_objc(muster, DM1 + i - 1, FALSE);
							strcpy(muster_str[i],str);
							memcpy(&loc_opt[i], &loc_opt[0], (short) sizeof(LOCOPT));
							loc_opt_anz++;
							draw_Objc(muster, DMEXTBOX, 8);
						}
					}
					if (loc_opt_anz == MUSTER_ANZ)		/* wenn voll, Button aus! */
					{
						disable_objc(muster, DMNEW, TRUE);
						draw_Objc(muster, DMNEW, 1);
					}
					break;
				case DMDELETE: 						/* Muster lschen */
					i = selected_muster - DM1 + 1;
					if (i == local_option)			/* aktuelles Muster gelscht! */
						local_option = 0;
					memcpy(&loc_opt[i], &loc_opt[i+1], (short) sizeof(LOCOPT) * (loc_opt_anz-i-1));
					memcpy(&muster_str[i], &muster_str[i+1], (MUSTER_LEN+1) * (loc_opt_anz-i-1));
					loc_opt_anz--;
					for (; i<loc_opt_anz; i++)
						objc_setstring(muster, DM1 + i - 1, muster_str[i]);

					if (i < MUSTER_ANZ)
					{
							objc_setstring(muster, DM1 + i - 1, STRING(FREESTR));
							disable_objc(muster, DM1 + i - 1, TRUE);
					}
					select_objc(muster, selected_muster, FALSE);

					selected_muster = -1;
					disable_objc(muster, DMDELETE, TRUE);
					disable_objc(muster, DMCHANGE, TRUE);

					if (loc_opt_anz < MUSTER_ANZ) 		/* wieder welche frei? */
						disable_objc(muster, DMNEW, FALSE);

					dial_draw(&dial);
					break;
				case DMCHANGE: 						/* Muster ndern */
					objc_getstring(muster, selected_muster, str);
					objc_setstring(musterchg, DMCTEXT, str);
					if (handle_dial(musterchg, DMCTEXT) == DMCOK)
					{
						objc_getstring(musterchg, DMCTEXT, str);
						objc_setstring(muster, selected_muster, str);
						draw_Objc(muster, DMEXTBOX, 8);
						strcpy(muster_str[selected_muster - DM1 + 1], str);
					}
					break;
				default:
					quit = TRUE;
					break;
			} /* switch */
			select_objc(muster, antw, FALSE);
			draw_Objc(muster, antw, 1);
		} /* if */
	} /* while */
	while (!quit);
	dial_end(&dial);
	disable_objc(localop, OTYPECIRC, (loc_opt_anz <= 1));
	if (antw == DMOK)
	{
		if (muster_str[local_option][0]==EOS)
		{
			local_option = 0;
			option_fill();
		}
		draw_Objc(localop, OTYPE, 1);
		draw_Objc(localop, OBOX, 8);
	}
	else
	{
		memcpy(loc_opt,bak_loc_opt, (short) sizeof(LOCOPT) * MUSTER_ANZ);
		memcpy(muster_str, bak_muster_str, MUSTER_ANZ * (MUSTER_LEN + 1));
	}
	if (selected_muster!=-1)
		select_objc(muster, selected_muster, FALSE);
}


LOCAL BOOLEAN build_popup(POPUP *pop)
{
	UBYTE str[MUSTER_LEN + 2];
	WORD	i;

	if (loc_opt_anz <= 1)
	{
		pop->tree = NULL;
		return FALSE;
	}

	strcpy(str, " ");
	strcat(str, muster_str[0]);
	create_popup(pop, MUSTER_ANZ, MUSTER_LEN+1, str);

	for (i = 1; i < loc_opt_anz; i++)
	{
		strcpy(str, " ");
		strcat(str, muster_str[i]);
		append_popup(pop, str);
	}

	if (pop->tree != NULL)
	{
		for(i = 0; i < pop->akt_item + 2; i++)
			rsrc_obfix(pop->tree, i);
		dial_fix(pop->tree);
		return TRUE;
	}
	return FALSE;
}


GLOBAL VOID local_options(VOID)
{
	WORD			antw, y, edit_obj;
	WINDOWP 		window;
	PATH			save_name;
	DIALINFO		dial;
	BOOLEAN		quit = FALSE, doppel_klick;
	FSEL			fsel = {"", "*.krz"};
	PATH			name = "";
	UBYTE 		str[MUSTER_LEN + 2] = " ";
	POPUP			pop;

	local_option = 0;
	window = winlist_top();
	if ((window != NULL) && (window->class == CLASS_EDIT))
	{
		TEXTP t_ptr = get_text(window->handle);

		local_option = (short)(t_ptr->loc_opt - loc_opt);
		strcat(str, muster_str[local_option]);
	}

	/* Sonderbehandlung fr '*'-Eintrag, damit das Popup klappt! */
	if (local_option == 0)
		strcpy(str, " *");

	objc_setstring(localop, OTYPE, str);
	option_fill();
	strcpy(save_name, loc_opt[local_option].kurzel);

	disable_objc(localop, OTYPECIRC, (loc_opt_anz <= 1));
	build_popup(&pop);
	
	open_dial(localop, &dial);
	dial_draw(&dial);
	edit_obj = OTABSIZE;
	do
	{
		antw = dial_do(&dial, &edit_obj);
		doppel_klick = (antw&0x8000);
		antw &= 0x7FFF;
		switch (antw)
		{
			case OTYPESTR :
			case OTYPECIRC :
			case OTYPE :
				if (doppel_klick && antw == OTYPE)
				{
					config_muster();
					option_fill();

					/* Popup neu aufbauen */
					free_popup(&pop);
					build_popup(&pop);

					dial_draw(&dial);
				}
				else if (loc_opt_anz > 1)
				{
					if (antw == OTYPE)
						y = popup_select(localop, OTYPE, pop.tree, 1, FALSE, DO_POPUP);
					else
						y = popup_select(localop, OTYPE, pop.tree, 1, FALSE, DO_CYCLE);
					y -= pop.first_item;
					if (y >= 0 && y != local_option)
					{
						if (option_changed() && note(1,APPLAYCH) == 1)
								option_get();
						local_option = y;
						option_fill();
						draw_Objc(localop, OBOX, MAX_DEPTH);
					}
				}
				break;
			case OKURZEL:
				if (doppel_klick)
				{
					strcpy(loc_opt[local_option].kurzel, "");
					krz_changed = TRUE;
					fill_ptext(localop, OKURZELNAME, STRING(KURZELSTR));
					draw_Objc(localop, OKURZELNAME, 1);
				}
				else
				{
					close_dial(&dial);
					if (loc_opt[local_option].kurzel[0] != EOS)
					{
						set_fsel_path(loc_opt[local_option].kurzel);
						file_name(loc_opt[local_option].kurzel, name, FALSE);
					}
					strcpy(fsel.name, name);
					if (select_file(&fsel, name, STRING(FINDKURZELSTR)))
					{
						strcpy(loc_opt[local_option].kurzel, name);
						file_name(name, str, FALSE);
						krz_changed = TRUE;
						objc_setstring(localop, OKURZELNAME, str);
					}
					open_dial(localop, &dial);
					select_objc(localop, OKURZEL, FALSE);
					dial_draw(&dial);
				}
				break;
			case OOK:
				quit = TRUE;
				break;
			case ORAUS :
				quit = TRUE;
				break;
		}
		select_objc(localop, antw, FALSE);
		draw_Objc(localop, antw, 1);
	}
	while (!quit);
	dial_end(&dial);
	free_popup(&pop);
	if (antw == OOK)
	{
		option_get();
		update_loc_opt();
		absatz_edit();
		ch_kurzel(loc_opt[local_option].kurzel, TRUE);
	}
	else
		strcpy(loc_opt[local_option].kurzel, save_name);
}


/*
 * Defaulteinstellungen
*/
VOID init_default_var(VOID)
{
	WORD 		i;
	UBYTE		*c;

	s_grkl     = FALSE;
	s_vorw	  = TRUE;
	s_global	  = TRUE;
	s_quant    = FALSE;
	s_wort	  = FALSE;
	s_round	  = FALSE;
	df_rekursiv= FALSE;
	r_modus	  = RP_FIRST;
	s_str[0] = EOS;
	r_str[0] = EOS;
	df_name[0] = EOS;
	for (i = 0; i < HIST_ANZ; i++)
	{
		s_history[i][0] = EOS;
		r_history[i][0] = EOS;
	}
	rp_box_x	  = 0;
	rp_box_y	  = 0;

	use_gdos_print = FALSE;
	vorschub	  = TRUE;
	zeilen_nr  = FALSE;
	seiten_nr  = FALSE;
	rand_len   = 2;
	use_rand   = TRUE;
	print_block = 0;
	wp_mode = 0;
	wp_treiber[0] = EOS;
	wp_nlq = FALSE;
	wp_seiten_len = 65;
	wp_seiten_width = 80;
	metafile[0] = EOS;

	save_opt	  = FALSE;
	wind_cycle = FALSE;
	clip_on_disk = TRUE;
	overwrite  = FALSE;
	transfer_size = 100;

	c = getenv("STGUIDE");
	if (c != NULL)
		strcpy(helpprog, c);
	else
		helpprog[0] = EOS;
		
	blinking_cursor = TRUE;
	ctrl_mark_mode = FALSE;
	use_dial_3d = TRUE;
	f_to_desk = FALSE;
	
	for (i = 0; i < FEHLERANZ; i++)
		error[i][0] = EOS;

	for (i = 0; i < MUSTER_ANZ; i++)
		muster_str[i][0] = EOS;
	strcpy(muster_str[0],"*");						/* Bleibt konstant */
	loc_opt_anz = 1;
	loc_opt[0].tab        = TRUE;
	loc_opt[0].tabsize    = 8;
	loc_opt[0].einruecken = TRUE;
	strcpy(loc_opt[0].wort_str,"A-Za-z0-9");
	str2set(loc_opt[0].wort_str,loc_opt[0].wort_set);
	loc_opt[0].umbrechen  = FALSE;
	loc_opt[0].format_by_load = FALSE;
	loc_opt[0].format_by_paste = FALSE;
	strcpy(loc_opt[0].umbruch_str,"- \t");
	str2set(loc_opt[0].umbruch_str,loc_opt[0].umbruch_set);
	loc_opt[0].lineal_len = 70;
	strcpy(loc_opt[0].backup_ext, "BAK");
	loc_opt[0].backup = FALSE;
	loc_opt[0].show_end = FALSE;

	se_autosave = FALSE;
	se_autosearch = FALSE;
	for (i = 0; i < SHELLANZ; i++)
	{
		se_shells[i].Name[0] = EOS;
		se_shells[i].Makefile[0] = EOS;
	}

	umlaut_from = 0;
	umlaut_to = 0;

	as_text 		= FALSE;
	as_text_min = 0;
	as_text_ask = FALSE;
	as_prj 		= FALSE;
	as_prj_min = 0;
	as_prj_ask = FALSE;

	bin_line_len = 80;

	strcpy(klammer_auf, "({[<\"\'");
	strcpy(klammer_zu, ")}]>\"\'");
}


/*
 * Datei
*/
#define CFGNAME	"qed.cfg"

LOCAL PATH			cfg_path = "";
LOCAL FILE			*fd;
LOCAL WORD			muster_nr;
LOCAL LOCOPTP		lo;

LOCAL VOID get_cfg_path(VOID)
{
	UBYTE		*p;
	BOOLEAN	found = FALSE;

	p = getenv("HOME");								/* 1. $HOME */
	if (p != NULL)
	{
		strcpy(cfg_path, p);
		if (make_normalpath(cfg_path, FALSE))
			strcat(cfg_path, CFGNAME);
		found = file_exist(cfg_path);
		if (!found)										/* 1a. $HOME/defaults */
		{
			strcpy(cfg_path, p);
			make_normalpath(cfg_path, FALSE);
			strcat(cfg_path, "defaults\\");
			strcat(cfg_path, CFGNAME);
			found = file_exist(cfg_path);
		}		
	}

	p = getenv("QED");								/* 2. $QED */
	if (!found && (p != NULL))
	{
		strcpy(cfg_path, p);
		if (make_normalpath(cfg_path, FALSE))
			strcat(cfg_path, CFGNAME);
		found = file_exist(cfg_path);
	}

	if (!found && app_path[0] != EOS)			/* 3. Startverzeichnis */
	{
		strcpy(cfg_path, app_path);
		strcat(cfg_path, CFGNAME);
		found = file_exist(cfg_path);
	}

	if (!found && file_exist(CFGNAME))			/* 4. aktuelles Verzeichnis */
	{
		get_path(cfg_path, 0);
		strcat(cfg_path, CFGNAME);
		found = TRUE;
	}

	if (found)
	{
		if (!caseSens(cfg_path, NULL))
			str_upper(cfg_path);
	}
	else
		strcpy(cfg_path, CFGNAME);
/*
Debug("cfg_path: %s\n", cfg_path);
*/
}

/******************************************************************************/
/* Dateioperation: Laden																		*/
/******************************************************************************/
LOCAL VOID get_bool(UBYTE *str, BOOLEAN *val)
{
	if (stricmp(str, "TRUE") == 0)
		*val = TRUE;
	if (stricmp(str, "FALSE") == 0)
		*val = FALSE;
}

LOCAL VOID get_str(UBYTE *str, UBYTE *val)
{
	val[0] = EOS;
	if ((str[0] == '"') && (str[1] == '"'))	/* nur "" -> leer */
		return;
	else
	{
		WORD	len, i, j;
		
		if (str[0] == '"')
		{
			len = (WORD)strlen(str);
			j = 0;
			i = 1;
			while ((str[i] != '\"') && (i < len))
			{
				if ((str[i] == '\\') && (str[i+1] == '"'))
					i++;
				val[j++] = str[i++];
			}
			val[j] = EOS;
		}
	}
}


LOCAL VOID parse_line(POSENTRY **arglist, UBYTE *zeile)
{
	UBYTE		var[30], *p, tmp[80];
	WORD		x, i, d;
	LONG		y;
	PATH		filename;
					
	p = strchr(zeile, '=');
	if (p != NULL)
	{
		strncpy(var, zeile, p-zeile);
		var[p-zeile] = EOS;
		strcpy(buffer, p+1);

		/* Autosave */
		if (strcmp(var, "AutoSavePrj") == 0)
			get_bool(buffer, &as_prj);
		else if(strcmp(var, "AutoSavePrjAsk") == 0)
			get_bool(buffer, &as_prj_ask);
		else if(strcmp(var, "AutoSavePrjMin") == 0)
			as_prj_min = atoi(buffer);
		else if(strcmp(var, "AutoSaveText") == 0)
			get_bool(buffer, &as_text);
		else if(strcmp(var, "AutoSaveTextAsk") == 0)
			get_bool(buffer, &as_text_ask);
		else if(strcmp(var, "AutoSaveTextMin") == 0)
			as_text_min = atoi(buffer);

		/* DefaultPrj */
		else if(strcmp(var, "DefaultPrj") == 0)
		{
			get_str(buffer, def_prj_path);
			set_def_prj();
		}
		
		/* Fehlerzeilen */
		else if(strcmp(var, "Error") == 0)
		{
			get_str(buffer, tmp);
			set_errorline(tmp);
		}
		
		/* GDOS Drucker */
		else if(strcmp(var, "GdosDriver") == 0)
			gdos_device = atoi(buffer);
		else if(strcmp(var, "GdosFile") == 0)
			get_str(buffer, metafile);
		else if(strcmp(var, "GdosFontID") == 0)
			druckFont.id = atoi(buffer);
		else if(strcmp(var, "GdosFontSize") == 0)
			druckFont.pts = atoi(buffer);
		else if(strcmp(var, "GdosMode") == 0)
			get_bool(buffer, &use_gdos_print);

		/* GEMDOS Drucker */
		else if(strcmp(var, "GemdosDensity") == 0)
			wp_mode = atoi(buffer);
		else if(strcmp(var, "GemdosDriver") == 0)
			get_str(buffer, wp_treiber);
		else if(strcmp(var, "GemdosNLQ") == 0)
			get_bool(buffer, &wp_nlq);
		else if(strcmp(var, "GemdosPageHeight") == 0)
			wp_seiten_len = atoi(buffer);
		else if(strcmp(var, "GemdosPageWidth") == 0)
			wp_seiten_width = atoi(buffer);
			

		/* Globales */
		else if (strcmp(var, "GlobalAutosaveCfg") == 0)
			get_bool(buffer, &save_opt);
		else if (strcmp(var, "GlobalBinLineLen") == 0)
			bin_line_len = atoi(buffer);
		else if (strcmp(var, "GlobalBlinkCursor") == 0)
			get_bool(buffer, &blinking_cursor);
		else if (strcmp(var, "GlobalCtrlBlock") == 0)
			get_bool(buffer, &ctrl_mark_mode);
		else if (strcmp(var, "GlobalDial3d") == 0)
			get_bool(buffer, &use_dial_3d);
		else if (strcmp(var, "GlobalFtoDesk") == 0)
			get_bool(buffer, &f_to_desk);
		else if (strcmp(var, "GlobalGEMClip") == 0)
			get_bool(buffer, &clip_on_disk);
		else if (strcmp(var, "GlobalOverwrite") == 0)
			get_bool(buffer, &overwrite);
		else if (strcmp(var, "GlobalTransSize") == 0)
			transfer_size = atoi(buffer);
		else if (strcmp(var, "GlobalWindCycle") == 0)
			get_bool(buffer, &wind_cycle);

		/* Hilfe-Programm */
		else if (strcmp(var, "HelpProgram") == 0)
			get_str(buffer, helpprog);
		
		/* Klammerpaare */
		else if (strcmp(var, "KlammerAuf") == 0)
			get_str(buffer, klammer_auf);
		else if (strcmp(var, "KlammerZu") == 0)
			get_str(buffer, klammer_zu);
			
		/* Lokales */
		else if (strcmp(var, "LocalBegin") == 0)
		{
			get_str(buffer, tmp);
			if (muster_nr > 0)
				strcpy(muster_str[muster_nr], tmp);
			lo = &(loc_opt[muster_nr]);
		}
		else if (strcmp(var, "LocalEnd") == 0)
		{
			muster_nr++;
			lo = NULL;
		}
		else if ((strcmp(var, "LocalBackup") == 0) && (lo != NULL))
			get_bool(buffer, &(lo->backup));
		else if ((strcmp(var, "LocalBackupExt") == 0) && (lo != NULL))
			get_str(buffer, lo->backup_ext);
		else if ((strcmp(var, "LocalInsert") == 0) && (lo != NULL))
			get_bool(buffer, &(lo->einruecken));
		else if ((strcmp(var, "LocalKurzel") == 0) && (lo != NULL))
			get_str(buffer, lo->kurzel);
		else if ((strcmp(var, "LocalTab") == 0) && (lo != NULL))
			get_bool(buffer, &(lo->tab));
		else if ((strcmp(var, "LocalTabSize") == 0) && (lo != NULL))
			lo->tabsize = atoi(buffer);
		else if ((strcmp(var, "LocalUmbruch") == 0) && (lo != NULL))
			get_bool(buffer, &(lo->umbrechen));
		else if ((strcmp(var, "LocalUmbruchLineLen") == 0) && (lo != NULL))
			lo->lineal_len = atoi(buffer);
		else if ((strcmp(var, "LocalUmbruchIns") == 0) && (lo != NULL))
			get_bool(buffer, &(lo->format_by_paste));
		else if ((strcmp(var, "LocalUmbruchLoad") == 0) && (lo != NULL))
			get_bool(buffer, &(lo->format_by_load));
		else if ((strcmp(var, "LocalUmbruchAt") == 0) && (lo != NULL))
		{
			get_str(buffer, lo->umbruch_str);
			str2set(lo->umbruch_str, lo->umbruch_set);
		}
		else if ((strcmp(var, "LocalUmbruchShow") == 0) && (lo != NULL))
			get_bool(buffer, &(lo->show_end));
		else if ((strcmp(var, "LocalWordSet") == 0) && (lo != NULL))
		{
			get_str(buffer, lo->wort_str);
			str2set(lo->wort_str,lo->wort_set);
		}		

		/* Makro */
		else if (strcmp(var, "Makro") == 0)
			set_makro_str(buffer);

		/* Marken */
		else if (strcmp(var, "Marke") == 0)
		{
			get_str(buffer, filename);
			d = sscanf(buffer + strlen(filename) + 3, "%d \"%[^\"]\" %ld %d", &i, tmp, &y, &x);
			if (d != 4)		/* altes Format (<4.10) ohne " um tmp */
				sscanf(buffer + strlen(filename) + 3, "%d %s %ld %d", &i, tmp, &y, &x);
			set_marke(i, tmp, filename, y, x);
		}

		/* offenen Dateien */
		else if (strcmp(var, "OpenPrj") == 0)
		{
			get_str(buffer, filename);
			insert_poslist(arglist, filename, 0, 0);
		}
		else if (strcmp(var, "OpenText") == 0)
		{
			get_str(buffer, filename);
			sscanf(buffer + strlen(filename) + 3, "%ld %d", &y, &x);
			insert_poslist(arglist, filename, x, y);
		}
		
		/* allg. Drucker */
		else if (strcmp(var, "PrintCheck") == 0)
			get_bool(buffer, &pruef_prn);
		else if (strcmp(var, "PrintFormfeed") == 0)
			get_bool(buffer, &vorschub);
		else if (strcmp(var, "PrintLineNumers") == 0)
			get_bool(buffer, &zeilen_nr);
		else if (strcmp(var, "PrintMargin") == 0)
			get_bool(buffer, &use_rand);
		else if (strcmp(var, "PrintMarginLen") == 0)
			rand_len = atoi(buffer);
		else if (strcmp(var, "PrintPageNumbers") == 0)
			get_bool(buffer, &seiten_nr);

		/* Ersetzen */
		else if (strcmp(var, "ReplaceBox") == 0)
			sscanf(buffer, "%d %d", &rp_box_x, &rp_box_y);
		else if (strcmp(var, "ReplaceMode") == 0)
			r_modus = atoi(buffer);
		else if (strcmp(var, "ReplaceStr") == 0)
			get_str(buffer, r_str);
		else if (strcmp(var, "ReplaceHistory") == 0)
		{
			get_str(buffer, tmp);
			for (i = 0; i < HIST_ANZ; i++)
				if (r_history[i][0] == EOS)
					break;
			if (i < HIST_ANZ)
				strcpy(r_history[i], tmp);
		}
		else if (strcmp(var, "ReplaceUmlautFrom") == 0)
			umlaut_from = atoi(buffer);
		else if (strcmp(var, "ReplaceUmlautTo") == 0)
			umlaut_to = atoi(buffer);

		/* Suchen */
		else if (strcmp(var, "SearchDiskName") == 0)
			get_str(buffer, df_name);
		else if (strcmp(var, "SearchDiskRek") == 0)
			get_bool(buffer, &df_rekursiv);
		else if (strcmp(var, "SearchDown") == 0)
			get_bool(buffer, &s_vorw);
		else if (strcmp(var, "SearchGlobal") == 0)
			get_bool(buffer, &s_global);
		else if (strcmp(var, "SearchGrkl") == 0)
			get_bool(buffer, &s_grkl);
		else if (strcmp(var, "SearchHistory") == 0)
		{
			get_str(buffer, tmp);
			for (i = 0; i < HIST_ANZ; i++)
				if (s_history[i][0] == EOS)
					break;
			if (i < HIST_ANZ)
				strcpy(s_history[i], tmp);
		}
		else if (strcmp(var, "SearchQuant") == 0)
			get_bool(buffer, &s_quant);
		else if (strcmp(var, "SearchRound") == 0)
			get_bool(buffer, &s_round);
		else if (strcmp(var, "SearchWord") == 0)
			get_bool(buffer, &s_wort);
		else if (strcmp(var, "SearchStr") == 0)
			get_str(buffer, s_str);
			
		/* SE-Protokoll */
		else if (strcmp(var, "SESave") == 0)
			get_bool(buffer, &se_autosave);
		else if (strcmp(var, "SESearch") == 0)
			get_bool(buffer, &se_autosearch);
		else if (strcmp(var, "SEShellName") == 0)
		{
			get_str(buffer, tmp);
			for (i = 0; i < SHELLANZ; i++)
				if (se_shells[i].Name[0] == EOS)
					break;
			if (i < SHELLANZ)
				strcpy(se_shells[i].Name, tmp);
		}

		/* Fensterfont */
		else if (strcmp(var, "WinFontID") == 0)
			winFont.id = atoi(buffer);
		else if (strcmp(var, "WinFontSize") == 0)
			winFont.pts = atoi(buffer);

		/* Fensterposition */
		else if (strcmp(var, "Window") == 0)
		{
			WORD	class;
			GRECT	size;
			
			sscanf(buffer, "%d %d %d %d %d", &class, &size.g_x, &size.g_y,
																 &size.g_w, &size.g_h);
			add_winlist(class, &size);
		}


		/* nicht mehr vorhandene Zeilen */
		else if ((strcmp(var, "GlobalExtFontsel") == 0) ||
			(strcmp(var, "GlobalDialMac") == 0))
			/* ignore seit 4.10 */ ;

		/* Unbekannte Zeile */
		else
		{
			if (strlen(var) > 28)
				var[28] = EOS;
			fnote(1, WRONGINF, var);
		}
	}
	else
	{
		if (strlen(zeile) > 28)
			zeile[28] = EOS;
		fnote(1, WRONGINF, zeile);
	}
}

GLOBAL WORD	option_load	(POSENTRY **list)
{
	WORD	ret;

	get_cfg_path();
	fd = fopen(cfg_path, "r");
	if (fd != NULL)
	{
		/* 1. Zeile auf ID checken */
		fgets(buffer, (WORD)sizeof(buffer), fd);
		if (strncmp(buffer, "ID=qed", 6) == 0)
		{
			muster_nr = 0;
			while (fgets(buffer, (WORD)sizeof(buffer), fd) != NULL)
			{
				if (buffer[strlen(buffer) - 1] == '\n')
					buffer[strlen(buffer) - 1] = EOS;
				parse_line(list, buffer);
			}
			loc_opt_anz = max(1, muster_nr);
			ret = 0;
		}
		else
		{
			/* Zeile kurzhacken */
			if (strlen(buffer) > 28)
				buffer[28] = EOS;
			fnote(1, WRONGINF, buffer);
			ret = 1;
		}
		fclose(fd);
		fd = NULL;
	}
	else
	{
		fnote(1, READERR, CFGNAME);
		ret = 1;
	}	
	return ret;
}


/******************************************************************************/
/* Dateioperation: Speichern																	*/
/******************************************************************************/
LOCAL VOID write_str(UBYTE *var, UBYTE *value)
{
	if (strchr(value, '\"') != NULL)	/* " in value fhrt zu \" in der Datei */
	{
		WORD	len, i;

		fprintf(fd, "%s=\"", var);
		len = (WORD)strlen(value);
		for (i = 0; i < len; i++)
		{
			if (value[i] == '\"')
				fputc('\\', fd);
			fputc(value[i], fd);
		}
		fprintf(fd, "\"\n");
	}
	else
		fprintf(fd, "%s=\"%s\"\n", var, value);
}

LOCAL VOID write_int(UBYTE *var, WORD value)
{
	fprintf(fd, "%s=%d\n", var, value);
}

LOCAL VOID write_long(UBYTE *var, LONG value)
{
	fprintf(fd, "%s=%ld\n", var, value);
}

LOCAL VOID write_bool(UBYTE *var, BOOLEAN bool)
{
	UBYTE	str[6];
	
	if (bool)
		strcpy(str, "TRUE");
	else
		strcpy(str, "FALSE");
	fprintf(fd, "%s=%s\n", var, str);
}

LOCAL VOID save_open_text(TEXTP t_ptr)
{
	WINDOWP	w = get_window(t_ptr->link);

	if (!t_ptr->namenlos)
	{
		if (w->class == CLASS_EDIT)
		{
			fprintf(fd, "OpenText=\"%s\" %ld %d\n", t_ptr->filename, t_ptr->ypos,
							BildPos(t_ptr->xpos, t_ptr->cursor_line, t_ptr->loc_opt->tab, t_ptr->loc_opt->tabsize));
		}
		if (w->class == CLASS_PROJEKT)
			write_str("OpenPrj", t_ptr->filename); 
	}
}

GLOBAL VOID option_save(VOID)
{
	WORD		i, x;
	LONG		y;
	UBYTE		tmp[50];
	LOCOPTP	lo;

	fd = fopen(cfg_path, "w");
	if (fd != NULL)
	{
		/* ID zur identifizierung */
		fprintf(fd, "ID=qed %s\n", ProgrammVersion);
	
		/* Autosave */	
		write_bool("AutoSavePrj", as_prj);
		write_bool("AutoSavePrjAsk", as_prj_ask);
		write_int("AutoSavePrjMin", as_prj_min);
		write_bool("AutoSaveText", as_text);
		write_bool("AutoSaveTextAsk", as_text_ask);
		write_int("AutoSaveTextMin", as_text_min);
	
		/* Defaultprojekt */
		write_str("DefaultPrj", def_prj_path);
	
		/* Fehlerzeilen */	
		for (i = 0; i < FEHLERANZ; i++)
		{
			if (error[i][0] != EOS)
				write_str("Error", error[i]);
		}
	
		/* GDOS Drucker */
		write_int("GdosDriver", gdos_device);
		write_str("GdosFile", metafile);
		write_int("GdosFontID", druckFont.id);
		write_int("GdosFontSize", druckFont.pts);
		write_bool("GdosMode", use_gdos_print);
	
		/* GEMDOS Drucker */
		write_int("GemdosDensity", wp_mode);
		write_str("GemdosDriver", wp_treiber);
		write_bool("GemdosNLQ", wp_nlq);
		write_int("GemdosPageHeight", wp_seiten_len);
		write_int("GemdosPageWidth", wp_seiten_width);
	
		/* Globales */
		write_bool("GlobalAutosaveCfg", save_opt);
		write_int ("GlobalBinLineLen", bin_line_len);
		write_bool("GlobalBlinkCursor", blinking_cursor);
		write_bool("GlobalCtrlBlock", ctrl_mark_mode);
		write_bool("GlobalDial3d", use_dial_3d);
		write_bool("GlobalFtoDesk", f_to_desk);
		write_bool("GlobalGEMClip", clip_on_disk);
		write_bool("GlobalOverwrite", overwrite);
		write_int ("GlobalTransSize", transfer_size);
		write_bool("GlobalWindCycle", wind_cycle);
	
		/* Hilfeprogramm */
		write_str("HelpProgram", helpprog);
	
		/* Klammerpaare */
		write_str("KlammerAuf", klammer_auf);
		write_str("KlammerZu", klammer_zu);

		/* Lokales */	
		for (i = 0; i < loc_opt_anz; i++)
		{
			lo = &loc_opt[i];

			write_str("LocalBegin", muster_str[i]);			

			write_bool("LocalBackup", lo->backup);
			write_str("LocalBackupExt", lo->backup_ext);
			write_bool("LocalInsert", lo->einruecken);
			write_str("LocalKurzel", lo->kurzel);
			write_bool("LocalTab", lo->tab);
			write_int("LocalTabSize", lo->tabsize);
			write_bool("LocalUmbruch", lo->umbrechen);
			write_int("LocalUmbruchLineLen", lo->lineal_len);
			write_bool("LocalUmbruchIns", lo->format_by_paste);
			write_bool("LocalUmbruchLoad", lo->format_by_load);
			write_str("LocalUmbruchAt", lo->umbruch_str);
			write_bool("LocalUmbruchShow", lo->show_end);
			write_str("LocalWordSet", lo->wort_str);

			write_str("LocalEnd", muster_str[i]);			
		}
	
		/* Makros */
		for (i = 0; i < MAKRO_ANZ; i++)
		{
			if (get_makro_str(i, buffer))
				fprintf(fd, "Makro=%s\n", buffer);
		}
		
		/* Marken */
		for (i = 0; i < MARKEN_ANZ; i++)
		{
			if (get_marke(i, tmp, buffer, &y, &x))
				fprintf(fd, "Marke=\"%s\" %d \"%s\" %ld %d\n", buffer, i, tmp, y, x);
		}
	
		/* geladene Dateien */
		do_all_text(save_open_text);

		/* allg. Drucker */
		write_bool("PrintCheck", pruef_prn);
		write_bool("PrintFormfeed", vorschub);
		write_bool("PrintLineNumers", zeilen_nr);
		write_bool("PrintMargin", use_rand);
		write_int("PrintMarginLen", rand_len);
		write_bool("PrintPageNumbers", seiten_nr);	
	
		/* Ersetzen */
		fprintf(fd, "ReplaceBox=%d %d\n", rp_box_x, rp_box_y);
		write_int("ReplaceMode", r_modus);
		write_str("ReplaceStr", r_str);
		for (i = 0; i < HIST_ANZ; i++)
		{
			if (r_history[i][0] != EOS)
				write_str("ReplaceHistory", r_history[i]);
		}
		write_int("ReplaceUmlautFrom", umlaut_from);				
		write_int("ReplaceUmlautTo", umlaut_to);				

		/* Suchen */
		write_str("SearchDiskName", df_name);
		write_bool("SearchDiskRek", df_rekursiv);
		write_bool("SearchDown", s_vorw);
		write_bool("SearchGlobal", s_global);
		write_bool("SearchGrkl", s_grkl);
		for (i = 0; i < HIST_ANZ; i++)
		{
			if (s_history[i][0] != EOS)
				write_str("SearchHistory", s_history[i]);
		}
		write_bool("SearchQuant", s_quant);
		write_bool("SearchRound", s_round);
		write_bool("SearchWord", s_wort);
		write_str("SearchStr", s_str);

		/* SE-Protokoll */
		write_bool("SESave", se_autosave);
		write_bool("SESearch", se_autosearch);
		for (i = 0; i < SHELLANZ - 1; i++)
		{
			if (se_shells[i].Name[0] != EOS)
				write_str("SEShellName", se_shells[i].Name);
		}			

		/* Fensterfont */	
		write_int("WinFontID", winFont.id);
		write_int("WinFontSize", winFont.pts);
	
		/* Fensterposition */
		save_winlist(fd);
		
		fclose(fd);
		fd = NULL;
	}
	else
		note(1, WRITEERR);
}
