/*---------------------------------------------------------------------------*/
/* client_config.h                                                           */
/* copyright (c) innovaphone 2018                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

typedef struct {
    int id;
    const char *name;
} ClientConfigIdNameItem;

const char * ClientConfigIdName(const ClientConfigIdNameItem * map, int id);
int ClientConfigNameId(const ClientConfigIdNameItem * map, const char * name);


class IClientConfigItem : public btree
{
friend class IClientConfigItems;
friend class IClientConfigBasicItem;
friend class IClientConfigAdminItem;
    int btree_compare(void * key);
    int btree_compare(class btree * b);
    virtual void Init() = 0;
    virtual void Apply() = 0;
    virtual void ToJson(class json_io & json, word base, char * & tmp) = 0;
    virtual void FromJson(class json_io & json, word base) = 0;
public:
    class IClientConfigItems * items;
    char * name;

    IClientConfigItem(class IClientConfigItems * items, const char * name);
    virtual ~IClientConfigItem();
};

class IClientConfigBasicItem : public IClientConfigItem
{
friend class IClientConfigItems;
public:
    IClientConfigBasicItem(class IClientConfigItems * items, const char * name);
    virtual ~IClientConfigBasicItem();
};


class UClientConfigBool
{
public:
    virtual void Init(class IClientConfigBool * item) {};
    virtual void Apply(class IClientConfigBool * item) = 0;
};

class IClientConfigBool : public IClientConfigBasicItem
{
    UClientConfigBool * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word base, char * & tmp) override;
    void FromJson(class json_io & json, word base) override;

public:
    bool value;

    IClientConfigBool(class IClientConfigItems * items, UClientConfigBool * user, const char * name, bool init = false);
    ~IClientConfigBool();

    void Set(bool newValue);
};

template <class IClientConfigBoolSubclass> class UClientConfigBoolSubclass : public UClientConfigBool {
    void Init(IClientConfigBool * item) { Init(static_cast<IClientConfigBoolSubclass *>(item)); };
    void Apply(IClientConfigBool * item) { Apply(static_cast<IClientConfigBoolSubclass *>(item)); };
public:
    virtual void Init(IClientConfigBoolSubclass * item) {};
    virtual void Apply(IClientConfigBoolSubclass * item) = 0;
};


class UClientConfigEnum
{
public:
    virtual void Init(class IClientConfigEnum * item) {};
    virtual void Apply(class IClientConfigEnum * item) = 0;
};

class IClientConfigEnum : public IClientConfigBasicItem
{
    UClientConfigEnum * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word base, char * & tmp) override;
    void FromJson(class json_io & json, word base) override;

public:
    const ClientConfigIdNameItem * map;
    int value;

    IClientConfigEnum(class IClientConfigItems * items, UClientConfigEnum * user, const char * name, const ClientConfigIdNameItem * map, int init);
    IClientConfigEnum(class IClientConfigItems * items, UClientConfigEnum * user, const char * name, const ClientConfigIdNameItem * map);
    ~IClientConfigEnum();

    void Set(int newValue);
};

template <class IClientConfigEnumSubclass> class UClientConfigEnumSubclass : public UClientConfigEnum {
    void Init(IClientConfigEnum * item) { Init(static_cast<IClientConfigEnumSubclass *>(item)); };
    void Apply(IClientConfigEnum * item) { Apply(static_cast<IClientConfigEnumSubclass *>(item)); };
public:
    virtual void Init(IClientConfigEnumSubclass * item) {};
    virtual void Apply(IClientConfigEnumSubclass * item) = 0;
};


class UClientConfigInt
{
public:
    virtual void Init(class IClientConfigInt * item) {};
    virtual void Apply(class IClientConfigInt * item) = 0;
};

class IClientConfigInt : public IClientConfigBasicItem
{
    UClientConfigInt * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word base, char * & tmp) override;
    void FromJson(class json_io & json, word base) override;

public:
    int value;

    IClientConfigInt(class IClientConfigItems * items, UClientConfigInt * user, const char * name, int init = 0);
    ~IClientConfigInt();

    void Set(int newValue);
};

template <class IClientConfigIntSubclass> class UClientConfigIntSubclass : public UClientConfigInt {
    void Init(IClientConfigInt * item) { Init(static_cast<IClientConfigIntSubclass *>(item)); };
    void Apply(IClientConfigInt * item) { Apply(static_cast<IClientConfigIntSubclass *>(item)); };
public:
    virtual void Init(IClientConfigIntSubclass * item) {};
    virtual void Apply(IClientConfigIntSubclass * item) = 0;
};


class UClientConfigUnsigned
{
public:
    virtual void Init(class IClientConfigUnsigned * item) {};
    virtual void Apply(class IClientConfigUnsigned * item) = 0;
};

class IClientConfigUnsigned : public IClientConfigBasicItem
{
    UClientConfigUnsigned * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word base, char * & tmp) override;
    void FromJson(class json_io & json, word base) override;

public:
    unsigned value;

    IClientConfigUnsigned(class IClientConfigItems * items, UClientConfigUnsigned * user, const char * name, unsigned init = 0 );
    ~IClientConfigUnsigned();

    void Set(unsigned newValue);
};

template <class IClientConfigUnsignedSubclass> class UClientConfigUnsignedSubclass : public UClientConfigUnsigned {
    void Init(IClientConfigUnsigned * item) { Init(static_cast<IClientConfigUnsignedSubclass *>(item)); };
    void Apply(IClientConfigUnsigned * item) { Apply(static_cast<IClientConfigUnsignedSubclass *>(item)); };
public:
    virtual void Init(IClientConfigUnsignedSubclass * item) {};
    virtual void Apply(IClientConfigUnsignedSubclass * item) = 0;
};


class UClientConfigString
{
public:
    virtual void Init(class IClientConfigString * item) {};
    virtual void Apply(class IClientConfigString * item) = 0;
};

class IClientConfigString : public IClientConfigBasicItem
{
    UClientConfigString * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word base, char * & tmp) override;
    void FromJson(class json_io & json, word base) override;

public:
    char * value;

    IClientConfigString(class IClientConfigItems * items, UClientConfigString * user, const char * name, const char * init = NULL);
    virtual ~IClientConfigString();

    void Set(const char * newValue);
};

template <class IClientConfigStringSubclass> class UClientConfigStringSubclass : public UClientConfigString {
    void Init(IClientConfigString * item) { Init(static_cast<IClientConfigStringSubclass *>(item)); };
    void Apply(IClientConfigString * item) { Apply(static_cast<IClientConfigStringSubclass *>(item)); };
public:
    virtual void Init(IClientConfigStringSubclass * item) {};
    virtual void Apply(IClientConfigStringSubclass * item) = 0;
};


class UClientConfigKeyValueStore
{
public:
    virtual void Init(class IClientConfigKeyValueStore * item) {};
    virtual void Apply(class IClientConfigKeyValueStore * item) = 0;
};

class IClientConfigKeyValueStore : public IClientConfigBasicItem
{
    UClientConfigKeyValueStore * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word base, char * & tmp) override;
    void FromJson(class json_io & json, word base) override;

public:
    class btree * store;

    IClientConfigKeyValueStore(class IClientConfigItems * items, UClientConfigKeyValueStore * user, const char * name);
    virtual ~IClientConfigKeyValueStore();

    void SetItem(const char * id, const char * val);
    char * GetItem(const char * id);
};

template <class IClientConfigKeyValueStoreSubclass> class UClientConfigKeyValueStoreSubclass : public UClientConfigKeyValueStore {
    void Init(IClientConfigKeyValueStore * item) { Init(static_cast<IClientConfigKeyValueStoreSubclass *>(item)); };
    void Apply(IClientConfigKeyValueStore * item) { Apply(static_cast<IClientConfigKeyValueStoreSubclass *>(item)); };
public:
    virtual void Init(IClientConfigKeyValueStoreSubclass * item) {};
    virtual void Apply(IClientConfigKeyValueStoreSubclass * item) = 0;
};


class IClientConfigAdminItem : public IClientConfigItem
{
friend class IClientConfigItems;
    void AdminToJson(class json_io & json, word base, char * & tmp);
    void SetAdminSettings(class json_io & json, word baseObject, bool pbx);
public:
    bool set;
    bool force;

    IClientConfigAdminItem(class IClientConfigItems * items, const char * name);
    virtual ~IClientConfigAdminItem();
};


class UClientConfigAdminBool
{
public:
    virtual void Init(class IClientConfigAdminBool * item) {};
    virtual void Apply(class IClientConfigAdminBool * item) = 0;
};

class IClientConfigAdminBool : public IClientConfigAdminItem
{
    UClientConfigAdminBool * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word baseObject, char * & tmp) override;
    void FromJson(class json_io & json, word baseObject) override;

public:
    bool value;

    IClientConfigAdminBool(class IClientConfigItems * items, UClientConfigAdminBool * user, const char * name, bool init = false);

    void Set(bool newValue);
};

template <class IClientConfigAdminBoolSubclass> class UClientConfigAdminBoolSubclass : public UClientConfigAdminBool {
    void Init(IClientConfigAdminBool* item) { debug->printf("---INIT--"); Init(static_cast<IClientConfigAdminBoolSubclass*>(item)); };
    void Apply(IClientConfigAdminBool * item) { debug->printf("---APPLY--");  Apply(static_cast<IClientConfigAdminBoolSubclass *>(item)); };
public:
    virtual void Init(IClientConfigAdminBoolSubclass * item) {};
    virtual void Apply(IClientConfigAdminBoolSubclass * item) = 0;
};


class UClientConfigAdminEnum
{
public:
    virtual void Init(class IClientConfigAdminEnum * item) {};
    virtual void Apply(class IClientConfigAdminEnum * item) = 0;
};

class IClientConfigAdminEnum : public IClientConfigAdminItem
{
    UClientConfigAdminEnum * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word baseObject, char * & tmp) override;
    void FromJson(class json_io & json, word baseObject) override;

public:
    const ClientConfigIdNameItem * map;
    int value;

    IClientConfigAdminEnum(class IClientConfigItems * items, UClientConfigAdminEnum * user, const char * name, const ClientConfigIdNameItem * map, int init);
    IClientConfigAdminEnum(class IClientConfigItems * items, UClientConfigAdminEnum * user, const char * name, const ClientConfigIdNameItem * map);

    void Set(int newValue);
};

template <class IClientConfigAdminEnumSubclass> class UClientConfigAdminEnumSubclass : public UClientConfigAdminEnum {
    void Init(IClientConfigAdminEnum * item) { Init(static_cast<IClientConfigAdminEnumSubclass *>(item)); };
    void Apply(IClientConfigAdminEnum * item) { Apply(static_cast<IClientConfigAdminEnumSubclass *>(item)); };
public:
    virtual void Init(IClientConfigAdminEnumSubclass * item) {};
    virtual void Apply(IClientConfigAdminEnumSubclass * item) = 0;
};


class UClientConfigAdminInt
{
public:
    virtual void Init(class IClientConfigAdminInt * item) {};
    virtual void Apply(class IClientConfigAdminInt * item) = 0;
};

class IClientConfigAdminInt : public IClientConfigAdminItem
{
    UClientConfigAdminInt * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word baseObject, char * & tmp) override;
    void FromJson(class json_io & json, word baseObject) override;

public:
    int value;

    IClientConfigAdminInt(class IClientConfigItems * items, UClientConfigAdminInt * user, const char * name, int init = 0);

    void Set(int newValue);
};

template <class IClientConfigAdminIntSubclass> class UClientConfigAdminIntSubclass : public UClientConfigAdminInt {
    void Init(IClientConfigAdminInt * item) { Init(static_cast<IClientConfigAdminIntSubclass *>(item)); };
    void Apply(IClientConfigAdminInt * item) { Apply(static_cast<IClientConfigAdminIntSubclass *>(item)); };
public:
    virtual void Init(IClientConfigAdminIntSubclass * item) {};
    virtual void Apply(IClientConfigAdminIntSubclass * item) = 0;
};


class UClientConfigAdminUnsigned
{
public:
    virtual void Init(class IClientConfigAdminUnsigned * item) {};
    virtual void Apply(class IClientConfigAdminUnsigned * item) = 0;
};

class IClientConfigAdminUnsigned : public IClientConfigAdminItem
{
    UClientConfigAdminUnsigned * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word baseObject, char * & tmp) override;
    void FromJson(class json_io & json, word baseObject) override;

public:
    unsigned value;

    IClientConfigAdminUnsigned(class IClientConfigItems * items, UClientConfigAdminUnsigned * user, const char * name, unsigned init = 0);

    void Set(unsigned newValue);
};

template <class IClientConfigAdminUnsignedSubclass> class UClientConfigAdminUnsignedSubclass : public UClientConfigAdminUnsigned {
    void Init(IClientConfigAdminUnsigned * item) { Init(static_cast<IClientConfigAdminUnsignedSubclass *>(item)); };
    void Apply(IClientConfigAdminUnsigned * item) { Apply(static_cast<IClientConfigAdminUnsignedSubclass *>(item)); };
public:
    virtual void Init(IClientConfigAdminUnsignedSubclass * item) {};
    virtual void Apply(IClientConfigAdminUnsignedSubclass * item) = 0;
};


class UClientConfigAdminUlong64
{
public:
    virtual void Init(class IClientConfigAdminUlong64 * item) {};
    virtual void Apply(class IClientConfigAdminUlong64 * item) = 0;
};

class IClientConfigAdminUlong64 : public IClientConfigAdminItem
{
    UClientConfigAdminUlong64 * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word baseObject, char * & tmp) override;
    void FromJson(class json_io & json, word baseObject) override;

public:
    ulong64 value;

    IClientConfigAdminUlong64(class IClientConfigItems * items, UClientConfigAdminUlong64 * user, const char * name, ulong64 init = 0);

    void Set(ulong64 newValue);
};

template <class IClientConfigAdminUlong64Subclass> class UClientConfigAdminUlong64Subclass : public UClientConfigAdminUlong64 {
    void Init(IClientConfigAdminUlong64 * item) { Init(static_cast<IClientConfigAdminUlong64Subclass *>(item)); };
    void Apply(IClientConfigAdminUlong64 * item) { Apply(static_cast<IClientConfigAdminUlong64Subclass *>(item)); };
public:
    virtual void Init(IClientConfigAdminUlong64Subclass * item) {};
    virtual void Apply(IClientConfigAdminUlong64Subclass * item) = 0;
};


class UClientConfigAdminString
{
public:
    virtual void Init(class IClientConfigAdminString * item) {};
    virtual void Apply(class IClientConfigAdminString * item) = 0;
};

class IClientConfigAdminString : public IClientConfigAdminItem
{
    UClientConfigAdminString * user;

    void Init() { user->Init(this); }
    void Apply() { user->Apply(this); }
    void ToJson(class json_io & json, word baseObject, char * & tmp) override;
    void FromJson(class json_io & json, word baseObject) override;

public:
    char * value;

    IClientConfigAdminString(class IClientConfigItems * items, UClientConfigAdminString * user, const char * name, const char * init = NULL);
    virtual ~IClientConfigAdminString();

    void Set(const char * newValue);
};

template <class IClientConfigAdminStringSubclass> class UClientConfigAdminStringSubclass : public UClientConfigAdminString {
    void Init(IClientConfigAdminString * item) { Init(static_cast<IClientConfigAdminStringSubclass *>(item)); };
    void Apply(IClientConfigAdminString * item) { Apply(static_cast<IClientConfigAdminStringSubclass *>(item)); };
public:
    virtual void Init(IClientConfigAdminStringSubclass * item) {};
    virtual void Apply(IClientConfigAdminStringSubclass * item) = 0;
};


class UClientConfigItems
{
public:
    virtual void ClientConfigItemAdded(IClientConfigItem * item) = 0;
    virtual void ClientConfigItemSet(IClientConfigItem * item) = 0;
};

class IClientConfigItems
{
friend class IClientConfigBasicItem;
friend class IClientConfigAdminItem;
    class btree * basicItems;
    class btree * adminItems;

    void Add(IClientConfigBasicItem * item);
    void Remove(IClientConfigBasicItem * item);
    void Add(IClientConfigAdminItem * item);
    void Remove(IClientConfigAdminItem * item);

    UClientConfigItems * user;

public:
    IClientConfigItems(UClientConfigItems * user);
    virtual ~IClientConfigItems();

    void Init();
    void ToJson(class json_io & json, word base, char * & tmp);
    void SetAdminSettings(class json_io & json, word base, bool pbx);
    void SetItemAdminSettings(IClientConfigItem * item, class json_io & json, word base, bool pbx);
    void ItemAdded(IClientConfigItem * item) { user->ClientConfigItemAdded(item); };
    void ItemSet(IClientConfigItem * item) { user->ClientConfigItemSet(item); };
};

extern IClientConfigItems * appclientConfigItems;