// ========================================================= //
//                                                           //
//   File      : ConfigMapping.h                             //
//   Purpose   : config <-> string mapping                   //
//                                                           //
//   Coded by Ralf Westram (coder@reallysoft.de) in Mar 19   //
//   http://www.arb-home.de/                                 //
//                                                           //
// ========================================================= //

#ifndef CONFIGMAPPING_H
#define CONFIGMAPPING_H

#ifndef ARB_CORE_H
#include <arb_core.h>
#endif
#ifndef ARB_STRARRAY_H
#include <arb_strarray.h>
#endif

#ifndef _GLIBCXX_MAP
#include <map>
#endif
#ifndef _GLIBCXX_STRING
#include <string>
#endif

typedef std::map<std::string, std::string> config_map;

struct ConfigMapping : public config_map {

    GB_ERROR parseFrom(const std::string& configString);

    // props + modifiers
    bool has_entry(const char *entry) const {
        // returns true if mapping contains 'entry'
        return find(entry) != end();
    }
    const char *get_entry(const char *entry) const {
        // returns value of 'entry'
        config_map::const_iterator found = find(entry);
        return (found == end()) ? NULp : found->second.c_str();
    }
    void set_entry(const std::string& entry, const std::string& value) {
        // sets a (new) entry to value.
        // existing entries get overwritten.
        (*this)[entry] = value;
    }
    void delete_entry(const char *entry) {
        // deletes an existing 'entry'
        erase(entry);
    }

    // result
    std::string config_string() const {
        using std::string;
        string result;
        for (config_map::const_iterator e = begin(); e != end(); ++e) {
            const string& config_name(e->first);
            string             value(e->second);

            encode_escapes(value, "\'");
            string entry = config_name+"='"+value+'\'';
            if (result.empty()) {
                result = entry;
            }
            else {
                result = result+';'+entry;
            }
        }
        return result;
    }
    void get_entries(class ConstStrArray& to_array) {
        for (config_map::const_iterator e = begin(); e != end(); ++e) {
            const std::string& key(e->first);
            to_array.put(key.c_str());
        }
    }

    static GB_ERROR decode_escapes(std::string& s);
    static void     encode_escapes(std::string& s, const char *to_escape);
};


#else
#error ConfigMapping.h included twice
#endif // CONFIGMAPPING_H
