#ifndef GENESIS_GEN_GRID_H
#define GENESIS_GEN_GRID_H

#include <stdint.h>

#define DCOLS 79
#define DROWS 29

typedef enum {
    T_NOTHING    = 0,
    T_FLOOR      = 1,
    T_WALL       = 2,
    T_DOOR       = 3,
    T_CORRIDOR   = 4,
    T_LIQUID     = 5,
    T_BRIDGE     = 6,
    T_STAIRS_UP  = 7,
    T_STAIRS_DOWN = 8,
} terrain_t;

typedef enum {
    L_NONE      = 0,
    L_WATER     = 1,
    L_LAVA      = 2,
    L_CHASM     = 3,
    L_BRIMSTONE = 4,
} liquid_t;

typedef enum {
    F_IN_ROOM              = 1u << 0,
    F_IN_LOOP              = 1u << 1,
    F_CHOKEPT              = 1u << 2,
    F_BRIDGE               = 1u << 3,
    F_WREATH               = 1u << 4,
    /* Set on cells of a lake currently being tested for passability. Cleared
       on the next event (rejection or placement). Lets the viewer render the
       proposal overlay without any out-of-band metadata. */
    F_PROPOSED_LAKE        = 1u << 5,
    F_IN_MACHINE           = 1u << 6,  /* cell belongs to a machine instance */
    F_MACHINE_INTERIOR     = 1u << 7,  /* interior cell (not boundary) */
    F_MACHINE_GATE         = 1u << 8,  /* the vestibule / entry point */
    F_MACHINE_IMPREGNABLE  = 1u << 9,  /* later phases must not alter */
    F_MACHINE_KEY          = 1u << 10, /* key goes here (gameplay hint) */
} cell_flag_t;

/* Semantic placement markers, stored in cell.surface. Brogue uses the surface
   byte for atmospherics (gas/fluid splash). We repurpose it for machine
   markers, which the Godot RL interprets to spawn concrete items / decor /
   monsters. If we later want atmospherics back, cell_t can grow to 12 bytes
   and the .gen format bumps version; for MVP 8 bytes is plenty. */
typedef enum {
    MK_NONE           = 0,
    MK_CARPET,            /* decorative floor tint */
    MK_ALTAR,             /* item pedestal on an altar */
    MK_CAGE,              /* item behind a cage (key-guarded) */
    MK_PEDESTAL,          /* item on pedestal */
    MK_STATUE,            /* decorative statue */
    MK_TORCH,             /* light source */
    MK_BRAZIER,           /* light source */
    MK_CHEST,             /* item container */
    MK_SPAWN_MONSTER,     /* Godot spawns an enemy here */
    MK_SPAWN_BOSS,
    MK_KEY_ITEM,          /* the key that unlocks this machine's parent */
} marker_t;

typedef struct {
    uint8_t  terrain;
    uint8_t  liquid;
    uint8_t  surface;     /* marker_t — repurposed; see above */
    uint8_t  gas;
    uint16_t flags;
    uint8_t  room_id;
    uint8_t  machine_id;  /* 0 = not in any machine, 1..N = machine instance */
} cell_t;

typedef cell_t grid_t[DROWS][DCOLS];

void grid_fill(grid_t g, terrain_t t);
int  grid_in_bounds(int x, int y);
/* True if the terrain is walkable (floor, corridor, door, bridge, stairs). */
static inline int terrain_is_passable(uint8_t t) {
    return t == T_FLOOR || t == T_CORRIDOR || t == T_DOOR || t == T_BRIDGE
        || t == T_STAIRS_UP || t == T_STAIRS_DOWN;
}
void grid_draw_rect(grid_t g, int x, int y, int w, int h, terrain_t t, uint8_t room_id);
void grid_draw_circle(grid_t g, int cx, int cy, int r, terrain_t t, uint8_t room_id);
int  grid_flood_fill4(grid_t g, int x, int y, uint8_t marker);
int  grid_count_floor(grid_t g);

#endif
