#ifndef BASE_CFG_H
#define BASE_CFG_H

#include "misc/compat.h"
#include "base/strarray.h"

///@name config
//@{

typedef void (*ConfigEntrySetFunc)(void *, char *);
typedef void (*ConfigEntryGetFunc)(void *, StringArrayHandle **);
typedef void (*ConfigEntryResetFunc)(void *);
typedef void (*ConfigEntryValidateFunc)(void *, int *, void *, char **); //returns a non-zero int on a bad data format. descriptive message returned at the string pointer


typedef struct ConfigEntryName {
	char *name;
	char *clname;
} ConfigEntryName;

typedef struct ConfigEntryInt {
	int *data;
	int datadefault;
} ConfigEntryInt;
#define CEIB {NULL, 0}

typedef struct ConfigEntryString {
	char **data;
	char *datadefault;
} ConfigEntryString;
#define CESB {NULL, NULL}

typedef struct ConfigEntryFunc {
	ConfigEntrySetFunc setfunc;
	ConfigEntryGetFunc getfunc;
	ConfigEntryResetFunc resetfunc;
} ConfigEntryFunc;
#define CEFB {NULL, NULL, NULL}

typedef struct ConfigEntryHelp {
	char *shrt;
	char *lng;
} ConfigEntryHelp;
#define CEHB {NULL, NULL}

typedef struct ConfigEntry {
	int type;
	ConfigEntryName name;
	ConfigEntryInt i;
	ConfigEntryString s;
	ConfigEntryFunc getset;
	ConfigEntryValidateFunc validatefunc;
	void *funcextra;
	ConfigEntryHelp help;
} ConfigEntry;

typedef struct ConfigEntryArrayHandle {
	int size;
	ConfigEntry *data;
} ConfigEntryArrayHandle;

//todo: move this out of cfg.*
#define DEFAULT_CONFIGNAME "@isproxy.ini"

#define BLANKCONFIGENTRY {CETYPE_NONE,  {NULL, NULL}, CEIB, CESB, CEFB, NULL, NULL, CEHB}

#define CETYPE_NONE 0
#define CETYPE_INT 1
#define CETYPE_BOOL 2
#define CETYPE_STRING 3
#define CETYPE_FUNC 4

#define CETYPE_FLAG 5

#define CEVALIDATE_OK 1 //validate found the value to be ok
#define CEVALIDATE_BAD 2 //validate found the value to be bad
#define CEVALIDATE_FIXED 3 //validate adjusted the value to a correct one

void setConfigFile(char *filename);
void configSetCL(int argc, char **argv);
void configReadCL(void);
void configReadAll(void);

#if defined(__WIN32__) || defined(WIN32) || defined(_WIN32)
	#include <windows.h>
	void configSetWinCL(LPSTR lpcmdline);
#endif


void configInit(void);
void configAddList(ConfigEntry *cea);
void configResetList(void);
int configMatchEntry(char *s);
int configMatchEntryCL(char *s);
int configValidate(ConfigEntryValidateFunc func, void *extra, void *value, char **s);
int configReadEntryData(int index, char *key, char *value, char *ss);
void configShowHelp(void);
void configReadFile(char *config);
void configRead(void);
void configWriteFile(char *config);
void configWrite(void);
void configReset(void);

extern char *configfilename;

//@}

#endif //BASE_CFG_H
