#pragma once

#include <functional>
#include "../geometry/glm.hpp"
#include "../geometry/Box.hpp"

namespace world {

const auto CHUNK_LENGTH = glm::IDX_LENGTH;
const auto CHUNK_SIZE = glm::IDX_SIZE;
const auto REGION_LENGTH = glm::IDX_LENGTH;

/// Absolute floating position
using world_pos = glm::lfvec3;
/// Absolute integer position
using cell_pos = glm::llvec3;

using offset_pos = glm::vec3;
using pivot = glm::quat;
constexpr auto identity_pivot = pivot(1, 0, 0, 0);
using lpivot = glm::qua<glm::lf>;

/// Relative region position inside given area
/// CHUNK_LENGTH * REGION_LENGTH voxels long
/// Just needed 56 bits (i64 - u8)
using region_pos = glm::llvec3;
/// Relative chunk position inside given region
/// Just needed 5 bits (log2(REGION_LENGTH))
using region_chunk_pos = glm::usvec3;
/// Chunk index inside given region
/// Just needed 15 bits (log2(REGION_SIZE))
using region_chunk_idx = glm::us;
/// Relative chunk position inside given area
/// Needs 48 bits (i64 - u8 - u8)
using chunk_pos = glm::lvec3;
/// Relative voxel position inside given chunk
/// Just needed 5 bits (log2(CHUNK_LENGTH))
using chunk_voxel_pos = glm::ucvec3;
/// Voxel index inside given chunk
/// Just needed 15 bits (log2(REGION_SIZE))
using chunk_voxel_idx = glm::us;
/// Relative voxel position inside given area
using voxel_pos = glm::llvec3;

/// Axis Aligned Bounding box
using aabb = geometry::lfaabb;
/// Oriented Bounding box
using obb = geometry::lfobb;
}