/*
 *
 *	config.c
 *
 *	Routines for reading and writing a configuration file.
 *
 *	HNMS User Interface
 *	HNMS 2.0
 *
 *	February 1994
 *
 *	Leslie Schlecht
 *	Computer Sciences Corporation
 *	Numerical Aerodynamic Simulation Systems Division
 *	NASA Ames Research Center
 *
 *	Copyright (c) 1994 Leslie Schlecht
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 1, or (at your option)
 *	any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include	<stdio.h>
#include	<string.h>
#include	<time.h>

#include	<X11/StringDefs.h>
#include	<X11/Intrinsic.h>
#include	<X11/Shell.h>
#include	<X11/Core.h>
#include	<Xm/Xm.h>
#include	<Xm/FileSB.h>
#include	<Xm/PushB.h>

#include	"defines.h"
#include	"externs.h"
#include	"viewpanel.h"
#include	"view.h"
#include	"config.h"

static Widget	config_panel;
static FILE	*fp;
static int	current_rec, error_flag;

/*
 *	Close the configuration panel.
 */
void
CloseConfigurationPanel(widg, save, cb)
Widget	widg;
int	save;
XmFileSelectionBoxCallbackStruct	*cb;
	{
	char	*f;

	XtUnmanageChild(config_panel);
	if (save) {
		f = exstr(cb->value);
		if (!strlen(f)) {
			LogMessage("No file name, nothing saved.\n");
			return;
			}
		if (!(fp = fopen(f, "w"))) {
			LogMessage(logbuf("Unable to open %s for output.\n",
				f));
			return;
			}
		SaveMainPanel();
		SaveServerPanel();
		SaveObjectList();
		SaveViews();
		fclose(fp);
		}
	}


/*
 *	Create the configuration panel.
 */
void
CreateConfigurationPanel(parent, b)
Widget	parent;
Widget	b;
	{
	XtAddCallback(b, XmNactivateCallback, OpenConfigurationPanel, NULL);

	config_panel = XmCreateFileSelectionDialog(parent,
		"configuration", NULL, 0);
	XtAddCallback(config_panel, XmNcancelCallback, CloseConfigurationPanel, 0);
	XtAddCallback(config_panel, XmNokCallback, CloseConfigurationPanel, 1);
	}


/*
 *	Load the configuration file.
 */
void
LoadConfiguration(f)
char	*f;
	{
	char	*view, *variable, *value;

	if ((fp = fopen(f, "r")) == NULL) {
		LogMessage(logbuf("Unable to open %s for input.\n", f));
		return;
		}
	while (ReadConfiguration(&view, &variable, &value)) {
		/*
		printf("view=%s variable=%s value=%s\n", view, variable, value);
		*/
		if (strcmp(view, "hnms") == 0)
			ConfigureMainPanel(variable, value);
		else if (strcmp(view, "server") == 0)
			ConfigureServerPanel(variable, value);
		else if (strcmp(view, "objectlist") == 0)
			ConfigureObjectList(variable, value);
		else
			ConfigureView(view, variable, value);
		free(view);
		free(variable);
		free(value);
		}
	close(fp);
	}

/*
 *	Open the configuration panel.
 */
void
OpenConfigurationPanel(w, a1, a2)
Widget	w;
caddr_t	a1, a2;
	{
	XtManageChild(config_panel);
	}


/*
 *	Split a configuration record into view name, variable
 *	name, and value string.
 */
int
ParseConfiguration(buf, view, variable, value)
char	*buf, **view, **variable, **value;
	{
	char	*c1, *c2;

	for (c1=buf; (*c1) != '.'; c1++)
		if (!(*c1)) return(0);
	*c1 = '\0';
	c1 ++;
	*view = buf;
	for (c2=c1; *c2!=':'; c2++)
		if (!(*c2)) return(0);
	*c2 = '\0';
	c2 ++;
	*variable = c1;
	for (c1=c2; ((*c1==' ') || (*c1=='	')); c1++)
		if (!(*c1)) return(0);
	*value = c1;
	return(1);
	}


/*
 *	Write a record to the configuration file.
 */
void
PutConfiguration(v, s, value, type)
char	*v, *s;
caddr_t	value;
int	type;
	{
	char	buf[BUFSIZ];

	switch (type) {
	/* integer value */
	case 1:
		sprintf(buf, "%s.%s: %d\n", v, s, (int)value);
		break;
	/* string value */
	case 2:
		sprintf(buf, "%s.%s: %s\n", v, s, value);
		break;
	/* list value */
	case 3:
		strcpy(buf, v);
		strcat(buf, ".");
		strcat(buf, s);
		strcat(buf, ": {\n");
		if (value) strcat(buf, value);
		strcat(buf, "}\n");
		break;
	default:;
		}
	fputs(buf, fp);
	}


/*
 *	Read a configuration file record.
 */
int
ReadConfiguration(view, variable, value)
char	**view, **variable, **value;
	{
	static char	buf1[BUFSIZ], buf2[BUFSIZ], *vw, *vr, *vl;
	int		list=0;

	while (1) {
		if (!fgets(buf1, BUFSIZ, fp)) return(0);
		current_rec ++;
		if (!list) {
			if (!ParseConfiguration(buf1, &vw, &vr, &vl)) {
				LogMessage(
				logbuf("Error in configuration file line %d\n",
					current_rec));
				return(1);
				}
			*view = newstr(vw);
			*variable = newstr(vr);
			/* continue reading if list */
			if (strchr(vl, '{')) {
				list = 1;
				buf2[0] = '\0';
				}
			else {
				vl[strlen(vl)-1] = '\0';
				*value = newstr(vl);
				return(1);
				}
			}
		else {
			/* end of list */
			if (strchr(buf1, '}')) {
				*value = newstr(buf2);
				return(1);
				}
			strcat(buf2, buf1);
			}
		}
	}
