use imgui::Key;


#[derive(Clone, Copy)]
pub struct Keypad {
    keys: [bool; 0x10],
}

impl Keypad {
    pub fn format_as_string(&self) -> String {
        let mut return_value = String::new();
        // draw a 4x4 grid showing the keys with * filling the cells that are depressed
        let keys = [
            [0x1, 0x2, 0x3, 0xc],[0x4, 0x5, 0x6, 0xd],[0x7, 0x8, 0x9, 0xe],[0xa, 0x0, 0xb, 0xf]
        ];

        for row in keys.iter() {
            for (index, key) in row.iter().enumerate() {
                let is_lit = if self.keys[*key] { "*".to_string() } else { char::from_digit(*key as u32, 16).unwrap_or(' ').to_string() };
                match index {
                    3 => {
                        // last in col
                        return_value += format!("|{}|\n", is_lit).as_str();
                    }
                    _=> {
                        return_value += format!("|{}", is_lit).as_str();
                    }
                }
            }
        }

        return_value
    }
}

impl Default for Keypad {
    fn default() -> Self {
        Keypad {
            keys: [ false; 16]
        }
    }
}

impl Keypad {
    pub fn push_key(&mut self, key_index: u8) {
        self.keys[key_index as usize] = true;
    }

    pub fn release_key(&mut self, key_index: u8) {
        self.keys[key_index as usize] = false;
    }

    pub fn key_state(&self, key_index: u8) -> bool {
        self.keys[key_index as usize]
    }

    pub fn new() -> Keypad {
        Keypad::default()
    }

    pub fn pressed(&self, key: u8) -> bool {
        self.key_state(key)
    }
    pub fn released(&self, key: u8) -> bool {
        !self.key_state(key)
    }
}

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

    #[test]
    fn smoke() { assert!(true) }

    #[test]
    fn keys_check() {
        let mut k = Keypad::new();

        for i in 0..16 {
            assert!(!k.key_state(i));
        }

        // press a key
        k.push_key(1);
        k.push_key(2);
        assert!(k.pressed(1));
        assert!(k.pressed(2));
        k.release_key(1);
        assert!(k.released(1));
    }
}