//
// Created by sebastian on 29.07.26.
//

#ifndef COLORRACE_VAO_H
#define COLORRACE_VAO_H

#pragma once
#include <memory>
#include <vector>
#include "Vbo.h"
#include "Attribute.h"

namespace engine {

class Vao {
public:
    static std::unique_ptr<Vao> create();

    ~Vao();

    Vao(const Vao&) = delete;
    Vao& operator=(const Vao&) = delete;

    Vbo& getVbo(size_t index) const { return *m_relatedVbos.at(index); }

    void bind() const;
    void unbind() const;

    void enableAttributes() const;
    void disableAttributes(const std::vector<unsigned int>& attribNumbers) const;

    Vbo& createDataFeed(size_t maxVertexCount, GLenum usage,
                         std::vector<std::unique_ptr<Attribute>> newAttributes);

    Vbo& createInstanceDataFeed(size_t maxInstances,
                                 std::vector<std::unique_ptr<Attribute>> newAttributes);

    Vbo& initDataFeed(const void* data, size_t sizeInBytes, GLenum usage,
                       std::vector<std::unique_ptr<Attribute>> newAttributes);

    void linkBoundVbo(std::unique_ptr<Vbo> vbo,
                       std::vector<std::unique_ptr<Attribute>> newAttributes);

    void linkInstancingVbo(std::unique_ptr<Vbo> vbo,
                            std::vector<std::unique_ptr<Attribute>> newAttributes);

    Vbo& createIndexBuffer(const unsigned int* indices, size_t count);
    Vbo& createIndexBufferFeed(size_t maxIndexCount);

    unsigned int getId() const { return m_id; }
    bool hasIndexBuffer() const { return m_indexBuffer != nullptr; }

private:
    explicit Vao(unsigned int id);

    unsigned int m_id;
    std::vector<std::unique_ptr<Vbo>> m_relatedVbos;
    std::unique_ptr<Vbo> m_indexBuffer;
    std::vector<std::unique_ptr<Attribute>> m_attributes;

    void indicateInstancedAttributes(const std::vector<std::unique_ptr<Attribute>>& attributes) const;
    void linkAttributes(int bytesPerVertex, std::vector<std::unique_ptr<Attribute>>& newAttributes);
    static int getVertexDataTotalBytes(const std::vector<std::unique_ptr<Attribute>>& attributes);
};

} // namespace engine

#endif //COLORRACE_VAO_H
