/*
 * Options header for rootapps
 */

#ifndef ROOTAPP_OPTIONS_H
#define ROOTAPP_OPTIONS_H

#include <time.h>

#define MAX(a,b) (a > b ? a : b)
#define MIN(a,b) (a < b ? a : b)


/* Config Variables Types */
typedef enum {
        C_NONE,
        C_CHAR,
        C_INT,
        C_BOOL,
        C_FLOAT,
        C_LONG,
        C_DOUBLE,
        C_STRING,
        C_STRLST
} CfgType;
#define O_HELP -1
#define O_VERS -2


/* Structure for the command line options and config file entries */
typedef struct
{
        char     key;    /* letter for option (eg : h for -h) */
        char    *arg;    /* "#" for num, "<string>"...        */
        char    *entry;  /* entry for configuration file      */
        CfgType  type;   /* type of variable below            */
        void    *var;    /* pointer storing variable          */
        int      set;    /* True = set, False = unset         */
        char    *help;   /* help to be displayed              */
}
Option;


/* Command line only options */
#define OHLP(h)          {'h', NULL, NULL, O_HELP,   NULL, False, h}
#define OVRS(h)          {'v', NULL, NULL, O_VERS,   NULL, False, h}
#define OCHR(k, o, v, h) {k,   o,    NULL, C_CHAR,   v,    False, h}
#define OINT(k, o, v, h) {k,   o,    NULL, C_INT,    v,    False, h}
#define OBOL(k, o, v, h) {k,   o,    NULL, C_BOOL,   v,    False, h}
#define OFLT(k, o, v, h) {k,   o,    NULL, C_FLOAT,  v,    False, h}
#define OLNG(k, o, v, h) {k,   o,    NULL, C_LONG,   v,    False, h}
#define ODBL(k, o, v, h) {k,   o,    NULL, C_DOUBLE, v,    False, h}
#define OSTR(k, o, v, h) {k,   o,    NULL, C_STRING, v,    False, h}
#define OSTL(k, o, v, h) {k,   o,    NULL, C_STRLST, v,    False, h}
#define OSTP             {0,   NULL, NULL, C_NONE,   NULL, False, NULL}

/* Options that are also in a configuration file */
#define FCHR(k, o, f, v, h) {k,   o,    f, C_CHAR,   v,    False, h}
#define FINT(k, o, f, v, h) {k,   o,    f, C_INT,    v,    False, h}
#define FBOL(k, o, f, v, h) {k,   o,    f, C_BOOL,   v,    False, h}
#define FFLT(k, o, f, v, h) {k,   o,    f, C_FLOAT,  v,    False, h}
#define FLNG(k, o, f, v, h) {k,   o,    f, C_LONG,   v,    False, h}
#define FDBL(k, o, f, v, h) {k,   o,    f, C_DOUBLE, v,    False, h}
#define FSTR(k, o, f, v, h) {k,   o,    f, C_STRING, v,    False, h}
#define FSTL(k, o, f, v, h) {k,   o,    f, C_STRLST, v,    False, h}


/* Strings list with timestamp */
typedef struct StrLst
{
        char *entry;
        time_t time;
        struct StrLst *next;
}
StrLst;


/* Redefinitions for better memory handling */
#define FREE(data) {if (data) free (data); data = NULL;}
void *xmalloc(size_t taille);
char *xstrdup(const char *chaine);

/* Command execution and environnement knowledge */
int my_system(const char *command, const char *options);
char *robust_home();

/* Strings lists management */
void strlst_add(StrLst **list, const char *value);
void free_strlst(StrLst **list);
int strlst_nb(StrLst *list);

/* Command-line options parsing */
void Usage(Option *opttab, int help);
void parse_argv(Option *opttab, int argc, char *argv[]);
void load_config(Option *opttab, const char *filename, int force);

/* Free all Options */
void free_vars(Option *opttab);

/* Init variables */
void init_app(char *package, char *program, char *version, char *build, char *authors);

#endif
