use crate::prelude::*;
use std::fmt::Debug;

pub trait Light<R: Rng>: Send + Sync + Debug {
    fn emit(&self, w_in: Dir3, rng: &mut R) -> Color;
}

impl<R: Rng> Light<R> for &'_ dyn Light<R> {
    fn emit(&self, w_in: Dir3, rng: &mut R) -> Color {
        (*self).emit(w_in, rng)
    }
}

impl<R: Rng, L: Light<R>> Light<R> for &L {
    fn emit(&self, w_in: Dir3, rng: &mut R) -> Color {
        (*self).emit(w_in, rng)
    }
}

#[derive(Clone, Debug)]
pub struct AreaLight {
    pub(crate) color: Color,
}

impl AreaLight {
    pub fn new(color: Color) -> Self {
        Self { color }
    }
}

impl<R: Rng> Light<R> for AreaLight {
    fn emit(&self, w_in: Dir3, _rng: &mut R) -> Color {
        if w_in.y() > 0.0 {
            self.color
        } else {
            Color::black()
        }
    }
}
