#pragma once

#include <glad/gl.h>

#include <memory>

namespace kuiper
{

namespace gl
{

    class vertex_array {
      public:
        using s_ptr = std::shared_ptr<vertex_array>;

        explicit vertex_array(GLuint id)
            : m_id(id) {}
        ~vertex_array() {
            destroy();
        }

        vertex_array(const vertex_array& other)                = delete;
        vertex_array& operator=(const vertex_array& other)     = delete;
        vertex_array(vertex_array&& other) noexcept            = default;
        vertex_array& operator=(vertex_array&& other) noexcept = default;

        static s_ptr make() noexcept;

      public:
        GLuint id() const noexcept {
            return m_id;
        }

        void destroy() noexcept;
        void bind() const noexcept;
        void enable_attrib(std::uint32_t index) noexcept;
        void disable_attrib(std::uint32_t index) noexcept;
        void set_attrib_divisor(std::uint32_t attrib, std::uint32_t divisor) noexcept;
        void set_binding_divisor(std::uint32_t binding, std::uint32_t divisor) noexcept;

      private:
        GLuint m_id {0};
    };

} // namespace gl

} // namespace kuiper
