#ifndef CODUO_CM_LEAF_QUERIES_PRIVATE_H
#define CODUO_CM_LEAF_QUERIES_PRIVATE_H

#include <stddef.h>
#include <stdint.h>

#include "coduo_engine_structs.h"

typedef struct cmLeafQueryWork_s cmLeafQueryWork_t;
typedef void (*cmLeafQueryStoreFn)(
    cmLeafQueryWork_t *work, int32_t nodeNum);

struct cmLeafQueryWork_s {
    int32_t count;
    int32_t maxcount;
    qboolean overflowed;
    /* 0x080572b0/0x080573cb: the callback owns this one +0x0c result-list
     * pointer.  CM_StoreLeafs writes int32_t leaf numbers; CM_StoreLeafBrushes
     * writes brush pointers.  The machine code does not establish distinct
     * union arms. */
    void *list;
    vec3_t mins;
    vec3_t maxs;
    int32_t lastLeaf;
    cmLeafQueryStoreFn storeLeafs;
};

_Static_assert(offsetof(cmLeafQueryWork_t, count) == 0x00,
               "cmLeafQueryWork_t.count offset mismatch");
_Static_assert(offsetof(cmLeafQueryWork_t, maxcount) == 0x04,
               "cmLeafQueryWork_t.maxcount offset mismatch");
_Static_assert(offsetof(cmLeafQueryWork_t, overflowed) == 0x08,
               "cmLeafQueryWork_t.overflowed offset mismatch");
#if UINTPTR_MAX == UINT32_MAX
_Static_assert(offsetof(cmLeafQueryWork_t, list) == 0x0c,
               "cmLeafQueryWork_t.list offset mismatch");
_Static_assert(offsetof(cmLeafQueryWork_t, mins) == 0x10,
               "cmLeafQueryWork_t.mins offset mismatch");
_Static_assert(offsetof(cmLeafQueryWork_t, maxs) == 0x1c,
               "cmLeafQueryWork_t.maxs offset mismatch");
_Static_assert(offsetof(cmLeafQueryWork_t, lastLeaf) == 0x28,
               "cmLeafQueryWork_t.lastLeaf offset mismatch");
_Static_assert(offsetof(cmLeafQueryWork_t, storeLeafs) == 0x2c,
               "cmLeafQueryWork_t.storeLeafs offset mismatch");
#endif

extern coduo_collision_node_t *cm_nodes;
extern coduo_collision_leaf_t *cm_leafs;

int32_t BoxOnPlaneSide(const vec3_t emins, const vec3_t emaxs,
                       const cplane_t *plane);
int32_t CM_PointLeafnum_r(const vec3_t point,
                                             int32_t nodeNum);
void CM_StoreLeafs(cmLeafQueryWork_t *work, int32_t nodeNum);
void CM_StoreLeafBrushes(cmLeafQueryWork_t *work, int32_t nodeNum);
void CM_BoxLeafnums_r(cmLeafQueryWork_t *work, int32_t nodeNum);

#endif
