#include <iomanip>
#include <iostream>
#include <string>
#include <type_traits>

#include <glm/glm.hpp>

#include <glbase.hpp>
#include <gltraits.hpp>


struct GLTraitsTest : protected GLBase
{

    template<typename Value>
    void static test_value()
    {
        using Traits = GLTraits::Value<Value>;
        static_assert(
            std::is_empty<Traits>::value,
            "GLTraits::Value must be empty"
        );
        #define GLTRAITS_TEST_VALUE(NAME, VALUE) \
            << std::left << std::setw(35) << "  " NAME ":" << VALUE << "\n"
        #define GLTRAITS_TEST_VALUE_DEC(NAME) \
            GLTRAITS_TEST_VALUE(#NAME, std::dec << Traits::NAME)
        #define GLTRAITS_TEST_VALUE_BOOL(NAME) \
            GLTRAITS_TEST_VALUE(#NAME, std::boolalpha << Traits::NAME)
        #define GLTRAITS_TEST_VALUE_ENUM(NAME, SUFFIX) \
            GLTRAITS_TEST_VALUE( \
                #NAME #SUFFIX, \
                str_##NAME##_(Traits::NAME##SUFFIX) \
            )
        std::cout
            << "Value<" << Traits::name << ">" << "\n"
            GLTRAITS_TEST_VALUE_DEC(columns)
            GLTRAITS_TEST_VALUE_DEC(rows)
            GLTRAITS_TEST_VALUE_ENUM(glsl,)
            GLTRAITS_TEST_VALUE_ENUM(format,)
            GLTRAITS_TEST_VALUE_ENUM(type,)
            GLTRAITS_TEST_VALUE_ENUM(internal_format,)
            GLTRAITS_TEST_VALUE_ENUM(internal_format, _srgb)
            GLTRAITS_TEST_VALUE_ENUM(internal_format, _compressed)
            GLTRAITS_TEST_VALUE_ENUM(internal_format, _compressed_srgb)
            GLTRAITS_TEST_VALUE_BOOL(integer);
    }

};


int main()
{
    GLTraitsTest::test_value<GLfloat>();
    GLTraitsTest::test_value<bool>();
    GLTraitsTest::test_value<GLshort>();
    GLTraitsTest::test_value<GLdouble>();
    GLTraitsTest::test_value<glm::mat4x3>();
    GLTraitsTest::test_value<glm::uvec2>();
    GLTraitsTest::test_value<glm::dvec2>();
}