#ifndef M_DO_M_DO_HOSTIO_H
#define M_DO_M_DO_HOSTIO_H

#include "JSystem/JHostIO/JORReflexible.h"
#include <cstring>

class mDoHIO_child_c {
public:
    mDoHIO_child_c() {
        unk18 = 0;
        mPt = NULL;
    }

    ~mDoHIO_child_c();

    void setPt(JORReflexible* i_pt) { mPt = i_pt; }
    void setName(const char* i_name) { strncpy(mName, i_name, sizeof(mName)); }
    JORReflexible* getPt() { return mPt; }
    const char* getName() { return mName; }

    /* 0x00 */ char mName[24];
    /* 0x18 */ u8 unk18;
    /* 0x1C */ JORReflexible* mPt;
};

class mDoHIO_entry_c : public JORReflexible {
public:
#if DEBUG
    mDoHIO_entry_c();
    void entryHIO(const char* i_name);
    void removeHIO();

    virtual ~mDoHIO_entry_c();

    /* 0x4 */ s8 mNo;
    /* 0x5 */ u8 mCount;
#else
#if PARTIAL_DEBUG
    // Initialized here since the DEBUG ctor doesn't run.
    /* 0x4 */ s8 mNo = -1;
    /* 0x5 */ u8 mCount = 0;
#endif
    virtual ~mDoHIO_entry_c() {}
#endif
};

class mDoHIO_subRoot_c : public JORReflexible {
public:
    mDoHIO_subRoot_c() {}
    void updateChild(s8);
    void deleteChild(s8);
    s8 createChild(const char*, JORReflexible*);

    virtual void genMessage(JORMContext*);
    virtual ~mDoHIO_subRoot_c();

    /* 0x4 */ mDoHIO_child_c mChildren[80];
};

class mDoHIO_root_c : public JORReflexible {
public:
    mDoHIO_root_c() {}
    void update();
    void updateChild(s8);
    void deleteChild(s8);
    s8 createChild(const char* i_name, JORReflexible* i_node) {
        return mSub.createChild(i_name, i_node);
    }

    virtual void genMessage(JORMContext*);
    virtual ~mDoHIO_root_c();

    /* 0x4 */ mDoHIO_subRoot_c mSub;
};

extern mDoHIO_root_c mDoHIO_root;

void mDoHIO_updateChild(s8 i_no);
inline void mDoHIO_update() {
    mDoHIO_root.update();
};
void mDoHIO_deleteChild(s8 i_no);
inline s8 mDoHIO_createChild(const char* i_name, JORReflexible* i_node) {
    return mDoHIO_root.createChild(i_name, i_node);
}

#if DEBUG
#define mDoHIO_CREATE_CHILD(i_name, i_node) mDoHIO_createChild(i_name, i_node)
#define mDoHIO_DELETE_CHILD(i_no)           mDoHIO_deleteChild(i_no)
#else
#define mDoHIO_CREATE_CHILD(i_name, i_node) (-1)
#define mDoHIO_DELETE_CHILD(i_no)           (void)0
#endif

#endif /* M_DO_M_DO_HOSTIO_H */
