#pragma once

#include "Chunk.hpp"
#include "../geometry/Faces.hpp"

using namespace geometry;
namespace world::client {
    class EdittableChunk: public virtual world::Chunk {
    public:
        virtual ~EdittableChunk();

        /// Update voxels
        /// @return if modified neighbors to update
        virtual std::optional<Faces> update(float deltaTime, bool animate);

        /// Notify for render
        inline void invalidate(Faces faces) {
            upToDate = false;
            toUpdate = toUpdate | faces;
        }
        void invalidate(chunk_voxel_idx idx);

        void apply(const Chunk::Edit &edit);

        using edits_t = robin_hood::unordered_map<chunk_voxel_idx, EditBody>;
        /// Get pending changes
        const edits_t &getEdits() const { return edits; }

        static std::optional<chunk_voxel_idx> getNeighborIdx(chunk_voxel_idx idx, Face dir);

    protected:
        EdittableChunk();

        /// Animated changes
        edits_t edits;
        /// Require update
        bool upToDate = true;
        /// Neighbors to update
        Faces toUpdate = Faces::None;
    };
}