# -*- coding: utf-8 -*-
"""
:mod:`pambox.inner` regroups processes of the inner ear.
"""
from __future__ import absolute_import, division, print_function

import numpy as np
from numpy import exp, sin, cos, sqrt, abs, ones, pi
import scipy as sp
import scipy.signal as ss

from .utils import next_pow_2, hilbert


try:
    _ = np.use_fastnumpy  # Use Enthought MKL optimizations
    from numpy.fft import fft, ifft, rfft, irfft
except AttributeError:
    try:
        import mklfft  # MKL FFT optimizations from Continuum Analytics
        from numpy.fft import fft, ifft, rfft, irfft
    except ImportError:
        # Finally, just use Numpy's and Scipy's
        from scipy.fftpack import fft, ifft
        from numpy.fft import rfft, irfft


CENTER_F = np.asarray([63, 80, 100, 125, 160, 200, 250, 315, 400, 500,
                       630, 800, 1000, 1250, 1600, 2000, 2500, 3150, 4000,
                       5000, 6300, 8000])
FS = np.asarray([22050.])


def erb_bandwidth(fc):
    """Bandwitdh of an Equivalent Rectangular Bandwidth (ERB).

    Parameters
    ----------
    fc : ndarray
        Center frequency, or center frequencies, of the filter.

    Returns
    -------
    ndarray or float
        Equivalent rectangular bandwidth of the filter(s).
    """
    # In Hz, according to Glasberg and Moore (1990)
    return 24.7 + fc / 9.265


def lowpass_env_filtering(x, cutoff=150., n=1, fs=22050):
    """Low-pass filters a signal using a Butterworth filter.

    Parameters
    ----------
    x : ndarray
    cutoff : float, optional
        Cut-off frequency of the low-pass filter, in Hz. The default is 150 Hz.
    n : int, optional
        Order of the low-pass filter. The default is 1.
    fs : float, optional
        Sampling frequency of the signal to filter. The default is 22050 Hz.

    Returns
    -------
    ndarray
        Low-pass filtered signal.

    """

    b, a = sp.signal.butter(N=n, Wn=cutoff * 2. / fs, btype='lowpass')
    return sp.signal.lfilter(b, a, x)


class GammatoneFilterbank(object):

    def __init__(self, fs, cf, b=1.019, order=1, q=9.26449, min_bw=24.7):
        """Gammatone Filterbank

        Parameters
        ----------
        fs : float
            Sampling frequency of the signals to filter.
        cf : array_like
            Center frequencies of the filterbank.
        b : float
            beta of the gammatone filters. The default is `b` = 1.019.
        order : int
            Order. The default value is 1.
        q : float
            Q-value of the ERB. The default value is 9.26449.
        min_bw : float
            Minimum bandwidth of an ERB.

        References
        ----------

        """

        self.fs = fs
        try:
            len(cf)
        except TypeError:
            cf = [cf]
        self.cf = np.asarray(cf)
        self.b = b
        self.erb_order = order
        self.q = q
        self.min_bw = min_bw


    def _calculate_coefficients(self):
        cf = self.cf
        b = self.b
        order = self.erb_order
        q = self.q
        min_bw = self.min_bw

        erb = ((cf / q) ** order + min_bw ** order) ** (1 / order)
        t = 1 / self.fs
        b = b * 2 * pi * erb
        a0 = t
        a2 = 0
        b0 = 1
        b1 = -2 * cos(2 * cf * pi * t) / exp(b * t)
        b2 = exp(-2 * b * t)
        a11 = -(2 * t * cos(2 * cf * pi * t) / exp(b * t) + 2 * sqrt(
            3 + 2 ** 1.5) * t * sin(2 * cf * pi * t) / exp(b * t)) / 2
        a12 = -(2 * t * cos(2 * cf * pi * t) / exp(b * t) - 2 * sqrt(
            3 + 2 ** 1.5) * t * sin(2 * cf * pi * t) / exp(b * t)) / 2