// Utilities for impulse response design

use crate::complex::Complex32;

pub mod design
{
    use crate::fft::FFT;
    use crate::windows::{self, Window};
    use crate::complex::Complex32;

    ///Designs a impulse response from a desired transfer function using windowing technique
    pub fn ir_from_transfer_function(transfer_function: &[Complex32], ir_length: usize, window: Window) -> Vec<Complex32>
    {
        let tf_len = transfer_function.len();
        let mut ifft = FFT::new_inv(tf_len);
        
        // Compute ideal convolution kernel/impulse response
        ifft.execute(transfer_function);

        // Shorten and window
        let mut ir = vec![];

        for i in 0..ir_length
        {
            // Get value within ifft result (centering/trimming)
            let k = (tf_len - (ir_length / 2) + i) % tf_len;
            // Windowing
            ir.push(
                ifft.get_output()[k] * window(i as f32 / ir_length as f32) / tf_len as f32
            );
        }

        ir
    }

    pub fn frequency_response(impulse_response: &[Complex32]) -> Vec<Complex32>
    {
        let len = impulse_response.len();
        let mut fft = FFT::new(len, windows::rectangular);
        // Recenter impulse response
        let mut centered_ir = vec![]; 
        for i in 0..len
        {
            let k = (len / 2) + i;
            centered_ir.push(impulse_response[k % len]);
        }

        fft.execute(&centered_ir);
        Vec::from(fft.get_output())
    }
}
