use crate::utils::read_float_file;
use anyhow::Result;
use shared::core::color::{Coeffs, RES, RGBToSpectrumTable};
use shared::{Float, Ptr};
use std::ops::Deref;
use std::path::Path;

pub struct RGBToSpectrumTableData {
    _z_nodes: Vec<Float>,
    _coeffs: Vec<Float>,

    pub view: RGBToSpectrumTable,
}

impl Deref for RGBToSpectrumTableData {
    type Target = RGBToSpectrumTable;
    fn deref(&self) -> &Self::Target {
        &self.view
    }
}

impl RGBToSpectrumTableData {
    pub fn new(z_nodes: Vec<Float>, coeffs: Vec<Float>) -> Self {
        assert_eq!(z_nodes.len(), RES as usize);
        assert_eq!(coeffs.len(), (RES * RES * RES) as usize * 3 * 3); // bucket*z*y*x*3(coeffs)
        let coeffs_struct = Coeffs::from(&[coeffs[0], coeffs[1], coeffs[2]]);

        let view = RGBToSpectrumTable {
            z_nodes: Ptr::from(z_nodes.as_ptr()),
            coeffs: Ptr::from(&coeffs_struct),
            n_nodes: z_nodes.len() as u32,
        };

        Self {
            _z_nodes: z_nodes,
            _coeffs: coeffs,
            view,
        }
    }

    pub fn load(base_dir: &Path, name: &str) -> Result<Self> {
        let z_path = base_dir.join(format!("{}_znodes.dat", name));
        let c_path = base_dir.join(format!("{}_coeffs.dat", name));

        let z_nodes = read_float_file(&z_path.to_str().unwrap())?;
        let coeffs = read_float_file(&c_path.to_str().unwrap())?;

        Ok(Self::new(z_nodes, coeffs))
    }
}
