#[derive(Clone, Copy)]
pub struct Switch<const T: u8> {
    status: u8,
}

enum Masks {
    LAST = 0x80,
    STATE = 0x40,
    COUNTER = 0x3F,
}

impl<const T: u8> Switch<T> {
    pub const fn new() -> Self {
        Self { status: 0 }
    }
    pub fn set(&mut self, down: bool) {
        if self.status & Masks::COUNTER as u8 != 0 {
            self.status += 1;
        } else if ((self.status & Masks::STATE as u8) != 0) != down {
            #[cfg(feature = "ps2")]
            {
                self.status <<= 1; //save old state
            }
            self.status |= u8::from(down) << 6; //set new state
            self.status += 1;
        }
        if self.status & Masks::COUNTER as u8 == T {
            self.status &= !(Masks::COUNTER as u8); //clear counter
        }
    }
    pub const fn is_down(self) -> bool {
        self.status & Masks::STATE as u8 != 0
    }
    #[cfg(feature = "ps2")]
    pub const fn changed(self) -> bool {
        self.status & Masks::STATE as u8 != self.status & Masks::LAST as u8
    }
}
