use super::input;
use babalcore::*;
use gdnative::prelude::*;

pub struct InputWrapper<'a> {
    obj: RefInstance<'a, input::Input, Shared>,
}

impl InputWrapper<'_> {
    pub fn new<'a>(instance: RefInstance<'a, input::Input, Shared>) -> InputWrapper<'a> {
        InputWrapper::<'a> { obj: instance }
    }

    pub fn from_variant<'a>(variant: &Variant) -> Result<InputWrapper<'a>, FromVariantError> {
        match variant.try_to_object_with_error::<Node>() {
            Ok(obj) => {
                let obj = unsafe { obj.assume_safe() };
                if let Some(inp) = obj.cast_instance::<input::Input>() {
                    Ok(Self::new(inp))
                } else {
                    Err(FromVariantError::CannotCast {
                        class: format_type_of(&obj),
                        to: "Input",
                    })
                }
            }
            Err(e) => Err(e),
        }
    }
}

impl InputQuery for InputWrapper<'_> {
    fn pop_jump(&mut self) -> bool {
        match self.obj.map_mut(|x, o| x.pop_jump(&o)) {
            Ok(v) => v,
            Err(e) => {
                godot_print!("unable to get input jump: {}", e);
                false
            }
        }
    }

    fn pop_steer(&mut self) -> f64 {
        match self.obj.map_mut(|x, o| x.pop_steer(&o)) {
            Ok(v) => v,
            Err(e) => {
                godot_print!("unable to get input steer: {}", e);
                0.0
            }
        }
    }
}
