use std::ops::Deref;

use crate::{camera::Camera, prelude::*, scene::Scene};

pub trait ClassicalRenderer<R: Rng, S: Scene<R>, C: Camera<R>> {
    fn render_pixel(&self, scene: &S, camera: &C, x: u32, y: u32, rng: &mut R) -> Color;
    fn width(&self) -> u32;
    fn height(&self) -> u32;
}

impl<R: Rng, S: Scene<R>, C: Camera<R>, T: ClassicalRenderer<R, S, C> + ?Sized>
    ClassicalRenderer<R, S, C> for Box<T>
{
    fn render_pixel(&self, scene: &S, camera: &C, x: u32, y: u32, rng: &mut R) -> Color {
        self.deref().render_pixel(scene, camera, x, y, rng)
    }

    fn width(&self) -> u32 {
        self.deref().width()
    }

    fn height(&self) -> u32 {
        self.deref().height()
    }
}
