/* date = June 17th 2023 10:48 pm */

#ifndef VN_CONFIG_H
#define VN_CONFIG_H

////////////////////////////////
//~ sixten: Config Types
enum config_entry_type
{
    Config_Entry_S32,
    Config_Entry_S64,
    Config_Entry_B32,
};

struct config_entry
{
    string Name;
    void *Target;
    config_entry_type Type;
    
    config_entry *Next;
    config_entry *Prev;
    
    config_entry *NextInternal;
};

struct config_entry_bucket
{
    config_entry *First;
    config_entry *Last;
};

struct config
{
    memory_arena *Arena;
    config_entry_bucket EntryBuckets[32];
    
    // sixten(NOTE): Keeps track of the order in which the entries were declared. (Used during saving)
    config_entry *FirstInternal;
    config_entry *LastInternal;
};

////////////////////////////////
//~ sixten: Config Parse Types
enum config_parse_mode
{
    ConfigParseMode_Main,
    ConfigParseMode_ScanForCurlyOpenOrEquals,
    ConfigParseMode_ScanForValue,
    ConfigParseMode_ScanForSemicolon,
};

struct config_parse_node
{
    config_parse_node *Next;
    config_parse_node *Prev;
    string Name;
};

struct config_parse_list
{
    config_parse_node *First;
    config_parse_node *Last;
    s64 TotalCountPlusOne;
};

////////////////////////////////
//~ sixten: Config Type Functions

static config *CreateConfig(void);

static config_entry *Config_FindEntryByName(config *Config, string Name);

static void Config_BindEntry(config *Config, string Name, config_entry_type Type, void *Target);
inline void Config_BindS32(config *Config, string Name, s32 *Target, s32 Default);
inline void Config_BindS64(config *Config, string Name, s64 *Target, s64 Default);
inline void Config_BindB32(config *Config, string Name, b32 *Target, b32 Default);

static void Config_ReadFile(config *Config, string Path);
static void Config_WriteFile(config *Config);

////////////////////////////////
//~ sixten: Config Parse Type Functions
static void Config_ParseListPush(memory_arena *Arena, config_parse_list *List, string Name);
static void Config_ParseListPop(config_parse_list *List);
static string Config_ParseListJoin(memory_arena *Arena, config_parse_list *List);

#endif //VN_CONFIG_H
