#ifndef CLIPMAP_H
#define CLIPMAP_H

#include "model.h"
#include "mapent.h"
#include "effectdef.h"

struct cStaticModelWritable
{
    unsigned __int16 nextModelInWorldSector;
};

struct cStaticModel_s
{
    cStaticModelWritable writable;
    Model *xmodel;
    float origin[3];
    float invScaledAxis[3][3];
    float absmin[3];
    float absmax[3];
};

struct dmaterial_t
{
    char material[64];
    int surfaceFlags;
    int contentFlags;
};

struct cNode_t
{
    CPlane *plane;
    __int16 children[2];
};

struct CLeaf
{
    unsigned __int16 firstCollAabbIndex;
    unsigned __int16 collAabbCount;
    int brushContents;
    int terrainContents;
    float mins[3];
    float maxs[3];
    int leafBrushNode;
    __int16 cluster;
};

struct CLeafBrushNodeLeaf
{
    unsigned __int16 *brushes;
};

struct CLeafBrushNodeChildren
{
    float dist;
    float range;
    unsigned __int16 childOffset[2];
};

union CLeafBrushNodeData
{
    CLeafBrushNodeLeaf leaf;
    CLeafBrushNodeChildren children;
};

struct CLeafBrushNode
{
    unsigned __int8 axis;
    __int16 leafBrushCount;
    int contents;
    CLeafBrushNodeData data;
};

struct CollisionBorder
{
    float distEq[3];
    float zBase;
    float zSlope;
    float start;
    float length;
};

struct CollisionPartition
{
    unsigned __int8 triCount;
    unsigned __int8 borderCount;
    int firstTri;
    CollisionBorder *borders;
};

union CollisionAabbTreeIndex
{
    int firstChildIndex;
    int partitionIndex;
};

struct CollisionAabbTree
{
    float origin[3];
    float halfSize[3];
    unsigned __int16 materialIndex;
    unsigned __int16 childCount;
    CollisionAabbTreeIndex u;
};

struct CModel
{
    float mins[3];
    float maxs[3];
    float radius;
    CLeaf leaf;
};

struct __declspec(align(16)) CBrush
{
    float mins[3];
    int contents;
    float maxs[3];
    unsigned int numsides;
    CBrushSide *sides;
    __int16 axialMaterialNum[2][3];
    unsigned __int8 *baseAdjacentSide;
    __int16 firstAdjacentSideOffsets[2][3];
    unsigned __int8 edgeCount[2][3];
};

enum DynEntityType : __int32
{
    DYNENT_TYPE_INVALID = 0x0,
    DYNENT_TYPE_CLUTTER = 0x1,
    DYNENT_TYPE_DESTRUCT = 0x2,
    DYNENT_TYPE_COUNT = 0x3,
};

struct GfxPlacement
{
    float quat[4];
    float origin[3];
};

struct XModelPieces;
struct DynEntityDef
{
    DynEntityType type;
    GfxPlacement pose;
    Model *xModel;
    unsigned __int16 brushModel;
    unsigned __int16 physicsBrushModel;
    const EffectDef *destroyFx;
    XModelPieces *destroyPieces;
    PhysPreset *physPreset;
    int health;
    PhysMass mass;
    int contents;
};

struct DynEntityPose
{
    GfxPlacement pose;
    float radius;
};

struct DynEntityClient
{
    int physObjId;
    unsigned __int16 flags;
    unsigned __int16 lightingHandle;
    int health;
};

struct DynEntityColl
{
    unsigned __int16 sector;
    unsigned __int16 nextEntInSector;
    float linkMins[2];
    float linkMaxs[2];
};

struct ClipMap
{
    const char *name;
    int isInUse;
    int planeCount;
    CPlane *planes;
    unsigned int numStaticModels;
    cStaticModel_s *staticModelList;
    unsigned int numMaterials;
    dmaterial_t *materials;
    unsigned int numBrushSides;
    CBrushSide *brushsides;
    unsigned int numBrushEdges;
    unsigned __int8 *brushEdges;
    unsigned int numNodes;
    cNode_t *nodes;
    unsigned int numLeafs;
    CLeaf *leafs;
    unsigned int leafbrushNodesCount;
    CLeafBrushNode *leafbrushNodes;
    unsigned int numLeafBrushes;
    unsigned __int16 *leafbrushes;
    unsigned int numLeafSurfaces;
    unsigned int *leafsurfaces;
    unsigned int vertCount;
    float (*verts)[3];
    int triCount;
    unsigned __int16 *triIndices;
    unsigned __int8 *triEdgeIsWalkable;
    int borderCount;
    CollisionBorder *borders;
    int partitionCount;
    CollisionPartition *partitions;
    int aabbTreeCount;
    CollisionAabbTree *aabbTrees;
    unsigned int numSubModels;
    CModel *cmodels;
    unsigned __int16 numBrushes;
    CBrush *brushes;
    int numClusters;
    int clusterBytes;
    unsigned __int8 *visibility;
    int vised;
    MapEnts *mapEnts;
    CBrush *box_brush;
    CModel box_model;
    unsigned __int16 dynEntCount[2];
    DynEntityDef *dynEntDefList[2];
    DynEntityPose *dynEntPoseList[2];
    DynEntityClient *dynEntClientList[2];
    DynEntityColl *dynEntCollList[2];
    unsigned int checksum;
};

#endif // CLIPMAP_H
