use super::{Direction, TextAlignment};
pub enum ColorKind {
Fg,
Bg
}
pub const RESET: &str = "\x1b[0m";
pub const BLACK: &str = "\x1b[30m";
pub const RED: &str = "\x1b[31m";
pub const GREEN: &str = "\x1b[32m";
pub const YELLOW: &str = "\x1b[33m";
pub const BLUE: &str = "\x1b[34m";
pub const MAGENTA: &str = "\x1b[35m";
pub const CYAN: &str = "\x1b[36m";
pub const WHITE: &str = "\x1b[37m";
pub const BRIGHT_BLACK: &str = "\x1b[90m";
pub const BRIGHT_RED: &str = "\x1b[91m";
pub const BRIGHT_GREEN: &str = "\x1b[92m";
pub const BRIGHT_YELLOW: &str = "\x1b[93m";
pub const BRIGHT_BLUE: &str = "\x1b[94m";
pub const BRIGHT_MAGENTA: &str = "\x1b[95m";
pub const BRIGHT_CYAN: &str = "\x1b[96m";
pub const BRIGHT_WHITE: &str = "\x1b[97m";
pub const BLACK_BG: &str = "\x1b[40m";
pub const RED_BG: &str = "\x1b[41m";
pub const GREEN_BG: &str = "\x1b[42m";
pub const YELLOW_BG: &str = "\x1b[43m";
pub const BLUE_BG: &str = "\x1b[44m";
pub const MAGENTA_BG: &str = "\x1b[45m";
pub const CYAN_BG: &str = "\x1b[46m";
pub const WHITE_BG: &str = "\x1b[47m";
pub const BRIGHT_BLACK_BG: &str = "\x1b[100m";
pub const BRIGHT_RED_BG: &str = "\x1b[101m";
pub const BRIGHT_GREEN_BG: &str = "\x1b[102m";
pub const BRIGHT_YELLOW_BG: &str = "\x1b[103m";
pub const BRIGHT_BLUE_BG: &str = "\x1b[104m";
pub const BRIGHT_MAGENTA_BG: &str = "\x1b[105m";
pub const BRIGHT_CYAN_BG: &str = "\x1b[106m";
pub const BRIGHT_WHITE_BG: &str = "\x1b[107m";
fn distance(x1: isize, y1: isize, x2: isize, y2: isize) -> f64 {
let x = ((x2-x1).pow(2) + (y2-y1).pow(2)) as f64;
x.sqrt()
}
pub fn rgb_to_ccode(rgb: (u8, u8, u8), kind: ColorKind) -> String {
let (r, g, b) = rgb;
match kind {
ColorKind::Fg => format!("\x1b[38;2;{};{};{}m", r, g, b),
ColorKind::Bg => format!("\x1b[48;2;{};{};{}m", r, g, b)
}
}
pub fn pixel(x: isize, y: isize, c: char, ccode: &str) {
let tsize = super::size();
if x >= 0 && x < tsize.0 as isize && y >= 0 && y < tsize.1 as isize && ccode.starts_with('\x1b') {
super::cursorto(x as usize, y as usize);
print!("{}{}", ccode, c);
}
}
pub fn straight_line(mut x: isize, mut y: isize, mut length: isize, dir: Direction, c: char, ccode: &str) {
let mut addx: isize = 0;
let mut addy: isize = 0;
match dir {
Direction::Left => addx = -1,
Direction::Right => addx = 1,
Direction::Up => addy = -1,
Direction::Down => addy = 1
}
if length < 0 {
length = -length;
addx = -addx;
addy = -addy;
}
for _ in 0..length {
pixel(x, y, c, ccode);
x += addx;
y += addy;
}
}
pub fn rectangle(x: isize, y: isize, width: usize, height: usize, c: char, ccode: &str, fill: bool) {
let w = width as isize;
let h = height as isize;
if fill {
for i in 0..width {
straight_line(x+i as isize, y, height as isize, Direction::Down, c, ccode);
}
return;
}
straight_line(x, y, w, Direction::Right, c, ccode);
straight_line(x, y+h-1, w, Direction::Right, c, ccode);
straight_line(x, y+1, h-2, Direction::Down, c, ccode);
straight_line(x+w-1, y+1, h-2, Direction::Down, c, ccode);
}
pub fn line(x1: isize, y1: isize, x2: isize, y2: isize, c: char, ccode: &str) {
if x1 == x2 {
straight_line(x1, y1, y2-y1, Direction::Down, c, ccode);
}
if y1 == y2 {
straight_line(x1, y1, x2-x1, Direction::Right, c, ccode);
}
let dist = distance(x1, y1, x2, y2);
let dx = (x2-x1) as f64 / dist;
let dy = (y2-y1) as f64 / dist;
let mut x = x1 as f64;
let mut y = y1 as f64;
for _ in 0..dist.round() as isize {
pixel(x.round() as isize, y.round() as isize, c, ccode);
x += dx;
y += dy;
}
pixel(x2, y2, c, ccode);
}
pub fn ellipse(h: isize, k: isize, a: usize, b: usize, c: char, ccode: &str, fill: bool) {
for x in 0..a*2+1 {
let shiftx: isize = x as isize + h - a as isize;
let inside_y = ((a*a) as isize - (shiftx-h).pow(2)).abs() as f64;
let y: f64 = (b as f64) / (a as f64) * inside_y.sqrt() + k as f64;
if fill {
let ydist: isize = 2 * (k - y.round() as isize).abs();
straight_line(shiftx as isize, y.round() as isize, ydist+1, Direction::Up, c, ccode);
continue;
}
let ydist: isize = 2 * (k - y.round() as isize);
pixel(shiftx, y.round() as isize, c, ccode);
pixel(shiftx, (y.round() as isize + ydist) as isize, c, ccode);
}
}
pub fn text(x: isize, y: isize, text: &str, ccode: &str) {
for (i, c) in text.chars().enumerate() {
pixel(x+i as isize, y, c, ccode);
}
}
pub fn text_aligned(x: isize, y: isize, text: &str, align: TextAlignment, ccode: &str) {
let mut x = x;
match align {
TextAlignment::Left => {},
TextAlignment::Center => x -= text.len() as isize / 2,
TextAlignment::Right => x -= text.len() as isize
}
for (i, c) in text.chars().enumerate() {
pixel(x+i as isize, y, c, ccode);
}
}