#ifndef MODEL_HPP_
#define MODEL_HPP_

#include <Vk/DescriptorSet/DescriptorSet.hpp>
#include <atomic>

#include <Utilities/Extern.hpp>
#include <BoundingBox/BoundingBox.hpp>
#include <GraphicsContext/GraphicsContext.hpp>

class WorldDisplay;
class VoxelSprite;

/**
 * @brief Represents a model.
 */
class Model
{
private:
    std::shared_ptr<Vk::Buffer> buffer;
    std::shared_ptr<Vk::DescriptorSet> descSet;

public:
    /**
     * @brief Construct a model with the specified material.
     */
    Model(std::shared_ptr<Vk::Buffer> buffer, std::shared_ptr<Vk::DescriptorSet> descSet);

    /**
     * @brief Draw the model.
     * 
     * This must be called during the world stage. It will use the current model
     * matrix.
     */
    void draw(GraphicsContext &context, WorldDisplay &worldDisplay);

    static void renderModel(std::shared_ptr<Model> &outModel, VoxelSprite &sprite, std::atomic<unsigned int> &tasksDone);

    #define DECL_VOXEL_SPRITE(name) static std::shared_ptr<Model> name
    #include <VoxelSprite/VoxelSpriteList.hpp>
};

#endif