#ifndef BREEZE_SPATIAL_GRID_H
#define BREEZE_SPATIAL_GRID_H

#include "../defines.h"

typedef struct BzSpatialGridIndex {
    i32 minX, minY;
    i32 maxX, maxY;
} BzSpatialGridIndex;

typedef i32 BzSpatialGridID;

typedef struct BzSpatialGridEntry {
    i32 queryIdx;
    BzSpatialGridID id;
    BzSpatialGridIndex index;
} BzSpatialGridEntry;

typedef struct BzSpatialGrid BzSpatialGrid;

typedef struct BzSpatialGridIter {
    BzSpatialGridEntry entry;
    void *data;
    BzSpatialGridIndex index;

    BzSpatialGrid *_grid;
    i32 _queryIdx;

    i32 _x;
    i32 _y;
    i32 _cellIdx;
} BzSpatialGridIter;

typedef struct BzSpatialGridDesc {
    i32 maxWidth;
    i32 maxHeight;
    i32 cellWidth;
    i32 cellHeight;
    i32 userDataSize;
} BzSpatialGridDesc;

BzSpatialGrid *bzSpatialGridCreate(const BzSpatialGridDesc *desc);
void bzSpatialGridDestroy(BzSpatialGrid *grid);

void *bzSpatialGridGetData(const BzSpatialGrid *grid, BzSpatialGridID id);

BzSpatialGridID bzSpatialGridInsert(BzSpatialGrid *grid, void *data, f32 posX, f32 posY, f32 sizeX, f32 sizeY);
void bzSpatialGridUpdate(BzSpatialGrid *grid, BzSpatialGridID id, f32 posX, f32 posY, f32 sizeX, f32 sizeY);
void bzSpatialGridRemove(BzSpatialGrid *grid, BzSpatialGridID id);

BzSpatialGridIter bzSpatialGridIter(BzSpatialGrid *grid, f32 posX, f32 posY, f32 sizeX, f32 sizeY);
bool bzSpatialGridQueryNext(BzSpatialGridIter *it);

void bzSpatialGridDrawDebugGrid(const BzSpatialGrid *grid);

#endif //BREEZE_SPATIAL_GRID_H
