use num_traits::{Float, FromPrimitive, One, Zero};

use crate::smooth::SmoothError;

pub fn rma<T>(data: &[T], period: usize) -> Result<Vec<T>, SmoothError> where 
    T: Float + FromPrimitive + Zero + Clone + One,
{
    let len = data.len();
    if period == 0 || len == 0 {
        return Err(SmoothError::RMAApplyError);
    }

    let alpha = T::from(1.0 / (period as f32)).unwrap();
    let half = period / 2;

    let mut extended = Vec::with_capacity(len + 2 * half);
    for _ in 0..half {
        extended.push(data[0]);
    }
    extended.extend_from_slice(data);
    for _ in 0..half {
        extended.push(data[len - 1]);
    }

    let mut result = Vec::with_capacity(extended.len());
    let mut rma = extended[0];
    result.push(rma);

    for &x in extended.iter().skip(1) {
        rma = (T::one() - alpha) * rma + alpha * x;
        result.push(rma);
    }

    let start = half;
    let end = start + len;
    Ok(result[start..end].to_vec())
}