#pragma once
#include <cstdint>

namespace Def
{
    constexpr int32_t MaxNameLength = 64;
    constexpr int32_t MaxFields = 64;
    constexpr int32_t MaxExtraEnumFields = 2;

    enum class EFieldType : uint8_t
    {
        DefinedClass,
        DefinedEnum
    };

    enum class ETypeFlags : uint32_t
    {
        None = 0,
        IsNative = 1 << 0,
    };

    enum class ETypeFieldFlags : uint32_t
    {
        None = 0,
        DynamicArray = 1 << 0,
    };

    struct TypeRef
    {
        uint16_t TypeIdx = UINT16_MAX;
        EFieldType FieldKind = EFieldType::DefinedClass;
    };
    inline bool IsValid(TypeRef ref)
    {
        return ref.TypeIdx != UINT16_MAX;
    }

    struct Type
    {
        int32_t FieldCount = 0;
        TypeRef FieldTypes[MaxFields];
        char FieldNames[MaxFields][MaxNameLength];
        uint32_t FieldArraySizes[MaxFields]{0};
        char FieldValues[MaxFields][128]{0};
        ETypeFlags TypeFlags = ETypeFlags::None;
        ETypeFieldFlags FieldFlags[MaxFields]{ETypeFieldFlags::None};
        char Name[MaxNameLength]{0};
        char NativeCName[MaxNameLength]{0};
        uint32_t Hash = 0;
    };

    struct Enum
    {
        TypeRef EnumType;
        int32_t EntryCount = 0;
        char EntryNames[MaxFields][MaxNameLength];
        int32_t ExtraStringFieldCount = 0;
        char ExtraStringFieldNames[MaxExtraEnumFields][MaxNameLength];
        char ExtraStringFields[MaxFields][MaxExtraEnumFields][MaxNameLength];
        char Name[MaxNameLength]{0};
        uint32_t Hash = 0;
    };

    struct DefinitionFile
    {
        static constexpr int32_t MaxTypes = 256;
        Def::Type Types[MaxTypes];
        uint16_t TypeCount = 0;
        Def::Enum Enums[MaxTypes];
        int32_t EnumCount = 0;
    };
} // namespace Def
