use crate::components::ComponentTrait;
use super::{components::Component, config::Config, error::CustomError};
use image::{ImageBuffer, Rgba, RgbaImage};
use std::error::Error;
pub struct Image<'a> {
config: Option<Config>,
image_buffer: Option<ImageBuffer<Rgba<u8>, Vec<u8>>>,
components: Option<Vec<&'a Component>>,
}
impl<'a> Image<'a> {
pub fn new() -> Self {
Self {
config: None,
image_buffer: None,
components: None,
}
}
pub fn config(&mut self, config: Config) -> &mut Self {
self.config = Some(config);
self
}
pub fn init(&mut self) -> Result<&mut Self, Box<dyn Error>> {
if let Some(config) = self.config.to_owned() {
let mut image_buffer = RgbaImage::new(config.width, config.height);
for y in 0..config.height {
for x in 0..config.width {
image_buffer.put_pixel(x, y, config.color);
}
}
if let Some(border_color) = config.border {
for x in 0..config.width {
image_buffer.put_pixel(x, 0, border_color);
image_buffer.put_pixel(x, config.height - 1, border_color)
}
for y in 0..config.height {
image_buffer.put_pixel(0, y, border_color);
image_buffer.put_pixel(config.width - 1, y, border_color)
}
}
self.image_buffer = Some(image_buffer);
Ok(self)
} else {
Err(Box::new(CustomError::NoConfigProvided))
}
}
pub fn add_component(&mut self, component: &'a Component) -> &mut Self {
if let Some(components) = &mut self.components {
components.push(component);
} else {
self.components = Some(vec![component]);
}
self
}
pub fn add_components(&mut self, components: Vec<&'a Component>) -> &mut Self {
if let Some(components_list) = &mut self.components {
components_list.extend(components);
} else {
self.components = Some(components);
}
self
}
pub fn draw(&self) -> Result<(), Box<dyn Error>> {
if let Some(components) = &self.components {
if let Some(config) = &self.config {
if let Some(buffer) = self.image_buffer.to_owned().as_mut() {
for component in components {
let c = component;
c.draw(config.to_owned(), buffer)?;
}
buffer.save(config.path)?;
Ok(())
} else {
Err(Box::new(CustomError::NoConfigProvided))
}
} else {
Err(Box::new(CustomError::NoConfigProvided))
}
} else {
Err(Box::new(CustomError::ThereIsNoComponent))
}
}
}