#include "libpdftex.h"

#define CFG_BUF_SIZE     1024

static FILE *cfg_file;
static char config_name[] = "pdftex.cfg";
char *mapfiles;
boolean true_dimen;

#define CFG_OPEN()       texpsheaderbopenin(cfg_file)
#define CFG_CLOSE()      xfclose(cfg_file, filename)
#define CFG_GETCHAR()    xgetc(cfg_file)
#define CFG_EOF()        feof(cfg_file)

typedef struct {
    char *name;
    integer value;
    boolean is_true_dimen;
} cfg_entry;

#define CFG_FONT_MAP        0
#define CFG_OUTPUT_FORMAT   1
#define CFG_COMPRESS_LEVEL  2
#define CFG_DECIMAL_DIGITS  3
#define CFG_PAGE_WIDTH      4
#define CFG_PAGE_HEIGHT     5
#define CFG_HORIGIN         6
#define CFG_VORIGIN         7
#define CFG_MAX             (CFG_VORIGIN + 1)

cfg_entry cfg_tab[CFG_MAX] = {
    {"map",              0, false},
    {"output_format",    0, false},
    {"compress_level",   0, false},
    {"decimal_digits",   0, false},
    {"page_width",       0, false},
    {"page_height",      0, false},
    {"horigin",          0, false},
    {"vorigin",          0, false}
};

void readconfig()
{
    int c;
    cfg_entry *ce;
    char cfg_line[CFG_BUF_SIZE], *p, *r;
    filename = config_name;
    packfilename(maketexstring(filename), getnullstr(), getnullstr());
    if (!CFG_OPEN())
        FAIL("cannot open config file");
    TEX_PRINTF("(%s" AND filename);
    mapfiles = 0;
    for (;;) {
        if (CFG_EOF()) {
            CFG_CLOSE();
            TEX_PRINTF(")");
            break;
        }
        p = cfg_line;
        do {
            c = CFG_GETCHAR();
            APPEND_CHAR_TO_BUF(c, p, cfg_line, CFG_BUF_SIZE);
        } while (c != 10);
        APPEND_EOL(p, cfg_line, CFG_BUF_SIZE);
        c = *cfg_line;
        if (p - cfg_line == 1 || c == '*' || c == '#' || c == ';' || c == '%')
            continue;
        p = cfg_line;
        for (ce = cfg_tab; ce - cfg_tab  < CFG_MAX; ce++)
            if (!strncmp(cfg_line, ce->name, strlen(ce->name)))
                break;
        if (ce - cfg_tab == CFG_MAX) {
            WARN("invalid parameter name in config file:\n>>> %s" AND cfg_line);
            continue;
        }
        p = cfg_line + strlen(ce->name);
        if (*p == ' ')
            p++;
        if (*p == '=')
            p++;
        if (*p == ' ')
            p++;
        switch (ce - cfg_tab) {
        case CFG_FONT_MAP:
            if (*p != '+') {
                if (mapfiles != 0) {
                    free(mapfiles);
                    mapfiles = 0;
                }
            }
            else
                p++;
            for (r = p; *r != ' ' && *r != 10; r++);
            if (mapfiles == 0) {
                mapfiles = XTALLOC(r - p + 2, char);
                *mapfiles = 0;
            }
            else
                mapfiles = 
                    XRETALLOC(mapfiles, strlen(mapfiles) + r - p + 2, char);
            strncat(mapfiles, p, r - p);
            strcat(mapfiles, "\n");
            p = r;
            break;
        case CFG_OUTPUT_FORMAT:
        case CFG_COMPRESS_LEVEL:
        case CFG_DECIMAL_DIGITS:
            ce->value = myatol(&p);
            if (ce->value == -1) {
                WARN("invalid parameter value in config file:\n>>> %s" AND cfg_line);
                ce->value = 0;
            }
            break;
        case CFG_PAGE_WIDTH:
        case CFG_PAGE_HEIGHT:
        case CFG_HORIGIN:
        case CFG_VORIGIN:
            ce->value = myatodim(&p);
            ce->is_true_dimen = true_dimen;
            break;
        }
        if (*p != 10)
            WARN("invalid line in config file:\n>>> %s" AND cfg_line);
    }
    if (mapfiles == 0)
        mapfiles = xstrdup("psfonts.map\n");
    fm_read_info();
}

void adjustcfgdimens(scaled m)
{
    cfg_entry *ce;
    for (ce = cfg_tab; ce - cfg_tab  < CFG_MAX; ce++)
        if (ce->is_true_dimen) {
            dividescaled(ce->value, m, 5);
            ce->value = scaledout;
        }
}

integer cfgoutput()
{
    return cfg_tab[CFG_OUTPUT_FORMAT].value;
}

integer cfgcompresslevel()
{
    return cfg_tab[CFG_COMPRESS_LEVEL].value;
}

integer cfgdecimaldigits()
{
    return cfg_tab[CFG_DECIMAL_DIGITS].value;
}

integer cfgpagewidth()
{
    return cfg_tab[CFG_PAGE_WIDTH].value;
}

integer cfgpageheight()
{
    return cfg_tab[CFG_PAGE_HEIGHT].value;
}

integer cfghorigin()
{
    return cfg_tab[CFG_HORIGIN].value;
}

integer cfgvorigin()
{
    return cfg_tab[CFG_VORIGIN].value;
}
