use super::PixelFormat;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Color {
    pub r: u8,
    pub g: u8,
    pub b: u8,
    pub a: u8,
}

impl Color {
    pub const BLACK: Self = Self::from_rgb_u32(0x000000);
    pub const WHITE: Self = Self::from_rgb_u32(0xFFFFFF);
    pub const RED: Self = Self::from_rgb_u32(0xFF0000);

    #[inline]
    pub const fn from_rgba_u32(v: u32) -> Self {
        // 0x11223344 -> [0x44, 0x33, 0x22, 0x11]
        //                 a     b     g     r
        let x = v.to_le_bytes();
        Self {
            a: x[0],
            b: x[1],
            g: x[2],
            r: x[3],
        }
    }

    #[inline]
    pub const fn from_rgb_u32(v: u32) -> Self {
        let x = v.to_le_bytes();
        Self {
            a: u8::MAX,
            b: x[0],
            g: x[1],
            r: x[2],
        }
    }

    #[inline]
    pub const fn to_rgba_u32(self) -> u32 {
        u32::from_ne_bytes([self.r, self.g, self.b, self.a])
    }

    #[inline]
    pub const fn to_bgra_u32(self) -> u32 {
        u32::from_ne_bytes([self.b, self.g, self.r, self.a])
    }

    #[inline]
    pub const fn to_pixel_u32(self, format: PixelFormat) -> u32 {
        match format {
            PixelFormat::B8G8R8A8 => self.to_bgra_u32(),
            PixelFormat::R8G8B8A8 => self.to_rgba_u32(),
            _ => unimplemented!(),
        }
    }

    pub const fn rgb_mul(self, v: u8) -> Self {
        Self {
            a: self.a,
            r: self.r.saturating_mul(v),
            g: self.g.saturating_mul(v),
            b: self.b.saturating_mul(v),
        }
    }
    // pub fn rgb_mul_assign(&mut self, v: u8) {
    //     self.r = self.r.saturating_mul(v);
    //     self.g = self.g.saturating_mul(v);
    //     self.b = self.b.saturating_mul(v);
    // }
}
