#ifndef CHUNK_H
#define CHUNK_H

#include <unordered_map>
#include <memory>

#include <glm/glm.hpp>

#include "Mesh.h"

enum VoxelKind {
    Dirt,
    Stone
};

const int CHUNK_SIZE = 32;

// Hash function for glm::ivec3 to use with unordered_set
namespace std {
    template <>
    struct hash<glm::ivec3> {
        size_t operator()(const glm::ivec3& v) const {
            // Combine hash values of x, y, z components
            size_t h1 = hash<int>()(v.x);
            size_t h2 = hash<int>()(v.y);
            size_t h3 = hash<int>()(v.z);

            // Use a simple hash combination algorithm
            return h1 ^ (h2 << 1) ^ (h3 << 2);
        }
    };
}

class Chunk {
  public:
    std::unordered_map<glm::ivec3, VoxelKind> voxels;

    Chunk();
    Chunk(std::unordered_map<glm::ivec3, VoxelKind> voxels);

    Mesh* getMesh();  // Returns pointer, can be null if not generated yet

    void generateMesh();
    void regenerateMesh();

  private:
    std::unique_ptr<Mesh> mesh;  // Nullable mesh
};

#endif CHUNK_H
