use crate::fm_demod::Sample;

pub struct DcBlocker<I> {
    pub inner: I,
    pub x_prev: Sample,
    pub y_prev: Sample,
    pub alpha: f32,
}

impl<I> DcBlocker<I> {
    pub fn new(inner: I, alpha: f32) -> Self {
        Self {
            inner,
            x_prev: 0.0,
            y_prev: 0.0,
            alpha,
        }
    }

    pub fn process_sample(&mut self, x_n: Sample) -> Sample {
        let y_n = x_n - self.x_prev + self.alpha * self.y_prev;

        self.x_prev = x_n;
        self.y_prev = y_n;

        y_n
    }
}

impl<I, E> Iterator for DcBlocker<I>
where
    I: Iterator<Item = Result<Sample, E>>,
{
    type Item = Result<Sample, E>;

    fn next(&mut self) -> Option<Self::Item> {
        match self.inner.next()? {
            Ok(sample) => Some(Ok(self.process_sample(sample))),
            Err(e) => Some(Err(e)),
        }
    }
}
