mod readers;
mod utils;

pub use utils::validate_wad;

use crate::lumps::{Lump, LumpType};
use std::{fs::File, io::Read, path::Path};

use super::header::Header;
use crate::utils::{read_ascii, read_i16_le, read_u32_le};

pub struct WADFile {
    pub path: String,
    pub wad_id: String,
    pub num_lumps: u32,
    pub dir_offset: u32,
    pub directory: Vec<Lump>,
    pub data: Vec<u8>,
}

impl WADFile {
    pub fn new(path: String) -> Self {
        if !(validate_wad(path.as_str()).unwrap()) {
            panic!();
        }

        let file_path = Path::new(path.as_str());
        let mut wad_file = File::open(file_path).unwrap();
        let file_size = wad_file.metadata().unwrap().len() as usize;
        let mut file_buffer: Vec<u8> = Vec::with_capacity(file_size);

        wad_file.read_to_end(&mut file_buffer).unwrap();

        let wad_header = Header::read_data(&file_buffer[0..12]);

        let mut lump_dir: Vec<Lump> = Vec::with_capacity(wad_header.num_lumps as usize);
        let offset = wad_header.dir_offset;

        for entry in 0..wad_header.num_lumps {
            let startpos = (offset + 16 * entry) as usize;
            let lump_offset = read_u32_le(&file_buffer[startpos..startpos + 4]);
            let size = read_u32_le(&file_buffer[startpos + 4..startpos + 8]);
            let name = read_ascii(&file_buffer[startpos + 8..startpos + 16]);
            let lump_type = match name.as_str() {
                "VERTEXES" => LumpType::Vertex,
                "LINEDEFS" => LumpType::Linedef,
                "SIDEDEFS" => LumpType::Sidedef,
                "THINGS" => LumpType::Thing,
                _ => LumpType::Unknown,
            };
            lump_dir.push(Lump {
                name,
                offset: lump_offset,
                lump_type,
                size,
            });
        }

        Self {
            path,
            wad_id: wad_header.wad_id,
            num_lumps: wad_header.num_lumps,
            dir_offset: wad_header.dir_offset,
            directory: lump_dir,
            data: file_buffer,
        }
    }
}
