use std::ops::Add;

pub struct Color {
    pub r: i32,
    pub g: i32,
    pub b: i32
}

impl Color {
    pub const BLACK: Color = Color { r: 0, g: 0, b: 0 };
    pub const RED: Color = Color { r: 255, g: 78, b: 78 };
    pub const ORANGE: Color = Color { r: 255, g: 158, b: 86 };
    pub const YELLOW: Color = Color { r: 255, g: 240, b: 86 };
    pub const LIGHTGREEN: Color = Color { r: 102, g: 255, b: 124 };
    pub const DARKGREEN: Color = Color { r: 27, g: 141, b: 43 };
    pub const MINT: Color = Color { r: 65, g: 255, b: 160 };
    pub const CYAN: Color = Color { r: 74, g: 255, b: 252 };
    pub const LIGHTBLUE: Color = Color { r: 88, g: 221, b: 255 };
    pub const SKYBLUE: Color = Color { r: 0, g: 169, b: 255 };
    pub const BLUE: Color = Color { r: 0, g: 91, b: 255 };
    pub const DARKBLUE: Color = Color { r: 0, g: 31, b: 255 };
    pub const DEEPPURPLE: Color = Color { r: 78, g: 0, b: 255 };
    pub const PURPLE: Color = Color { r: 123, g: 0, b: 255 };
    pub const VIOLET: Color = Color { r: 172, g: 108, b: 255 };
    pub const MAGENTA: Color = Color { r: 213, g: 0, b: 255 };
    pub const WARMPINK: Color = Color { r: 255, g: 0, b: 255 };
    pub const WATERMELON: Color = Color { r: 255, g: 113, b: 166 };
    pub const LIGHTGRAY: Color = Color { r: 153, g: 153, b: 153 };
    pub const DARKGRAY: Color = Color { r: 91, g: 91, b: 91 };
}

impl Add<&str> for Color {
    type Output = String;

    fn add(self, rhs: &str) -> Self::Output{
        format!("\x1B[38;2{};{};{}m{}{}", self.r, self.g, self.b, rhs, "\x1B[0m")
    }
}

pub fn color(text: &'static str, clr: Color) -> String{
    return clr + text;
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        println!("{}", color("rood", Color {255, 255, 255}));
    }
}
