using Glutils
using ModernGL
using GLFW
# matrices utils
import Glutils: Mat
# Create the window
window = GLFW.CreateWindow(800, 600, "Basic Example")
# set the current OpenGL context
GLFW.MakeContextCurrent(window)
# create a vertex buffer
vbo = arraybuffer(Cfloat[
    -0.5, -0.5, 0.0,
     0.5, -0.5, 0.0,
     0.0,  0.5, 0.0
], g"static draw")
# create a vertex array
vao = vertexarray()
vertexattrib(Cfloat, 3,
    (size = 3, offset = 0), # 0
)
# creates the shader program
# note: here we use the --- <type> pattern
# to indicate the beginning of each shader
program = program"""
--- vertex
#version 330 core
layout(location = 0) in vec3 pos;

uniform mat4 rotation;

void main() {
    gl_Position = rotation * vec4(pos.x, pos.y, pos.z, 1.0);
}

--- fragment
#version 330 core
out vec4 color;
uniform vec4 our_color;

void main() {
    color = our_color;
}
"""
# get the location of our_color 
# and rotation uniforms
@uniforms our_color, rotation = program
t = 0.0
# background color
glClearColor(0.0, 0.0, 0.0, 1.0)
# main loop
while true
    # Break the loop when the window closes
    GLFW.WindowShouldClose(window) && break
    # Wait for events
    GLFW.PollEvents()
    # Clear the screen
    glClear(g"color buffer bit")
    # set the uniform variables
    @uniforms! begin
        # compute the color based on t
        r, g, b = [sin(t), cos(t), sin(t)] ./ 2 .+ 1
        # the 'foo := bar' syntax sets the uniform value of foo
        our_color := Cfloat[r, g, b, 1.0]
        # rotate in the Z-axis
        rotation := Mat.rotationZ(t, Cfloat)
    end
    # Render here
    glBindVertexArray(vao)
    glUseProgram(program)
    glDrawArrays(g"TRIANGLES", 0, 3)
    # Swap the buffers
    GLFW.SwapBuffers(window)
    global t += 0.0001;
end

GLFW.DestroyWindow(window)