use super::input_query::*;
use std::collections::VecDeque;

/// A fake input used for tests, to simulate user inputs.
#[derive(Debug, Default)]
pub struct FakeInput {
    jumps: isize,
    steers: VecDeque<f64>,
}

impl FakeInput {
    /// New fake input.
    ///
    /// # Examples
    ///
    /// ```
    /// use babalcore::*;
    ///
    /// let _fake_input = FakeInput::new();
    /// ```
    pub fn new() -> FakeInput {
        FakeInput::default()
    }

    /// Push a new jump request.
    ///
    /// # Examples
    ///
    /// ```
    /// use babalcore::*;
    ///
    /// let mut fake_input = FakeInput::new();
    /// fake_input.push_jump();
    /// ```
    pub fn push_jump(&mut self) {
        self.jumps += 1;
    }

    /// Push a new steer command.
    ///
    /// # Examples
    ///
    /// ```
    /// use babalcore::*;
    ///
    /// let mut fake_input = FakeInput::new();
    /// fake_input.push_steer(0.1);
    /// fake_input.push_steer(-100.0);
    /// ```
    pub fn push_steer(&mut self, steer: f64) {
        self.steers.push_back(steer);
    }
}

impl InputQuery for FakeInput {
    /// Test whether a push request has been pushed.
    ///
    /// # Examples
    ///
    /// ```
    /// use babalcore::*;
    ///
    /// let mut fake_input = FakeInput::new();
    /// assert!(!fake_input.pop_jump());
    /// fake_input.push_jump();
    /// assert!(fake_input.pop_jump());
    /// assert!(!fake_input.pop_jump());
    /// ```
    fn pop_jump(&mut self) -> bool {
        if self.jumps > 0 {
            self.jumps -= 1;
            return true;
        }
        false
    }

    /// Pop steer commands.
    ///
    /// # Examples
    ///
    /// ```
    /// use babalcore::*;
    ///
    /// let mut fake_input = FakeInput::new();
    /// assert_eq!(0.0, fake_input.pop_steer());
    /// fake_input.push_steer(1.0);
    /// fake_input.push_steer(-3.0);
    /// assert_eq!(1.0, fake_input.pop_steer());
    /// assert_eq!(-3.0, fake_input.pop_steer());
    /// assert_eq!(0.0, fake_input.pop_steer());
    /// ```
    fn pop_steer(&mut self) -> f64 {
        match self.steers.pop_front() {
            Some(f) => f,
            None => 0.0,
        }
    }
}
