extern crate mallumo_gls;
extern crate glutin;

#[macro_use]
extern crate error_chain;

mod errors {
    error_chain!{}
}

use errors::*;

use std::path::Path;
use std::f32;
use std::fs::File;
use std::io::BufReader;

use glutin::*;

use mallumo_gls::*;


quick_main!(run);

fn run() -> Result<()> {
    let width: u32 = 1280;
    let height: u32 = 720;

    let mut events_loop = glutin::EventsLoop::new();
    let window = glutin::WindowBuilder::new()
        .with_title("Hello, world!")
        .with_dimensions(width, height);
    let context = glutin::ContextBuilder::new()
        .with_gl(GlRequest::Specific(Api::OpenGl, (4, 5)))
        .with_gl_profile(GlProfile::Core);
    let gl_window = match glutin::GlWindow::new(window, context, &events_loop) {
        Err(e) => panic!("OpenGL Window Creation Error: {}", e),
        Ok(window) => window,
    };

    // Creation of Renderer
    let mut renderer = Renderer::new(&gl_window).chain_err(
        || "Unable to create window",
    )?;
    renderer.make_current().chain_err(
        || "Unable to make context current",
    )?;

    // Create pipeline that renders triangle
    let vertex = Shader::from_file(ShaderType::Vertex, Path::new("shaders/triangle.vert"))
        .chain_err(|| "Failed to compile vertex shader")?;
    let fragment = Shader::from_file(ShaderType::Fragment, Path::new("shaders/triangle.frag"))
        .chain_err(|| "Failed to compile fragment shader")?;
    let pipeline = PipelineBuilder::new()
        .vertex_shader(&vertex)
        .fragment_shader(&fragment)
        .build()
        .chain_err(|| "Unable to build pipeline")?;

    renderer.mut_default_framebuffer().set_viewport(Viewport {
        x: 0,
        y: 0,
        width: width,
        height: height,
    });

    events_loop.run_forever(|event| {
        match event {
            glutin::Event::WindowEvent { event, .. } => {
                match event {
                    glutin::WindowEvent::Closed => return glutin::ControlFlow::Break,
                    glutin::WindowEvent::Resized(w, h) => gl_window.resize(w, h),
                    _ => (),
                }
            }
            _ => (),
        }

        renderer.draw_arrays(
            FramebufferRenderTarget::Default,
            &[],
            &[],
            &pipeline,
            3,
            ClearBuffers::Color,
        );
        renderer.swap_buffers();

        glutin::ControlFlow::Continue
    });

    Ok(())
}
