use super::{Action, ActionError};
use uinput::event::keyboard::Key;
pub struct UinputAction {
    pub device: std::rc::Rc<std::cell::RefCell<uinput::Device>>,
    pub modifiers: Vec<Key>,
    pub sequence: Vec<Key>,
}
impl UinputAction {
    pub fn default_device() -> std::rc::Rc<std::cell::RefCell<uinput::Device>> {
        let device = uinput::open("/dev/uinput")
            .unwrap()
            .name("wzmach_virtual")
            .unwrap()
            .event(uinput::event::Keyboard::All)
            .unwrap()
            .create()
            .unwrap();
        log::debug!("Created uinput device");
        std::rc::Rc::new(std::cell::RefCell::new(device))
    }
}
impl Action for UinputAction {
    fn execute(&mut self) -> Result<(), ActionError> {
        let mut device = self.device.borrow_mut();
        log::debug!("Execute action {:?} + {:?}", self.modifiers, self.sequence);
        for modifier in &self.modifiers {
            device.press(modifier)?;
        }
        for key in &self.sequence {
            device.click(key)?;
        }
        for modifier in self.modifiers.iter().rev() {
            device.release(modifier)?;
        }
        device.synchronize()?;
        Ok(())
    }
}
impl From<uinput::Error> for ActionError {
    fn from(err: uinput::Error) -> ActionError {
        ActionError(format!("{}", err))
    }
}