use crate::{MouseDevice, Result, colour::Rgb, error::MouseError, mouse::packet::MousePacket};
pub const COLOUR_PACKET_HEADER: [u8; 4] = [0x00, 0x0a, 0x00, 0x0f];
#[derive(Debug, Clone)]
pub struct ColourPacket {
colours: Vec<Rgb>,
zones: usize,
}
impl MousePacket for ColourPacket {
fn serialize(&self) -> Result<Vec<u8>> {
let mut buffer = Vec::with_capacity(4 + (self.zones * 3));
buffer.extend_from_slice(&COLOUR_PACKET_HEADER);
for zone in self.colours.iter().take(self.zones) {
buffer.push(zone.r);
buffer.push(zone.g);
buffer.push(zone.b);
}
Ok(buffer)
}
}
impl ColourPacket {
pub fn new(device_type: MouseDevice) -> Self {
Self {
zones: device_type.get_zones(),
colours: vec![Rgb::new(255, 255, 255); device_type.get_zones()],
}
}
pub fn with_colours(device_type: MouseDevice, colours: Vec<Rgb>) -> Self {
let zones = match device_type {
MouseDevice::None => 0,
MouseDevice::Rival3 => 4,
};
let mut colours_safe = colours;
colours_safe.resize(zones, Rgb::new(255, 255, 255));
Self {
zones,
colours: colours_safe,
}
}
pub fn get_colours(&self) -> Vec<Rgb> {
self.colours.clone()
}
pub fn get_zone(&self, index: usize) -> Result<Rgb> {
if index >= self.zones {
return Err(MouseError::ZoneOutOfRange.into());
}
self.colours
.get(index)
.cloned()
.ok_or_else(|| MouseError::ZoneOutOfRange.into())
}
pub fn change_zone(&mut self, index: usize, colour: Rgb) -> Result<()> {
if index >= self.zones {
return Err(MouseError::ZoneOutOfRange.into());
}
if let Some(value) = self.colours.get_mut(index) {
*value = colour;
Ok(())
} else {
Err(MouseError::ZoneOutOfRange.into())
}
}
}