use crate::tetromino::TetrominoType;
use sdl2::{
    pixels::Color,
    render::{Canvas, RenderTarget},
};
use std::fmt;

pub mod standard_renderer;

pub const CELL_SIZE: u32 = 32;
pub const BORDER_RADIUS: u32 = 1;
pub const UI_PADDING: u32 = 8;

pub static COLOR_BACKGROUND: Color = Color::RGB(60, 60, 60);
pub static COLOR_CYAN: Color = Color::RGB(0, 255, 255);
pub static COLOR_YELLOW: Color = Color::RGB(255, 255, 0);
pub static COLOR_PURPLE: Color = Color::RGB(255, 0, 255);
pub static COLOR_GREEN: Color = Color::RGB(0, 255, 0);
pub static COLOR_RED: Color = Color::RGB(255, 0, 0);
pub static COLOR_BLUE: Color = Color::RGB(0, 0, 255);
pub static COLOR_ORANGE: Color = Color::RGB(255, 127, 0);
pub static COLOR_GRAY: Color = Color::RGB(100, 100, 100);

pub trait Renderable {
    fn width(&self) -> usize;
    fn height(&self) -> usize;
    fn render<R: RenderTarget>(&self, canvas: &mut Canvas<R>) -> Result<(), String>;
}

#[derive(Copy, Clone)]
pub enum MinoColor {
    Cyan,
    Yellow,
    Purple,
    Green,
    Red,
    Blue,
    Orange,
    Gray,
}

impl fmt::Debug for MinoColor {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "{}",
            match self {
                Self::Cyan => "c",
                Self::Yellow => "y",
                Self::Purple => "p",
                Self::Green => "g",
                Self::Red => "r",
                Self::Blue => "b",
                Self::Orange => "o",
                Self::Gray => "x",
            }
        )
    }
}

impl Into<Color> for MinoColor {
    fn into(self) -> Color {
        match self {
            Self::Cyan => COLOR_CYAN,
            Self::Yellow => COLOR_YELLOW,
            Self::Purple => COLOR_PURPLE,
            Self::Green => COLOR_GREEN,
            Self::Red => COLOR_RED,
            Self::Blue => COLOR_BLUE,
            Self::Orange => COLOR_ORANGE,
            Self::Gray => COLOR_GRAY,
        }
    }
}

impl Into<Color> for TetrominoType {
    fn into(self) -> Color {
        Into::<MinoColor>::into(self).into()
    }
}

impl Into<Color> for &TetrominoType {
    fn into(self) -> Color {
        Into::<MinoColor>::into(*self).into()
    }
}
