#include <iostream>

#include <GL/glew.h>
#include <GLFW/glfw3.h>

constexpr auto width  = 640;
constexpr auto height = 480;
constexpr auto title  = "sdf-winding";

static void APIENTRY debug_message_callback(
    GLenum          /* source   */,
    GLenum          /* type     */,
    GLuint          /* id       */,
    GLenum          /* severity */,
    GLsizei         /* length   */,
    GLchar  const *    message,
    void    const * /* param    */
)
{
    std::cerr << message << std::endl;
};

int main()
{
    /// Window/context
    glfwInit();
    auto window = glfwCreateWindow(width, height, title, nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glewInit();

    /// Debug
    glEnable(GL_DEBUG_OUTPUT);
    glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
    glDebugMessageCallback(debug_message_callback, nullptr);

    /// Shader
    auto make_program = [](char const * fragment_source)
    {
        auto program = glCreateProgram();
        auto attach  = [&](GLenum type, char const * source)
        {
            auto shader = glCreateShader(type);
            glShaderSource(shader, 1, &source, nullptr);
            glCompileShader(shader);
            glAttachShader(program, shader);
        };
        attach(GL_VERTEX_SHADER, R"(
            #version 140

            out vec2 tex_coord;

            void main()
            {
                tex_coord = vec2[](
                    vec2(0, 0),
                    vec2(2, 0),
                    vec2(0, 2)
                )[gl_VertexID];
                gl_Position = vec4(tex_coord*2-1, 0, 1);
            }
        )");
        attach(GL_FRAGMENT_SHADER, fragment_source);
        glLinkProgram(program);
        return program;
    };
    auto tex_coord_program = make_program(R"(
        #version 140

        in vec2 tex_coord;

        void main()
        {
            gl_FragColor = vec4(tex_coord, 0, 1);
        }
    )");

    /// Draw loop
    while (glfwPollEvents(), !glfwWindowShouldClose(window))
    {
        //// Input
        if (glfwGetKey(window, GLFW_KEY_Q))
            glfwSetWindowShouldClose(window, GLFW_TRUE);

        //// Draw
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(tex_coord_program);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        //// Swap
        glfwSwapBuffers(window);
    }

    /// Cleanup
    glfwDestroyWindow(window);
    glfwTerminate();
}