mod gl {
    pub use gl::types::*;
    pub use gl::*;
}
use std::ptr;

use errors::Error;
use graphics;
use data::obj::OBJFile;

// Vertex data
// static VERTEX_DATA: [gl::GLfloat; 6] = [0.0, 0.5, 0.5, -0.5, -0.5, -0.5];
static TRI_OBJ: &'static str = "
v  0.0  0.5  0.0
v  0.5 -0.5  0.0
v -0.5 -0.5  0.0
v  0.0  0.5  0.0
v  0.5 -0.5  0.0
v -0.5 -0.5  0.0
f 1 2 3
";

// Shader sources
static VS_SRC: &'static str = "
#version 150
in vec3 position;
void main() {
    gl_Position = vec4(position, 1.0);
}";

static FS_SRC: &'static str = "
#version 150
out vec4 out_color;
void main() {
    out_color = vec4(1.0, 1.0, 1.0, 1.0);
}";

pub fn main_loop() -> Result<(), Error> {
    let window = graphics::Window::create()?;

    let vs = graphics::Shader::compile(graphics::ShaderType::Vertex, VS_SRC)?;
    let fs = graphics::Shader::compile(graphics::ShaderType::Fragment, FS_SRC)?;
    let program = graphics::Program::link(vec![vs, fs])?;

    let vertex_data = OBJFile::parse(TRI_OBJ).unwrap().to_bare_object().unwrap();
    let vbo = graphics::VertexBuffer::new_array_buffer(
        graphics::VertexArray::new(),
        &vertex_data,
    );

    program.use_program();
    program.bind_frag_data_location(0, "out_color")?;
    let pos_attr = program.get_attrib_location("position")?;

    unsafe {
        gl::EnableVertexAttribArray(pos_attr as gl::GLuint);
        gl::VertexAttribPointer(
            pos_attr as gl::GLuint,
            3,
            gl::FLOAT,
            gl::FALSE as gl::GLboolean,
            0,
            ptr::null(),
        );
    }

    vbo.unbind();

    window.run(move |event| {
        use glutin::event_loop::ControlFlow;
        use glutin::event::{Event, WindowEvent, VirtualKeyCode};

        println!("{:?}", event);
        match event {
            Event::WindowEvent { event: WindowEvent::CloseRequested, .. } =>
                return ControlFlow::Exit,
            Event::WindowEvent {
                event: WindowEvent::KeyboardInput {
                    input: k,
                    ..
                },
                ..
            } => {
                match k.virtual_keycode {
                    Some(VirtualKeyCode::Q) =>
                        return ControlFlow::Exit,
                    _ => println!("{:#?}", k),
                }
            }
            _ => (),
        }

        unsafe {
            gl::ClearColor(0.3, 0.3, 0.3, 1.0);
            gl::Clear(gl::COLOR_BUFFER_BIT);

            vbo.bind();

            gl::DrawArrays(gl::TRIANGLES, 0, 3);
        }

        ControlFlow::Wait
    })?;

    Ok(())
}
