/*
                Config.c
*/

/// Includes
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "mytypes.h"
#include "config.h"
#include "protos.h"
///
/// External variables
///
/// Prototypes
Prototype void load_config (int flags);
Prototype void save_config (int flags);
Prototype void load_config_custom (char *name);
Prototype void save_config_custom (char *name);
Prototype void parse_config_line(const char *linebuf);
///
/// Global variables
struct Config Config;
struct Config DefConfig = {
    ID_TAG, CONFIG_VER, // IDTag, Version
    "C:Ed @F", TRUE, FALSE, // EditCmd, GUI, NoInfo
    MODE_OFF, "Moods.txt",
    MODE_OFF, "Headers.txt",
    MODE_OFF, "NowPlaying.txt",
    MODE_OFF, "Signatures.txt",
    MODE_ON, "Taglines.txt",
    FALSE, "T:Tag-o-Miga.log", // NoReq, LogFile
    FALSE, FALSE, // Network2, NoTagName
    "@N@", "@FN@", "@LN@", // Name, FirstName, LastName
                "@D@", "@T@", "@S@", // Date, Time, Subject
    0x8002, TRUE, // DefTagfileType, MakeIndex
    0, TRUE // UseCount, Buffer
};
struct {
  char *param;
  enum { string, boolean, word } type;
  int offset;
} cfgtable[] = {
  "MOOD",       boolean, 268,
  "HEADER",     boolean, 526,
  "NP",         boolean, 784,
  "SIG",        boolean, 1042,
  "TAGLINE",    boolean, 1300,
  "MOODFILE",   string,  270,
  "HEADERFILE", string,  528,
  "NPFILE",     string,  786,
        "SIGFILE",    string,  1044,
  "TAGFILE",    string,  1302,
        "MACRO_N",    string,  1820,
        "MACRO_FN",   string,  1836,
  "MACRO_LN",   string,  1852,
  "MACRO_D",    string,  1868,
  "MACRO_T",    string,  1884,
  "MACRO_S",    string,  1900,
  "EDITOR",     string,  8,
  "GUI",        boolean, 264,
  "NOINFO",     boolean, 266,
  "NOREQ",      boolean, 1558,
  "LOGFILE",    string,  1560,
  "NETWORK2",   boolean, 1816,
  "NOTAGNAME",  boolean, 1818,
  "DEFTAGFILETYPE", word, 1916,
  "MAKEINDEX",  boolean, 1918,
  "USECOUNT",   word,    1920,
  "BUFFER",     boolean, 1922
};
///

// Config file
/// load_config
/* -------------------------------- load_config --------------------------------

 Comment: load a configuration file

*/

void
load_config(int flag)
{
    char *name;

    if (flag&CFG_SAVE) {
                                name = "ENVARC:Tag-o-Miga/Config";
    } else {
                                name = ConfigFilename();
                }

    memcpy (&Config, &DefConfig, sizeof (Config));
    load_config_custom (name);
}
///
/// load_config_custom
/* ---------------------------- load_config_custom -----------------------------

 Comment: load configuration from a different file

*/

void
load_config_custom(char *name)
{
                FILE *f;
                char linebuf[256];

                f = fopen (name, "r");
                if (f) {
                                while (fgets (linebuf, 256, f)) {
                                        parse_config_line(linebuf);
                                }
                                fclose (f);
                } else {
                                AlertUser ("Error while reading config file %s\n%s\n"
                                                                                                 "Using default options", "OK", name, ErrorMessage());
                }
}
///
/// parse_config_line
void parse_config_line(const char *linebuf0)
{
                char linebuf[256], *cmd, *param, *p;
                char fparam[256];
                int i;
                BOOL *b;
                void *ptr = &Config;

                strncpy(linebuf, linebuf0, 255);
                linebuf[255] = 0;

                if (linebuf[0] == '#' || strlen (linebuf) == 0)
                        return;

                cmd = linebuf;
                while (*cmd > 32) cmd++;
                if (*cmd != ' ') return;
                param = cmd + 1;
                *cmd = 0; cmd = linebuf;
                p = param;
                while (*p >= 32) p++;
                *p = 0;

        for (i = 0; i < 27; i++) {
                        if (strcmp (cfgtable[i].param, cmd) == 0) {

                        if (*param == '"') {
                                char *ps = param+1, *pd = fparam;
                                BOOL esc = FALSE;
                                while (*ps != '\"' || esc == TRUE) {
                                        if (*ps < 32) {
                                                AlertUser ("Bad configuration file\nMissing quote on %s", "_OK", cfgtable[i].param);
                                                break;
                                        }
                                        if (esc == FALSE) {
                                                if (*ps == '*') esc = TRUE;
                                                else {
                                                        *pd = *ps;
                                                        pd++;
                                                }
                                        } else {
                                                esc = FALSE;
                                                *pd = *ps;
                                                pd++;
                                        }
                                        ps++;
                                }
                                *pd = 0;
                                strcpy(param, fparam);
                        }

                if (cfgtable[i].type == string) {
                                                                        if (param)
                                                                                strcpy ((char *)((int)ptr+cfgtable[i].offset), param);
                                                                } else if (cfgtable[i].type == word) {
                                                                        if (param)
                                                                                *(UWORD *)((int)ptr+cfgtable[i].offset) = (UWORD)strtol (param, NULL, 0);
                                                                } else {
                                                                        b = (BOOL *)((int)ptr+cfgtable[i].offset);
                                                                        if (param)
                                                                                if (strcmp (param, "ON") == 0)
                                                                                        *b = TRUE;
                                                                                else
                                                                                        *b = FALSE;
                                                                }
                                                        }
                                                }
}
///
/// save_config
/* -------------------------------- save_config --------------------------------

 Comment: save the configuration

*/

void
save_config(int flag)
{
    char *name;

    if (flag&CFG_SAVE) {
        name = "ENVARC:Tag-o-Miga/Config";
        save_config (flag&(!CFG_SAVE));
    } else {
        //name = "ENV:Tag-o-Miga/Config";
        name = ConfigFilename();
    }

    save_config_custom (name);
}
///
/// save_config_custom
/* ---------------------------- save_config_custom -----------------------------

 Comment: save configuration to a different file

*/

void
save_config_custom(char *name)
{
    FILE *f;

    f = fopen (name, "w");
    if (f) {
        fprintf (f, "# Tag-o-Miga configuration file\n");
                                fprintf (f, "# Extendable format introducted in version 1.1.265\n");
        fprintf (f, "# Generated by " IDSTRING "\n");

        fprintf (f, "\n# Enable/disable parts\n");
        fprintf (f, "MOOD \"%s\"\n", Config.Part[0].Mode?"ON":"OFF");
        fprintf (f, "HEADER \"%s\"\n", Config.Part[1].Mode?"ON":"OFF");
        fprintf (f, "NP \"%s\"\n", Config.Part[2].Mode?"ON":"OFF");
        fprintf (f, "SIG \"%s\"\n", Config.Part[3].Mode?"ON":"OFF");
        fprintf (f, "TAGLINE \"%s\"\n", Config.Part[4].Mode?"ON":"OFF");

        fprintf (f, "\n# Filenames\n");
        fprintf (f, "MOODFILE \"%s\"\n", Config.Part[0].File);
        fprintf (f, "HEADERFILE \"%s\"\n", Config.Part[1].File);
        fprintf (f, "NPFILE \"%s\"\n", Config.Part[2].File);
        fprintf (f, "SIGFILE \"%s\"\n", Config.Part[3].File);
        fprintf (f, "TAGFILE \"%s\"\n", Config.Part[4].File);

        fprintf (f, "\n# Macros\n");
        fprintf (f, "MACRO_N \"%s\"\n", Config.Macro[0]);
        fprintf (f, "MACRO_FN \"%s\"\n", Config.Macro[1]);
        fprintf (f, "MACRO_LN \"%s\"\n", Config.Macro[2]);
        fprintf (f, "MACRO_D \"%s\"\n", Config.Macro[3]);
        fprintf (f, "MACRO_T \"%s\"\n", Config.Macro[4]);
        fprintf (f, "MACRO_S \"%s\"\n", Config.Macro[5]);

        fprintf (f, "\n# Miscellaneous settings\n");
        fprintf (f, "EDITOR \"%s\"\n", Config.EditCmd);
        fprintf (f, "GUI \"%s\"\n", Config.GUI?"ON":"OFF");
        fprintf (f, "NOINFO \"%s\"\n", Config.NoInfo?"ON":"OFF");
        fprintf (f, "NOREQ \"%s\"\n", Config.NoReq?"ON":"OFF");
        fprintf (f, "LOGFILE \"%s\"\n", Config.LogFile);
        fprintf (f, "NOTAGNAME \"%s\"\n", Config.NoTagName?"ON":"OFF");
        fprintf (f, "# Next option is NOT TO BE FIDDLED WITH!\n");
        fprintf (f, "NETWORK2 \"%s\"\n", Config.Network2?"ON":"OFF");

        fprintf (f, "\n# Options introduced in version 1.2\n");
        fprintf (f, "DEFTAGFILETYPE 0x%04lX\n", Config.DefTagfileType);
        fprintf (f, "MAKEINDEX \"%s\"\n", Config.MakeIndex?"ON":"OFF");
        fprintf (f, "USECOUNT %d\n", Config.UseCount);
        fprintf (f, "BUFFER %s\n", Config.Buffer?"ON":"OFF");

        fclose (f);
    } else {
        AlertUser ("Error while saving config file %s\n%s\n"
                         "Configuration NOT saved", "OK", name, ErrorMessage());
    }
}
///

