#pragma once

#include <Array.h>
#include <Critical.h>
#include <Model3D.h>
#include <Model3DCollection.h>
#include <Punkt.h>
#include <Reader.h>

#include "Area.h"
#include "Block.h"

class Chunk : public Framework::Model3DCollection
{
private:
    Framework::Punkt location;
    // TODO: use native array for bedder performance?
    Framework::RCArray<Block> blocks;
    Framework::Array<Block*> visibleBlocks;
    bool isLoading;
    Framework::Critical cs;
    Framework::Critical vcs;

public:
    Chunk(Framework::Punkt location);
    Chunk(Framework::Punkt location, Framework::StreamReader* zReader);
    ~Chunk();
    void api(char* message);
    Block* zBlockAt(Framework::Vec3<int> cLocation);
    void setBlock(Block* block);
    void removeBlock(Block* zBlock);
    void load(Framework::StreamReader* zReader);
    void blockVisibilityChanged(Block* zB);
    Framework::Punkt getCenter() const;
    Framework::Vec3<int> getMin() const;
    Framework::Vec3<int> getMax() const;
    void forAll(std::function<void(Model3D*)> f) override;
};