#ifndef VOXELGAME_H
#define VOXELGAME_H

#include <vector>

#include <algorithm>
#include <unordered_map>
#include "GreedyMesher.h"

// Structure representing a chunk (16×16×16 voxels)
struct Chunk {
    int x, z; // Chunk grid coordinates
    // 3D voxel data: dimensions [16][16][16]
    std::vector<std::vector<std::vector<int>>> voxels;
    // **Merged mesh faces** produced by the greedy mesher
    std::vector<Quad> mesh;
};

// A key for identifying a chunk by its grid coordinates.
struct ChunkKey {
    int x, z;
    bool operator==(const ChunkKey &other) const {
        return x == other.x && z == other.z;
    }
};

struct ChunkKeyHash {
    std::size_t operator()(const ChunkKey &key) const {
        return std::hash<int>()(key.x) ^ (std::hash<int>()(key.z) << 1);
    }
};

class VoxelGame {
public:
    VoxelGame();
    ~VoxelGame();
    
    bool init();
    void update(float deltaTime, const float cameraPos[3]);
    void render();
    void debugUI();
    
private:
    bool loadTextures();
    Chunk generateChunk(int cx, int cz);
    void updateChunks(const float cameraPos[3]);
    void drawCube(float x, float y, float z, int voxelType);
    
    std::unordered_map<ChunkKey, Chunk, ChunkKeyHash> chunks;
    int totalChunksLoaded;
    int totalChunksEverLoaded;
    
    unsigned int textureGrass;
    unsigned int textureDirt;
    unsigned int textureWood;
};

#endif // VOXELGAME_H
