#include "VertexArrayGroup.hpp"

#include <engine/graphics/utility/array_generator.hpp>

namespace megu {
    VertexArrayGroup::VertexArrayGroup()
    : _vbo(this->_vao, Quads::Layout(), Quads::Vertices(), megu::EditMode::STATIC) {
        Source vert("assets/shaders/Grid-Instanced.vert", Source::Categorie::VERTEX);
        this->_program.attach(vert);

        Source frag("assets/shaders/Grid-Instanced.frag", Source::Categorie::FRAGMENT);
        this->_program.attach(frag);

        this->_program.link();

        vert.release();
        frag.release();
    }

    void VertexArrayGroup::add(const Texture & texture, const VerticesArray & grid) {
        this->_objects[texture].push_back(grid);
    }

    void VertexArrayGroup::draw(const Window &, const Camera & camera, const TextureArray &) const {
        this->_vao.bind();
        this->_program.use();

        this->_program.setUniform("uProj", camera.projection());
        this->_program.setUniform("uView", camera.view());

        for(const auto & [texture, grids] : this->_objects) {
            texture.get().bind(0);
            for(const auto & grid : grids) {
                this->_program.setUniform("uModel", grid.get().transformation().model());
                this->_program.setUniform("uSampler", 0);
                this->_program.setUniform("uData", static_cast<const void *>(grid.get().vertices().data()), grid.get().size());

                glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(grid.get().size()));
            }
        }
    }
}