#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <gtk/gtk.h>

#include "../include/fio.h"
#include "../include/disk.h"
#include "../include/string.h"
#include "../include/strexp.h"

#include "guiutils.h"
#include "csd.h"

#include "pref.h"
#include "preffio.h"

#include "manedit.h"
#include "config.h"


#ifndef CFG_COMMENT_CHAR
# define CFG_COMMENT_CHAR	'#'
#endif

#ifndef CFG_DELIMINATOR_CHAR
# define CFG_DELIMINATOR_CHAR	'='
#endif


gint PrefLoadFromFile(pref_struct *pref, const gchar *filename);
gint PrefSaveToFile(pref_struct *pref, const gchar *filename);


/*
 *	Loads preferences from file into pref structure's widgets.
 *
 *	Preference structure must already be initialized.
 *
 *	Returns non-zero on error, -2 if file did not exist, and
 *	-3 if it is a directory.
 */
gint PrefLoadFromFile(pref_struct *pref, const gchar *filename)
{
	gint ignore_all_errors = 0;
	gint vali[10];
	gchar *valtext;
	gint strc;
	gchar **strv;
	csd_color_struct *csd_color_ptr;
	GdkColormap *colormap;
	GdkColor color;
	GtkWidget *w;
	GtkCList *clist;
	FILE *fp;
	gchar *parm = NULL;
	struct stat stat_buf;


	if((pref == NULL) ||
	   (filename == NULL)
	)
	    return(-1);

	if(!pref->initialized)
	    return(-1);

	if(stat(filename, &stat_buf))
	    return(-2);
	if(S_ISDIR(stat_buf.st_mode))
	    return(-3);

	fp = FOpen(filename, "rb");
	if(fp == NULL)
	    return(-2);

	/* Need to clear locations manpage directories clist */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_LOCATIONS_MAN_DIRS
	);
	if((w == NULL) ? 0 : GTK_IS_CLIST(w))
	{
	    clist = GTK_CLIST(w);
	    gtk_clist_freeze(clist);
	    gtk_clist_clear(clist);
	    gtk_clist_thaw(clist);
	}

	/* Update rcfile prompt with given filename */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_LOCATIONS_RCFILE
	);
	if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
	{
	    gtk_entry_set_text(GTK_ENTRY(w), filename);
	}
 

	/* Begin loading and parsing file */
	while(1)
	{
	    parm = FSeekNextParm(
		fp, parm,
		CFG_COMMENT_CHAR, CFG_DELIMINATOR_CHAR
	    );
	    if(parm == NULL)
		break;

	    /* Startup with an editor? */
	    if(!strcasecmp(parm, "startup_editor"))
	    {
		FGetValuesI(fp, vali, 1);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_STARTUP_EDITOR
		);
		if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
		{
		    GTK_TOGGLE_BUTTON(w)->active = ((vali[0]) ?
			TRUE : FALSE
		    );
		}
	    }
	    /* Startup with a viewer? */
	    else if(!strcasecmp(parm, "startup_viewer"))
	    {
		FGetValuesI(fp, vali, 1);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_STARTUP_VIEWER
		);
		if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
		{
		    GTK_TOGGLE_BUTTON(w)->active = ((vali[0]) ?
			TRUE : FALSE  
		    );
		}
	    }
	    /* Record window positions? */
	    else if(!strcasecmp(parm, "record_window_positions"))
	    {
		FGetValuesI(fp, vali, 1);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_RECORD_WIN_POS
		);
		if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
		{
		    GTK_TOGGLE_BUTTON(w)->active = ((vali[0]) ?
			TRUE : FALSE
		    );
		}
	    }
	    /* Enable tooltips? */
	    else if(!strcasecmp(parm, "enable_tooltips"))
	    {
		FGetValuesI(fp, vali, 1);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_TOOL_TIPS
		);
		if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
		{
		    GTK_TOGGLE_BUTTON(w)->active = ((vali[0]) ?
			TRUE : FALSE
		    );
		}
	    }
	    /* Display toolbar buttons as */
	    else if(!strcasecmp(parm, "display_toolbar_buttons"))
	    {
		FGetValuesI(fp, vali, 1);
		switch(vali[0])
		{
		  case 1:	/* Pictures only */
		    w = PrefParmGetWidget(
			pref, MEDIT_PREF_PARM_TOOLBAR_PT
		    );
		    if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
			GTK_TOGGLE_BUTTON(w)->active = FALSE;
		    w = PrefParmGetWidget(
			pref, MEDIT_PREF_PARM_TOOLBAR_P
		    );            
		    if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
			GTK_TOGGLE_BUTTON(w)->active = TRUE;
		    w = PrefParmGetWidget(
			pref, MEDIT_PREF_PARM_TOOLBAR_T
		    );            
		    if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
			GTK_TOGGLE_BUTTON(w)->active = FALSE;
		    break;

		  case 0:       /* Text only */
		    w = PrefParmGetWidget(
			pref, MEDIT_PREF_PARM_TOOLBAR_PT
		    );
		    if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
			GTK_TOGGLE_BUTTON(w)->active = FALSE;
		    w = PrefParmGetWidget(
			pref, MEDIT_PREF_PARM_TOOLBAR_P 
		    );
		    if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
			GTK_TOGGLE_BUTTON(w)->active = FALSE;
		    w = PrefParmGetWidget(
			pref, MEDIT_PREF_PARM_TOOLBAR_T 
		    );
		    if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
			GTK_TOGGLE_BUTTON(w)->active = TRUE;
		    break;

		  default:	/* Assume pictures and text */
		    w = PrefParmGetWidget(
			pref, MEDIT_PREF_PARM_TOOLBAR_PT
		    );            
		    if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
			GTK_TOGGLE_BUTTON(w)->active = TRUE;
		    w = PrefParmGetWidget(
			pref, MEDIT_PREF_PARM_TOOLBAR_P 
		    );
		    if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
			GTK_TOGGLE_BUTTON(w)->active = FALSE;
		    w = PrefParmGetWidget(
			pref, MEDIT_PREF_PARM_TOOLBAR_T
		    );
		    if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
			GTK_TOGGLE_BUTTON(w)->active = FALSE;
		    break;
		}
	    }       

	    /* Font: Editable normal? */
	    else if(!strcasecmp(parm, "font_editable_normal"))
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_FONT_EDIT_STD
		);
		if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
		{
		    if(valtext != NULL)
			gtk_entry_set_text(GTK_ENTRY(w), valtext);
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Font: ManPage normal? */
	    else if(!strcasecmp(parm, "font_manpage_normal"))
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_FONT_MANPAGE_STD
		);
		if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
		{
		    if(valtext != NULL)
			gtk_entry_set_text(GTK_ENTRY(w), valtext);
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Font: ManPage bold? */
	    else if(!strcasecmp(parm, "font_manpage_bold"))
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_FONT_MANPAGE_BOLD
		);
		if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
		{
		    if(valtext != NULL)
			gtk_entry_set_text(GTK_ENTRY(w), valtext);
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Font: ManPage underline? */
	    else if(!strcasecmp(parm, "font_manpage_underline"))
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_FONT_MANPAGE_UNDERLINE
		);
		if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
		{
		    if(valtext != NULL)
			gtk_entry_set_text(GTK_ENTRY(w), valtext);
		}
		g_free(valtext);
		valtext = NULL;
	    }

	    /* Color: Editable text foreground? */
	    else if(!strcasecmp(parm, "color_editable_foreground") ||
		    !strcasecmp(parm, "colour_editable_foreground")
	    )
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_COLOR_EDIT_TEXT_FG
		);
		if((w != NULL) && (valtext != NULL))
		{
		    csd_color_ptr = (csd_color_struct *)
			gtk_object_get_user_data(GTK_OBJECT(w));
		    colormap = gtk_widget_get_colormap(w);
		    if((csd_color_ptr != NULL) && (colormap != NULL))
		    {
			gdk_color_parse(valtext, &color);
			gdk_color_alloc(colormap, &color);
			csd_color_ptr->a = 1.0;
			csd_color_ptr->r = (gdouble)color.red / 65535.0;
			csd_color_ptr->g = (gdouble)color.green / 65535.0;
			csd_color_ptr->b = (gdouble)color.blue / 65535.0;
			if(!GTK_WIDGET_NO_WINDOW(w))
			{
			    gdk_window_set_background(w->window, &color);
			    gdk_window_clear(w->window);
			}
		    }
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Color: Editable text background? */
	    else if(!strcasecmp(parm, "color_editable_background") ||
		    !strcasecmp(parm, "colour_editable_background")
	    )
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_COLOR_EDIT_TEXT_BG
		);
		if((w != NULL) && (valtext != NULL))
		{
		    csd_color_ptr = (csd_color_struct *)
			gtk_object_get_user_data(GTK_OBJECT(w));
		    colormap = gtk_widget_get_colormap(w);
		    if((csd_color_ptr != NULL) && (colormap != NULL))
		    {
			gdk_color_parse(valtext, &color);         
			gdk_color_alloc(colormap, &color);
			csd_color_ptr->a = 1.0;
			csd_color_ptr->r = (gdouble)color.red / 65535.0;
			csd_color_ptr->g = (gdouble)color.green / 65535.0;
			csd_color_ptr->b = (gdouble)color.blue / 65535.0;
			if(!GTK_WIDGET_NO_WINDOW(w))
			{
			    gdk_window_set_background(w->window, &color);
			    gdk_window_clear(w->window);
			}
		    }
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Color: Editable text XML deliminator? */
	    else if(!strcasecmp(parm, "color_editable_xml_deliminator") ||   
		    !strcasecmp(parm, "colour_editable_xml_deliminator")
	    )
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_COLOR_EDIT_TEXT_DELIM
		);
		if((w != NULL) && (valtext != NULL))
		{
		    csd_color_ptr = (csd_color_struct *)
			gtk_object_get_user_data(GTK_OBJECT(w));
		    colormap = gtk_widget_get_colormap(w);
		    if((csd_color_ptr != NULL) && (colormap != NULL))
		    {
			gdk_color_parse(valtext, &color);         
			gdk_color_alloc(colormap, &color);
			csd_color_ptr->a = 1.0;
			csd_color_ptr->r = (gdouble)color.red / 65535.0;
			csd_color_ptr->g = (gdouble)color.green / 65535.0;
			csd_color_ptr->b = (gdouble)color.blue / 65535.0;
			if(!GTK_WIDGET_NO_WINDOW(w))
			{
			    gdk_window_set_background(w->window, &color);
			    gdk_window_clear(w->window);
			}
		    }
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Color: Editable text XML tag? */
	    else if(!strcasecmp(parm, "color_editable_xml_tag") ||   
		    !strcasecmp(parm, "colour_editable_xml_tag")
	    )
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_COLOR_EDIT_TEXT_TAG
		);
		if((w != NULL) && (valtext != NULL))
		{
		    csd_color_ptr = (csd_color_struct *)
			gtk_object_get_user_data(GTK_OBJECT(w));
		    colormap = gtk_widget_get_colormap(w);
		    if((csd_color_ptr != NULL) && (colormap != NULL))
		    {
			gdk_color_parse(valtext, &color);         
			gdk_color_alloc(colormap, &color);
			csd_color_ptr->a = 1.0;
			csd_color_ptr->r = (gdouble)color.red / 65535.0;
			csd_color_ptr->g = (gdouble)color.green / 65535.0;
			csd_color_ptr->b = (gdouble)color.blue / 65535.0;
			if(!GTK_WIDGET_NO_WINDOW(w))
			{
			    gdk_window_set_background(w->window, &color);
			    gdk_window_clear(w->window);
			}
		    }
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Color: Editable text XML symbolic representationd? */
	    else if(!strcasecmp(parm, "color_editable_xml_symrep") ||   
		    !strcasecmp(parm, "colour_editable_xml_symrep")
	    )
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_COLOR_EDIT_TEXT_SYMREP
		);
		if((w != NULL) && (valtext != NULL))
		{
		    csd_color_ptr = (csd_color_struct *)
			gtk_object_get_user_data(GTK_OBJECT(w));
		    colormap = gtk_widget_get_colormap(w);
		    if((csd_color_ptr != NULL) && (colormap != NULL))
		    {
			gdk_color_parse(valtext, &color);         
			gdk_color_alloc(colormap, &color);
			csd_color_ptr->a = 1.0;
			csd_color_ptr->r = (gdouble)color.red / 65535.0;
			csd_color_ptr->g = (gdouble)color.green / 65535.0;
			csd_color_ptr->b = (gdouble)color.blue / 65535.0;
			if(!GTK_WIDGET_NO_WINDOW(w))
			{
			    gdk_window_set_background(w->window, &color);
			    gdk_window_clear(w->window);
			}
		    }
		}
		g_free(valtext);
		valtext = NULL;
	    }

	    /* Color: ManPage text foreground? */
	    else if(!strcasecmp(parm, "color_manpage_foreground") ||   
		    !strcasecmp(parm, "colour_manpage_foreground")
	    )
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_FG
		);
		if((w != NULL) && (valtext != NULL))
		{
		    csd_color_ptr = (csd_color_struct *)
			gtk_object_get_user_data(GTK_OBJECT(w));
		    colormap = gtk_widget_get_colormap(w);
		    if((csd_color_ptr != NULL) && (colormap != NULL))
		    {
			gdk_color_parse(valtext, &color);         
			gdk_color_alloc(colormap, &color);
			csd_color_ptr->a = 1.0;
			csd_color_ptr->r = (gdouble)color.red / 65535.0;
			csd_color_ptr->g = (gdouble)color.green / 65535.0;
			csd_color_ptr->b = (gdouble)color.blue / 65535.0;
			if(!GTK_WIDGET_NO_WINDOW(w))
			{
			    gdk_window_set_background(w->window, &color);
			    gdk_window_clear(w->window);
			}
		    }
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Color: ManPage text background? */
	    else if(!strcasecmp(parm, "color_manpage_background") ||
		    !strcasecmp(parm, "colour_manpage_background")
	    )
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_BG
		);
		if((w != NULL) && (valtext != NULL))
		{
		    csd_color_ptr = (csd_color_struct *)
			gtk_object_get_user_data(GTK_OBJECT(w));
		    colormap = gtk_widget_get_colormap(w);
		    if((csd_color_ptr != NULL) && (colormap != NULL))
		    {
			gdk_color_parse(valtext, &color);
			gdk_color_alloc(colormap, &color);
			csd_color_ptr->a = 1.0;
			csd_color_ptr->r = (gdouble)color.red / 65535.0;
			csd_color_ptr->g = (gdouble)color.green / 65535.0;
			csd_color_ptr->b = (gdouble)color.blue / 65535.0;
			if(!GTK_WIDGET_NO_WINDOW(w))
			{
			    gdk_window_set_background(w->window, &color);
			    gdk_window_clear(w->window);
			}
		    }
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Color: ManPage text bold? */
	    else if(!strcasecmp(parm, "color_manpage_bold") ||
		    !strcasecmp(parm, "colour_manpage_bold")
	    )
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_BOLD
		);
		if((w != NULL) && (valtext != NULL))
		{
		    csd_color_ptr = (csd_color_struct *)
			gtk_object_get_user_data(GTK_OBJECT(w));
		    colormap = gtk_widget_get_colormap(w);
		    if((csd_color_ptr != NULL) && (colormap != NULL))
		    {
			gdk_color_parse(valtext, &color);
			gdk_color_alloc(colormap, &color);
			csd_color_ptr->a = 1.0;
			csd_color_ptr->r = (gdouble)color.red / 65535.0;
			csd_color_ptr->g = (gdouble)color.green / 65535.0;
			csd_color_ptr->b = (gdouble)color.blue / 65535.0;
			if(!GTK_WIDGET_NO_WINDOW(w))
			{
			    gdk_window_set_background(w->window, &color);
			    gdk_window_clear(w->window);
			}
		    }
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Color: ManPage text underline? */
	    else if(!strcasecmp(parm, "color_manpage_underline") ||
		    !strcasecmp(parm, "colour_manpage_underline")
	    )
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_UNDERLINE
		);
		if((w != NULL) && (valtext != NULL))
		{
		    csd_color_ptr = (csd_color_struct *)
			gtk_object_get_user_data(GTK_OBJECT(w));
		    colormap = gtk_widget_get_colormap(w);
		    if((csd_color_ptr != NULL) && (colormap != NULL))
		    {
			gdk_color_parse(valtext, &color);
			gdk_color_alloc(colormap, &color);
			csd_color_ptr->a = 1.0;
			csd_color_ptr->r = (gdouble)color.red / 65535.0;
			csd_color_ptr->g = (gdouble)color.green / 65535.0;
			csd_color_ptr->b = (gdouble)color.blue / 65535.0;
			if(!GTK_WIDGET_NO_WINDOW(w))
			{
			    gdk_window_set_background(w->window, &color);
			    gdk_window_clear(w->window);
			}
		    }
		}
		g_free(valtext);
		valtext = NULL;
	    }

	    /* Enable syntax highlighting? */
	    else if(!strcasecmp(parm, "enable_syntax_highlighting"))
	    {
		FGetValuesI(fp, vali, 1);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_EDITOR_ENABLE_SYNHL
		);
		if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
		{
		    GTK_TOGGLE_BUTTON(w)->active = ((vali[0]) ?
			TRUE : FALSE
		    );
		}
	    }

	    /* Locations: RCFile (skipped) */
	    /* Locations: Global data directory? */
	    else if(!strcasecmp(parm, "global_data_dir") ||
		    !strcasecmp(parm, "global_data_directory")
	    )
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_LOCATIONS_GLOBAL_DIR
		);
		if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
		{
		    if(valtext != NULL)
			gtk_entry_set_text(GTK_ENTRY(w), valtext);
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Locations: Tempory directory? */
	    else if(!strcasecmp(parm, "tmp_dir") ||
		    !strcasecmp(parm, "tmp_directory")
	    )
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_LOCATIONS_TMP_DIR
		);
		if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
		{
		    if(valtext != NULL)
			gtk_entry_set_text(GTK_ENTRY(w), valtext);
		}
		g_free(valtext);
		valtext = NULL;
	    }
	    /* Locations: ManPage directories? */
	    else if(!strcasecmp(parm, "manpage_dir") ||
		    !strcasecmp(parm, "manpage_directory")
	    )
	    {
		valtext = FGetString(fp);

		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_LOCATIONS_MAN_DIRS
		);
		if((w == NULL) ? 0 : GTK_IS_CLIST(w))
		{
		    clist = GTK_CLIST(w);

		    /* Explode arguments at ';' deliminators */
		    strv = strchrexp(valtext, ';', &strc);

		    /* Append to clist only if we got enough items */
		    if(strc >= 2)
			gtk_clist_append(clist, strv);

		    /* Delete exploded strings */
		    strlistfree(strv, strc);
		    strv = NULL;
		    strc = 0;
		}

		g_free(valtext);
		valtext = NULL;
	    }

	    /* Converters: ManPage to Output command */
	    else if(!strcasecmp(parm, "manpage_to_output_command"))
	    {
		valtext = FGetString(fp);
		w = PrefParmGetWidget(
		    pref, MEDIT_PREF_PARM_CONVERTERS_MANPAGE_TO_OUTPUT
		);
		if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
		{
		    if(valtext != NULL)
			gtk_entry_set_text(GTK_ENTRY(w), valtext);
		}
		g_free(valtext);
		valtext = NULL;
	    }

	    /* Last editor geometry */
	    else if(!strcasecmp(parm, "last_editor_geometry"))
	    {
		FGetValuesI(fp, vali, 4);

		pref->last_editor_width = ((vali[2] > 10) ?
		    vali[2] : MEDIT_DEF_WIDTH
		);
		pref->last_editor_height = ((vali[3] > 10) ?
		    vali[3] : MEDIT_DEF_HEIGHT
		);
	    }
	    /* Last viewer geometry */
	    else if(!strcasecmp(parm, "last_viewer_geometry"))
	    {
		FGetValuesI(fp, vali, 4);

		pref->last_viewer_width = ((vali[2] > 10) ?
		    vali[2] : MEDIT_VIEWER_DEF_WIDTH
		);
		pref->last_viewer_height = ((vali[3] > 10) ?
		    vali[3] : MEDIT_VIEWER_DEF_HEIGHT
		);
	    }

	    /* Last editor opened manpage path? */
	    else if(!strcasecmp(parm, "last_editor_opened_manpage_path"))
	    {
		g_free(pref->last_opened_manpage_path);
		pref->last_opened_manpage_path = FGetString(fp);
	    }
	    /* Last editor saved manpage path? */
	    else if(!strcasecmp(parm, "last_editor_saved_manpage_path"))
	    {
		g_free(pref->last_saved_manpage_path);
		pref->last_saved_manpage_path = FGetString(fp);
	    }
	    /* Last viewer opened manpage path? */
	    else if(!strcasecmp(parm, "last_viewer_opened_manpage_path"))
	    {
		g_free(pref->last_opened_manage_view_path);
		pref->last_opened_manage_view_path = FGetString(fp);
	    }

	    else
	    {
		if(!ignore_all_errors)
		    g_printerr(
			"%s: Warning: Unsupported parameter `%s'.\n",
			filename, parm
		    );

		FSeekNextLine(fp);
	    }
	}

	FClose(fp);

	return(0);
}


/*
 *	Saves preferences to file.
 *
 *	Returns non-zero on error, -2 if file is not writeable.
 */
gint PrefSaveToFile(pref_struct *pref, const gchar *filename)
{
	GtkWidget *w;
	GtkCList *clist;
	FILE *fp;
	const gchar *parm;
	csd_color_struct *csd_color_ptr;


	if((pref == NULL) || (filename == NULL))
	    return(-1);

	if(!pref->initialized)   
	    return(-1);

	/* Open file for writing */
	fp = FOpen(filename, "wb");
	if(fp == NULL)
	    return(-2);

	/* Begin writing configuration */

	/* Header */
	fprintf(
	    fp,
	    "%c %s Version %s Configuration\n\n",
	    CFG_COMMENT_CHAR, PROG_NAME_FULL, PROG_VERSION
	);

	/* Startup with an editor */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_STARTUP_EDITOR
	);
	parm = "startup_editor";
	if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
	{
	    fprintf(
		fp,
		"%s %c %i\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		(GTK_TOGGLE_BUTTON(w)->active) ?
		    1 : 0
	    );
	}
	/* Startup with a viewer */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_STARTUP_VIEWER
	);
	parm = "startup_viewer";
	if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
	{
	    fprintf(
		fp,
		"%s %c %i\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		(GTK_TOGGLE_BUTTON(w)->active) ?
		    1 : 0
	    );
	}
	/* Record window positions */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_RECORD_WIN_POS
	);
	parm = "record_window_positions";
	if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
	{
	    fprintf(
		fp,
		"%s %c %i\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		(GTK_TOGGLE_BUTTON(w)->active) ?
		    1 : 0
	    );
	}
	/* Last editor geometry */
	parm = "last_editor_geometry";
	if(1)
	{
	    fprintf(
		fp,
		"%s %c %i %i %i %i\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		0, 0,
		pref->last_editor_width,
		pref->last_editor_height
	    );
	}
	/* Last viewer geometry */
	parm = "last_viewer_geometry";
	if(1)
	{
	    fprintf(
		fp,
		"%s %c %i %i %i %i\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		0, 0,
		pref->last_viewer_width,
		pref->last_viewer_height
	    );
	}
	/* Last editor opened manpage path */
	parm = "last_editor_opened_manpage_path";
	if(pref->last_opened_manpage_path != NULL)
	{
	    fprintf(
		fp,
		"%s %c %s\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		pref->last_opened_manpage_path
	    );
	}
	/* Last editor saved manpage path */
	parm = "last_editor_saved_manpage_path";
	if(pref->last_saved_manpage_path != NULL)
	{
	    fprintf(
		fp,
		"%s %c %s\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		pref->last_saved_manpage_path
	    );
	}
	/* Last viewer opened manpage path? */
	parm = "last_viewer_opened_manpage_path";
	if(pref->last_opened_manage_view_path != NULL)
	{
	    fprintf(
		fp,
		"%s %c %s\n",
		parm,
		CFG_DELIMINATOR_CHAR, 
		pref->last_opened_manage_view_path
	    );
	}
	/* Enable tooltips */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_TOOL_TIPS
	);
	parm = "enable_tooltips";
	if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
	{
	    fprintf(
		fp,
		"%s %c %i\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		(GTK_TOGGLE_BUTTON(w)->active) ? 
		    1 : 0
	    );
	}
	/* Toolbar buttons */
	parm = "display_toolbar_buttons";
	if(PrefParmGetValueB(pref, MEDIT_PREF_PARM_TOOLBAR_P))
	{
	    fprintf(
		fp,
		"%s %c %i\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		1
	    );
	}
	else if(PrefParmGetValueB(pref, MEDIT_PREF_PARM_TOOLBAR_T))
	{
	    fprintf(
		fp,
		"%s %c %i\n",   
		parm,
		CFG_DELIMINATOR_CHAR,
		0
	    );
	}
	else
	{
	    /* All else assume pictures and text */
	    fprintf(
		fp,
		"%s %c %i\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		2
	    );
	}

	/* Font: Editable normal */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_FONT_EDIT_STD
	);
	parm = "font_editable_normal";
	if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
	{
	    fprintf(
		fp,
		"%s %c %s\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		gtk_entry_get_text(GTK_ENTRY(w))
	    );
	}
	/* Font: ManPage normal */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_FONT_MANPAGE_STD
	);
	parm = "font_manpage_normal";
	if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
	{
	    fprintf(
		fp,
		"%s %c %s\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		gtk_entry_get_text(GTK_ENTRY(w))
	    );
	}
	/* Font: ManPage bold */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_FONT_MANPAGE_BOLD
	);
	parm = "font_manpage_bold";
	if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
	{
	    fprintf(
		fp,
		"%s %c %s\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		gtk_entry_get_text(GTK_ENTRY(w))
	    );
	}
	/* Font: ManPage underline */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_FONT_MANPAGE_UNDERLINE
	);
	parm = "font_manpage_underline";
	if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
	{
	    fprintf(
		fp,
		"%s %c %s\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		gtk_entry_get_text(GTK_ENTRY(w))
	    );
	}

	/* Color: Editable text foreground */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_COLOR_EDIT_TEXT_FG
	);
	parm = "color_editable_foreground";
	if(w != NULL)
	{
	    csd_color_ptr = (csd_color_struct *)
		gtk_object_get_user_data(GTK_OBJECT(w));
	    if(csd_color_ptr != NULL)
	    {
		fprintf(
		    fp,
		    "%s %c rgb:%.4x/%.4x/%.4x\n",
		    parm,
		    CFG_DELIMINATOR_CHAR,
		    (guint)(csd_color_ptr->r * 65535.0),
		    (guint)(csd_color_ptr->g * 65535.0),
		    (guint)(csd_color_ptr->b * 65535.0)
		);
	    }
	}
	/* Color: Editable text background */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_COLOR_EDIT_TEXT_BG
	);
	parm = "color_editable_background";
	if(w != NULL)
	{
	    csd_color_ptr = (csd_color_struct *)
		gtk_object_get_user_data(GTK_OBJECT(w));
	    if(csd_color_ptr != NULL)
	    {
		fprintf(
		    fp,
		    "%s %c rgb:%.4x/%.4x/%.4x\n",
		    parm,
		    CFG_DELIMINATOR_CHAR,
		    (guint)(csd_color_ptr->r * 65535.0),
		    (guint)(csd_color_ptr->g * 65535.0),
		    (guint)(csd_color_ptr->b * 65535.0)
		);
	    }
	}
	/* Color: Editable text XML deliminator */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_COLOR_EDIT_TEXT_DELIM
	);
	parm = "color_editable_xml_deliminator";
	if(w != NULL)
	{
	    csd_color_ptr = (csd_color_struct *)
		gtk_object_get_user_data(GTK_OBJECT(w));
	    if(csd_color_ptr != NULL)
	    {
		fprintf(
		    fp,
		    "%s %c rgb:%.4x/%.4x/%.4x\n",
		    parm,
		    CFG_DELIMINATOR_CHAR,
		    (guint)(csd_color_ptr->r * 65535.0),
		    (guint)(csd_color_ptr->g * 65535.0),
		    (guint)(csd_color_ptr->b * 65535.0)
		);
	    }
	}
	/* Color: Editable text XML tag */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_COLOR_EDIT_TEXT_TAG
	);
	parm = "color_editable_xml_tag";
	if(w != NULL)
	{
	    csd_color_ptr = (csd_color_struct *)
		gtk_object_get_user_data(GTK_OBJECT(w));
	    if(csd_color_ptr != NULL)
	    {
		fprintf(
		    fp,
		    "%s %c rgb:%.4x/%.4x/%.4x\n",
		    parm,
		    CFG_DELIMINATOR_CHAR,
		    (guint)(csd_color_ptr->r * 65535.0),
		    (guint)(csd_color_ptr->g * 65535.0),
		    (guint)(csd_color_ptr->b * 65535.0)
		);
	    }
	}
	/* Color: Editable text XML symrep */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_COLOR_EDIT_TEXT_SYMREP
	);
	parm = "color_editable_xml_symrep";
	if(w != NULL)
	{
	    csd_color_ptr = (csd_color_struct *)
		gtk_object_get_user_data(GTK_OBJECT(w));
	    if(csd_color_ptr != NULL) 
	    {
		fprintf(
		    fp,
		    "%s %c rgb:%.4x/%.4x/%.4x\n",
		    parm,
		    CFG_DELIMINATOR_CHAR,
		    (guint)(csd_color_ptr->r * 65535.0),
		    (guint)(csd_color_ptr->g * 65535.0),
		    (guint)(csd_color_ptr->b * 65535.0)
		);
	    }
	}

	/* Color: ManPage text foreground */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_FG
	);
	parm = "color_manpage_foreground";
	if(w != NULL)
	{
	    csd_color_ptr = (csd_color_struct *)
		gtk_object_get_user_data(GTK_OBJECT(w));
	    if(csd_color_ptr != NULL)
	    {
		fprintf(
		    fp,
		    "%s %c rgb:%.4x/%.4x/%.4x\n",
		    parm,
		    CFG_DELIMINATOR_CHAR,
		    (guint)(csd_color_ptr->r * 65535.0),
		    (guint)(csd_color_ptr->g * 65535.0),
		    (guint)(csd_color_ptr->b * 65535.0)
		);
	    }
	}
	/* Color: ManPage background */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_BG
	);
	parm = "color_manpage_background";
	if(w != NULL)
	{
	    csd_color_ptr = (csd_color_struct *)
		gtk_object_get_user_data(GTK_OBJECT(w));
	    if(csd_color_ptr != NULL)
	    {
		fprintf(
		    fp,
		    "%s %c rgb:%.4x/%.4x/%.4x\n",
		    parm,
		    CFG_DELIMINATOR_CHAR,
		    (guint)(csd_color_ptr->r * 65535.0),
		    (guint)(csd_color_ptr->g * 65535.0),
		    (guint)(csd_color_ptr->b * 65535.0)
		);
	    }
	}
	/* Color: ManPage text bold */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_BOLD
	);
	parm = "color_manpage_bold";
	if(w != NULL)
	{
	    csd_color_ptr = (csd_color_struct *)
		gtk_object_get_user_data(GTK_OBJECT(w));
	    if(csd_color_ptr != NULL)
	    {
		fprintf(
		    fp,
		    "%s %c rgb:%.4x/%.4x/%.4x\n",
		    parm,
		    CFG_DELIMINATOR_CHAR,
		    (guint)(csd_color_ptr->r * 65535.0),
		    (guint)(csd_color_ptr->g * 65535.0),
		    (guint)(csd_color_ptr->b * 65535.0)
		);
	    }
	}
	/* Color: ManPage text underline */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_COLOR_MANPAGE_TEXT_UNDERLINE
	);
	parm = "color_manpage_underline";
	if(w != NULL)  
	{
	    csd_color_ptr = (csd_color_struct *)
		gtk_object_get_user_data(GTK_OBJECT(w));
	    if(csd_color_ptr != NULL)
	    {
		fprintf(
		    fp,
		    "%s %c rgb:%.4x/%.4x/%.4x\n",
		    parm,
		    CFG_DELIMINATOR_CHAR,
		    (guint)(csd_color_ptr->r * 65535.0),
		    (guint)(csd_color_ptr->g * 65535.0),
		    (guint)(csd_color_ptr->b * 65535.0)
		);
	    }
	}

	/* Syntax highlighting */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_EDITOR_ENABLE_SYNHL
	);
	parm = "enable_syntax_highlighting";
	if((w == NULL) ? 0 : GTK_IS_TOGGLE_BUTTON(w))
	{
	    fprintf(
		fp,
		"%s %c %i\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		(GTK_TOGGLE_BUTTON(w)->active) ?
		    1 : 0
	    );
	}
	/* Locations: RCFile (skipped) */
	/* Locations: Global data directory */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_LOCATIONS_GLOBAL_DIR
	);
	parm = "global_data_dir";
	if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
	{
	    fprintf(   
		fp,
		"%s %c %s\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		gtk_entry_get_text(GTK_ENTRY(w))
	    );
	}
	/* Locations: Tempory directory */ 
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_LOCATIONS_TMP_DIR
	);
	parm = "tmp_dir";
	if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
	{
	    fprintf(
		fp,
		"%s %c %s\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		gtk_entry_get_text(GTK_ENTRY(w))
	    );
	}
	/* Locations: ManPage directories */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_LOCATIONS_MAN_DIRS
	);
	parm = "manpage_dir";
	if((w == NULL) ? 0 : GTK_IS_CLIST(w))
	{
	    gint row;
	    gchar *path_ptr, *label_ptr;


	    clist = GTK_CLIST(w);

	    for(row = 0; row < clist->rows; row++)
	    {
		if(!gtk_clist_get_text(clist, row, 0, &path_ptr))
		    path_ptr = NULL;
		if(path_ptr != NULL)
		    path_ptr = strdup(path_ptr);

		if(!gtk_clist_get_text(clist, row, 1, &label_ptr))
		    label_ptr = NULL;
		if(label_ptr != NULL)
		    label_ptr = strdup(label_ptr);

		fprintf(
		    fp,
		    "%s %c %s;%s\n",
		    parm,
		    CFG_DELIMINATOR_CHAR,
		    path_ptr, label_ptr
		);

		g_free(path_ptr);
		g_free(label_ptr);
	    }
	}

	/* Converters: ManPage directories */
	w = PrefParmGetWidget(
	    pref, MEDIT_PREF_PARM_CONVERTERS_MANPAGE_TO_OUTPUT
	);
	parm = "manpage_to_output_command";
	if((w == NULL) ? 0 : GTK_IS_ENTRY(w))
	{
	    fprintf(
		fp,
		"%s %c %s\n",
		parm,
		CFG_DELIMINATOR_CHAR,
		gtk_entry_get_text(GTK_ENTRY(w))
	    );
	}    


	/* Close file */
	FClose(fp);

	return(0);
}
