#pragma once

#include <vector>

#include <glm/vec2.hpp>
#include <glm/vec3.hpp>

#include "glclasses.hpp"

namespace endofthejedi {
#if 0
    class VertexAttribute {
        public:
            class Data {
                public:
                    enum class Type {
                        Integer, Float, Float2, Float3, Float4, Matrix3, Matrix4
                    };

                    void setDataInteger(int index, int v)
                    {
                    }

                    Data(Type type, int size) : m_type(type), m_size(size)
                    {
                        if (type ==
                    }

                private:
                    int                m_size;
                    Type               m_type;
                    std::vector<int>   m_sourceInteger;
                    std::vector<float> m_sourceFloat;
            };

        public:
            Data        data;
            std::string variableName;
            int         divisor;
            GLint       index;
    };
#endif

    class ParticleBatch {
        public:
            ParticleBatch(size_t id, size_t numParticles, float particleRadius, float halfAge);

            // deallocate opengl stuff on destroy
            ~ParticleBatch();

            // set particle data
            void setParticle(size_t index, const glm::vec3 &p, const glm::vec3 &v, float maxDistance);

            // stuff for setup/rendering usage
            void setup(Shader *shader);
            void bind();
            void upload();
            void render(Shader *shader);

            // advance internal state (mostly age)
            void tick(float dt);

            // check if the lifetime is over and whether it can be deleted.
            bool done() const;

            // access attributes
            size_t numParticles()  const { return m_numParticles; }
            float  ageNormalized() const { return m_age / (m_maxNumHalfAges*m_halfAge); }
            float  age()           const { return m_age; }
            size_t id()            const { return m_id; }
            const glm::vec3 &explosionCenter() const { return m_center; }

            // set attributes
            void setCenter(const glm::vec3 &center);
            void setMaxVelocity(float maxVelocity);

        private:
            size_t dataSizeForIndex(size_t index);
            void  *dataSourceForIndex(size_t index);

        private:
            // id of explosion
            size_t                 m_id;

            // uniforms for the shader
            size_t                 m_numParticles;
            float                  m_particleRadius;
            float                  m_age;
            const float            m_halfAge;
            const float            m_maxNumHalfAges;
            float                  m_maxVelocity;
            glm::vec3              m_center;

            // meta data
            size_t                 m_num_vertex_buffers;
            std::vector<GLuint>    m_data_vbos;
            std::vector<GLuint>    m_attr_locations;

            // vertex attributes
            std::vector<float>     m_data_geometry;
            std::vector<glm::vec3> m_data_position;
            std::vector<glm::vec3> m_data_velocity;
            std::vector<float>     m_data_max_distance;
    };
}
