use anyhow::Result;

use std::fs::File;
use std::collections::HashMap;
use std::io::BufReader;

use crate::app_data;
use crate::scene;
use crate::vertex;

use cgmath::{vec3, vec2};

pub fn load_model(data: &mut app_data::AppData, scene_handler: &mut scene::Scene) -> Result<()> {
    // Model

    let mut reader = BufReader::new(File::open("./resources/viking_room.obj").expect("file not found"));

    let (models, _) = tobj::load_obj_buf(
        &mut reader,
        &tobj::LoadOptions {
            triangulate: true,
            ..Default::default()
        },
        |_| Ok(Default::default()),
    )?;

    // Vertices / Indices

    let mut unique_vertices = HashMap::new();

    for model in &models {
        for index in &model.mesh.indices {
            let pos_offset = (3 * index) as usize;
            let tex_coord_offset = (2 * index) as usize;

            let vertex = vertex::Vertex {
                pos: vec3(
                    model.mesh.positions[pos_offset],
                    model.mesh.positions[pos_offset + 1],
                    model.mesh.positions[pos_offset + 2],
                ),
                color: vec3(1.0, 1.0, 1.0),
                tex_coord: vec2(
                    model.mesh.texcoords[tex_coord_offset],
                    1.0 - model.mesh.texcoords[tex_coord_offset + 1],
                ),
            };

            if let Some(index) = unique_vertices.get(&vertex) {
                scene_handler.indices_cube.push(*index as u32);
            } else {
                let index = scene_handler.vertices.len();
                unique_vertices.insert(vertex, index);
                scene_handler.vertices.push(vertex);
                scene_handler.indices_cube.push(index as u32);
            }
        }
    }

    Ok(())
}