use crate::Float;
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext};
use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr;

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct GPUFloatScaledTexture {
    pub tex: Ptr<GPUFloatTexture>,
    pub scale: Ptr<GPUFloatTexture>,
}

impl GPUFloatScaledTexture {
    pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
        let sc = self.scale.get().map(|t| t.evaluate(ctx)).unwrap();
        if sc == 0. {
            return 0.;
        }
        self.tex.get().map(|t| t.evaluate(ctx)).unwrap_or(0.0) * sc
    }
}

#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct GPUSpectrumScaledTexture {
    pub tex: Ptr<GPUSpectrumTexture>,
    pub scale: Ptr<GPUFloatTexture>,
}

impl GPUSpectrumScaledTexture {
    pub fn evaluate(
        &self,
        ctx: &TextureEvalContext,
        lambda: &SampledWavelengths,
    ) -> SampledSpectrum {
        let sc = self.scale.get().map(|t| t.evaluate(ctx)).unwrap_or(0.);

        self.tex
            .get()
            .map(|t| t.evaluate(ctx, lambda))
            .unwrap_or(SampledSpectrum::new(0.))
            * sc
    }
}
