/**
 * Author: Saravana Krishnan Kannan
 * Date: Sometime around 24-April-2004!
 * Description: This file contains the functions for reading the configuration
 * file and setting up the sigcfg structure array which contain various data
 * related to a signal/reading. 
 **/

#include <confuse.h>
#include "conf.h"
#include <string.h>

SIGNALCFG sigcfg[CFG_CNT] =
{
 {NULL, NULL, 0, 0, 0, TRUE},
 {NULL, NULL, 0, 0, 0, TRUE},
 {NULL, NULL, 0, 0, 0, TRUE},
 {NULL, NULL, 0, 0, 0, TRUE},
 {NULL, NULL, 0, 0, 0, TRUE},
 {NULL, NULL, 0, 0, 0, TRUE}
};

/* Read the configuration from the file. */
int read_config(char *fname)
{
	unsigned int i;
	cfg_t *cfg;
	unsigned n;
	/* Set up the data structures for reading the config file. */
	/* The Structure below describes to the library the various variables
	 * to expect with-in a section - in our case we call it the "signal"
	 * section. */
	static cfg_opt_t signal_opts[] = 
	{
		CFG_STR("file", 0, CFGF_NONE),
		CFG_FLOAT("rawmax", 100.0, CFGF_NONE),
		CFG_FLOAT("expectedmax", 100.0, CFGF_NONE),
		CFG_STR("graphcolor", "0x0000FF", CFGF_NONE),
		CFG_BOOL("grid", cfg_false, CFGF_NONE),
		CFG_FLOAT("gridstep", 0.0, CFGF_NONE),
		CFG_STR("gridbgcolor", "0xDDEEFF", CFGF_NONE),
		CFG_STR("gridlinecolor", "0x0B2EEF", CFGF_NONE),
		CFG_STR("format", "%0.2f", CFGF_NONE),
		CFG_END()
	};
	/* Describes to the library the various components to expect with-in a
	 * config file. In our case we just expect for multiple sections with
	 * the name "signal". */
	cfg_opt_t opts[] = 
	{
		CFG_SEC("signal", signal_opts, CFGF_MULTI | CFGF_TITLE),
		CFG_END()
	};

	/* Initialise the library. */
	cfg = cfg_init(opts, CFGF_NOCASE);

	/* Parse the file. */
	switch(cfg_parse(cfg, fname))
	{
	 case CFG_FILE_ERROR:
		perror(fname);
		return 1;
	 case CFG_PARSE_ERROR:
		fprintf(stderr, "parse error\n");
		return 2;
	}

	/* Go through each "signal" section. */
	n = cfg_size(cfg, "signal");
	for(i = 0; i < n; i++) 
	{
		cfg_t *sig = cfg_getnsec(cfg, "signal", i);
		/* Its is important that this temporary structure variable be
		 * initialised. This is because we will be copying it to the
		 * actual sigcfg structure and we want to initialise certain
		 * fields of the structure even though those fields are not
		 * read from the config file. */
		static SIGNALCFG tcfg={NULL, NULL, 0, 0, 0, TRUE};

		/* Read all the variables in the section into a temporary
		 * structure. */
		strcpy(tcfg.fname,cfg_getstr(sig, "file"));
		tcfg.rawmax = (float) cfg_getfloat(sig, "rawmax");
		tcfg.expmax = (float) cfg_getfloat(sig, "expectedmax");
		sscanf(cfg_getstr(sig, "graphcolor"),"%x",&tcfg.color);
		tcfg.drawgrid = (int) cfg_getbool(sig, "grid");
		tcfg.gridstep = (float) cfg_getfloat(sig, "gridstep");
		sscanf(cfg_getstr(sig, "gridbgcolor"),"%x",&tcfg.gridbgcolor);
		sscanf(cfg_getstr(sig, "gridlinecolor"),"%x",&tcfg.gridlinecolor);
		strcpy(tcfg.format,cfg_getstr(sig, "format"));

		/* Copy the tcgg structure to the appropriate sigcfg structure
		 * depending on the title of the "signal" section. "signal" is
		 * not the title of the section, it is the section type. */
		if(!strcasecmp("input_current",cfg_title(sig)))
		 sigcfg[IC_CFG] = tcfg;
		if(!strcasecmp("input_voltage",cfg_title(sig)))
		 sigcfg[IV_CFG] = tcfg;
		if(!strcasecmp("output_current",cfg_title(sig)))
		 sigcfg[OC_CFG] = tcfg;
		if(!strcasecmp("output_voltage",cfg_title(sig)))
		 sigcfg[OV_CFG] = tcfg;
		if(!strcasecmp("pressure",cfg_title(sig)))
		 sigcfg[PRESSURE_CFG] = tcfg;
		if(!strcasecmp("speed",cfg_title(sig)))
		 sigcfg[SPEED_CFG] = tcfg;
	}

	/* Free the internal data structures initialised by the library. */
	cfg_free(cfg);

	return 0;
}
