organicomplex 0.7.0

Interactive complex-valued cellular automaton on 2D and 3D grids in search of that stuff - emergence, open-endedness, organicity etc.
use core::slice::ChunksMut;

use crate::{
    base::{
	    ARGB,
	    RGB
    },
    fontset::Font
};

use super::{
    System,
    video::{
        self,
        Image
    }
};

const ERR_DRAW_LOCKED: &str = "draw locked";

impl System {
    pub fn width(&self) -> i32 {
        self.video.width()
    }

    pub fn height(&self) -> i32 {
        self.video.height()
    }

	pub fn make_text_image(font: &Font, text: impl ToString, wrap: i32, color: RGB) -> Result<Image, String> {
		let text = text.to_string();
        video::System::make_text_image(font, text, wrap, color)
    }

	pub fn clear_screen(&mut self) -> Result<(), String> {
		if !self.draw_locked {
			self.video.clear();
            Ok(())
		} else {
			Err(String::from(ERR_DRAW_LOCKED))
		}
	}

    #[allow(dead_code)]
    pub fn draw_pixel(&mut self, x: i32, y: i32, color: ARGB) -> Result<(), String> {
        if !self.draw_locked {
			let (x, y) = (x + (self.width() >> 1), y + (self.height() >> 1));
            self.video.draw_pixel(x, y, color)
        } else {
            Err(String::from(ERR_DRAW_LOCKED))
        }
    }

    #[allow(dead_code)]
    pub fn draw_pixel_opaque(&mut self, x: i32, y: i32, color: RGB) -> Result<(), String> {
        if !self.draw_locked {
			let (x, y) = (x + (self.width() >> 1), y + (self.height() >> 1));
            self.video.draw_pixel_opaque(x, y, color)
        } else {
            Err(String::from(ERR_DRAW_LOCKED))
        }
    }

    #[allow(dead_code)]
    pub fn draw_line(&mut self, x1: i32, y1: i32, x2: i32, y2: i32, color: ARGB) -> Result<(), String> {
        if !self.draw_locked {
			let (x1, y1) = (x1 + (self.width() >> 1), y1 + (self.height() >> 1));
			let (x2, y2) = (x2 + (self.width() >> 1), y2 + (self.height() >> 1));
            self.video.draw_line(x1, y1, x2, y2, color)
        } else {
            Err(String::from(ERR_DRAW_LOCKED))
        }
    }

    #[allow(dead_code)]
    pub fn draw_rect(&mut self, x1: i32, y1: i32, x2: i32, y2: i32, color: ARGB, fill: bool) -> Result<(), String> {
        if !self.draw_locked {
			let (x1, y1) = (x1 + (self.width() >> 1), y1 + (self.height() >> 1));
			let (x2, y2) = (x2 + (self.width() >> 1), y2 + (self.height() >> 1));
            self.video.draw_rect(x1, y1, x2, y2, color, fill)
        } else {
            Err(String::from(ERR_DRAW_LOCKED))
        }
    }

    #[allow(dead_code)]
    pub fn draw_rect_size(&mut self, x1: i32, y1: i32, xsize: i32, ysize: i32, color: ARGB, fill: bool) -> Result<(), String> {
        self.draw_rect(x1, y1, x1 + xsize - 1, y1 + ysize - 1, color, fill)
    }

    #[allow(dead_code)]
    pub fn draw_image(&mut self, img: &Image, x: i32, y: i32) -> Result<(), String> {
        if !self.draw_locked {
            self.video.draw_image(img, x + (self.width() >> 1), y + (self.height() >> 1));
            Ok(())
        } else {
            Err(String::from(ERR_DRAW_LOCKED))
        }
    }

	pub fn shade(&mut self, shade: u8) -> Result<(), String> {
		if !self.draw_locked {
			self.video.shade(shade)
		} else {
			Err(String::from(ERR_DRAW_LOCKED))
		}
	}

    #[allow(dead_code)]
	pub fn draw_frame(&mut self,
		x: i32, y: i32, width: i32, height: i32, // interior rectangle
		color_int: ARGB, color_ext: ARGB, // internal and external edge color
		thickness_binlog: i32) -> Result<(), String> {
		if !self.draw_locked {
			let (x, y) = (x + (self.width() >> 1), y + (self.height() >> 1));
			self.video.draw_frame(x, y, width, height, color_int, color_ext, thickness_binlog)
		} else {
			Err(String::from(ERR_DRAW_LOCKED))
		}
	}

    #[allow(dead_code)]
    pub fn draw_text_image(&mut self, txt_img: &Image, shade: u8, margin: i32, x: i32, y: i32) -> Result<(), String> {
        if !self.draw_locked {
			let (x, y) = (x + (self.width() >> 1), y + (self.height() >> 1));
            self.video.draw_text_image(txt_img, shade, margin, x, y);
			Ok(())
        } else {
            Err(String::from(ERR_DRAW_LOCKED))
        }
    }

    /// Slow to do it every frame.
    /// Prepare image with make_text_image() once and draw it with draw_text_image() every frame...
    pub fn draw_text(&mut self, font: &Font, text: impl ToString, wrap: i32, color: RGB, shade: u8, margin: i32, x: i32, y: i32) -> Result<(), String> {
        if !self.draw_locked {
			let text = text.to_string();
			let (x, y) = (x + (self.width() >> 1), y + (self.height() >> 1));
            self.video.draw_text(font, text, wrap, color, shade, margin, x, y);
			Ok(())
        } else {
            Err(String::from(ERR_DRAW_LOCKED))
        }
    }

    #[allow(dead_code)]
	pub fn screen_raw_mut(&mut self) -> &mut [u8] {
		self.video.screen_raw_mut()
	}

    #[allow(dead_code)]
	pub fn screen_raw_chunks_mut(&mut self, pixels_per_chunk: i32) -> ChunksMut<'_, u8> {
        self.video.screen_raw_chunks_mut(pixels_per_chunk)
	}

    pub fn draw_locked(&self) -> bool {
        self.draw_locked
    }

}