extern crate gltf;

use glium::{ VertexBuffer, IndexBuffer, Program };

#[derive(Copy, Clone)]
struct Vertex {
    position: [f32; 3],
}

implement_vertex!(Vertex, position);

pub struct Model {
    vb: VertexBuffer<Vertex>,
    ib: IndexBuffer<u16>,
}

impl Model {
    pub fn new(display: &glium::Display, file: &str) -> Self {
	let (document, buffers, _images) = gltf::import(file).expect("Could not load gltf file");
	let mesh = document.meshes().next().expect("Could not find mesh");
	let primitive = mesh.primitives().next().expect("Could not find primitive");
	let reader = primitive.reader(|buffer| Some(&buffers[buffer.index()]));
	let vertices = reader
	    .read_positions()
	    .unwrap()
	    .map(|position| Vertex { position })
	    .collect::<Vec<Vertex>>();
	let vb = VertexBuffer::new(display, &vertices).unwrap();
	let indices = reader
	    .read_indices()
	    .unwrap()
	    .into_u32()
	    .map(|x| x as u16)
	    .collect::<Vec<u16>>();
	let ib = IndexBuffer::new(display, glium::index::PrimitiveType::TrianglesList, &indices).unwrap();
	Model { vb, ib }
    }

    pub fn draw(&self,
	target: &mut impl glium::Surface,
	program: &glium::Program,
	uniforms: &impl glium::uniforms::Uniforms
    ) {
	target.draw(&self.vb, &self.ib, program, uniforms, &Default::default()).unwrap()
    }
}
