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

use crate::filters::FilterError;

#[derive(Debug, PartialEq, Clone)]
pub enum FilterType {
    Bessel {
        order: usize,
        cutoff: Vec<f64>,
        band: FilterBand,
        analog: bool,
        criterion: BesselCriterion,
        fs: Option<f64>,
    },
    Butterworth {
        order: usize,
        cutoff: Vec<f64>,
        band: FilterBand,
        analog: bool,
        fs: Option<f64>,
    },
    ChebyshevType1 {
        order: usize,
        cutoff: Vec<f64>,
        band: FilterBand,
        analog: bool,
        fs: Option<f64>,
        rp: f64,
    },
    ChebyshevType2 {
        order: usize,
        cutoff: Vec<f64>,
        band: FilterBand,
        analog: bool,
        fs: Option<f64>,
        rs: f64,
    },
    Gauss1d {
        fs: f64,
        cutoff: f64,
        truncate: f64, 
        radius: Option<usize>
    }
}


/// 滤波模式
///
/// # 参数
///
/// - `LowPass`：低通滤波器
/// - `HighPass`: 高通滤波器
/// - `BandPass`: 带通滤波器
/// - `BandStop`: 带阻滤波器
///
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum FilterBand {
    LowPass,
    HighPass,
    BandPass,
    BandStop
}

#[derive(Debug, PartialEq, Clone, Copy)]
pub enum BesselCriterion {
    Delay,
    Phase,
    Mag
}
pub trait FilterApply<T> where
    T: Float + FromPrimitive + Zero + Clone + One,
{
    fn apply(&self, data: &Vec<T>) -> Result<Vec<T>, FilterError>;
    fn apply_inplase(&self, data: &mut Vec<T>) -> Result<(), FilterError>;
}

pub trait Factory<T> where
    T: Float + FromPrimitive + Clone + Zero + One + 'static,
{
    fn create(&self, ftype: FilterType,) -> Result<Box<dyn FilterApply<T>>, FilterError>;
}