
use crate::data::descriptors::ImageFrameProperties;
use crate::data::ImageFrame;
use crate::FeagiDataError;
use crate::genomic::CorticalID;
use crate::genomic::descriptors::CorticalChannelIndex;
use crate::neurons::xyzp::{CorticalMappedXYZPNeuronData, NeuronVoxelXYZPEncoder};
use crate::wrapped_io_data::{WrappedIOData, WrappedIOType};

pub struct ImageFrameNeuronVoxelXYZPEncoder {
    image_properties: ImageFrameProperties,
    cortical_write_target: CorticalID
}

impl NeuronVoxelXYZPEncoder for ImageFrameNeuronVoxelXYZPEncoder {

    fn get_encodable_data_type(&self) -> WrappedIOType {
        WrappedIOType::ImageFrame(Some(self.image_properties))
    }

    fn write_neuron_data_single_channel(&self, wrapped_value: &WrappedIOData, cortical_channel: CorticalChannelIndex, write_target: &mut CorticalMappedXYZPNeuronData) -> Result<(), FeagiDataError> {
        // We are not doing any sort of verification checks here, other than ensuring data types
        let image: &ImageFrame = wrapped_value.try_into()?;
        if image.skip_encoding {
            _ = write_target.ensure_clear_and_borrow_mut(&self.cortical_write_target, image.get_number_elements());
            return Ok(());
        }
        image.write_as_neuron_xyzp_data(write_target, self.cortical_write_target, cortical_channel)?;
        Ok(())
    }
}

impl ImageFrameNeuronVoxelXYZPEncoder {
    pub fn new(cortical_write_target: CorticalID, image_properties: &ImageFrameProperties) -> Result<Self, FeagiDataError> {        
        Ok(ImageFrameNeuronVoxelXYZPEncoder{
            image_properties: image_properties.clone(),
            cortical_write_target
        })
    }
}