#ifndef CODUO_DOBJ_PRIVATE_H
#define CODUO_DOBJ_PRIVATE_H

#include <stdint.h>

#include "coduo_engine_structs.h"

extern coduo_dobj_pool_t dobjPool;
extern coduo_dobj_occupancy_table_t dobjOccupancy;
extern coduo_dobj_primary_lookup_table_t dobjPrimaryLookup;
extern coduo_dobj_secondary_lookup_table_t dobjSecondaryLookup;
extern int32_t dobjLastSearchSlot;
extern qboolean dobjPoolInitialized;
extern int32_t dobj_skelCacheKey;

void DObjInitPool(void);
void DObjShutdownPool(void);
void DObjBumpSkelCacheKey(void);
DObj *DObjGetForEntity(int32_t entityNum);
void DObjConstructRecord(DObjModel *models,
                         uint16_t modelCount,
                         XAnimTree *runtimeTree,
                         DObj *state,
                         uint16_t gameId);
void DObjDestroyRecord(DObj *state,
                       qboolean releaseRuntimeTree);
void DObjDumpInfo(DObj *state);
void DObjGetBounds(DObj *state, vec3_t mins, vec3_t maxs);
qboolean DObjHasContents(DObj *state,
                         int32_t contentMask);
qboolean DObjSkelIsBoneUpToDate(DObj *state,
                                int32_t boneIndex);
qboolean DObjSkelAreBonesUpToDate(DObj *state,
                                  const uint32_t *partBits);
void DObjGetHierarchyBits(DObj *state,
                          int32_t boneIndex,
                          uint32_t *partBits);
void DObjCalcSkel(DObj *state, const uint32_t *partBits);
void DObjDisplayAnim(DObj *state);
void DObjTraceParts(DObj *state, const vec3_t start,
                    const vec3_t end, const uint8_t *partState,
                    coduo_dobj_trace_result_t *trace);
void DObjTraceModelParts(DObj *state, const vec3_t start,
                         const vec3_t end,
                         int32_t contentMask,
                         coduo_dobj_trace_result_t *trace);
DObjSkelMat *
DObjBasePoseForChild(DObj *state,
                     uint8_t childIndex);
void DObjMatrixTransformVector43(const vec3_t in,
                                 const DObjSkelMat *matrix,
                                 vec3_t out);
void DObjMatrixInverseTransformVector43(const vec3_t in,
                                        const DObjSkelMat *matrix,
                                        vec3_t out);
void DObjQuatToMatrix43(const vec4_t quat, DObjSkelMat *matrix);
void DObjMatrixTransformVector43InPlace(vec3_t point,
                                        const DObjSkelMat *matrix);
void DObjQuatMultiplyIntoFirst(vec4_t quat, const vec4_t rhs);
void DObjQuatMultiplyIntoSecond(const vec4_t lhs, vec4_t quat);

int32_t
DObjEvalStorageSize(DObj *state);
qboolean
DObjRefreshEvalStorageKey(DObj *state,
                          int32_t key);
void DObjBindEvalStorage(DObj *state,
                         coduo_xanim_eval_storage_t *storage);
int32_t DObjNumBones(DObj *state);
int32_t
DObjFindPartIndex(DObj *state,
                  uint16_t partName);
int32_t DObjGetBoneIndex(DObj *state,
                                         const char *tagName);
const char *DObjGetBoneName(DObj *state,
                            int32_t boneIndex);
DObjAnimMat *
DObjEvalStorageSeedOutput(DObj *state);
qboolean DObjMarkRotTransIndex(
    DObj *state, const uint32_t *partBits,
    int32_t boneIndex);
qboolean DObjMarkControlRotTransIndex(
    DObj *state, const uint32_t *partBits,
    int32_t boneIndex);
XAnimTree *DObjGetTree(DObj *state);

#endif
