"""
1D stationary wavelet transform.
"""
import numpy as np
import pywt

class swt1:
    
    def __init__(self, wavelet='db1', level=1, start_level=0, frequency_decreasing_path=False):
        self._wavelet = wavelet
        self._level = level
        self._start_level = start_level
        self._frequency_decreasing_path = frequency_decreasing_path
        
    def apply_filter(self, img, meta=None):
        return _swt1(img, meta, self._wavelet, self._level, self._start_level, self._frequency_decreasing_path)


def _swt1(signal, meta, wavelet, level=1, start_level=0, frequency_decreasing_path=False):
    """
    @param signal	The input signal.
    @param wavelet	The wavelet type.
    @param meta		Optional meta data.
    """

    tf = pywt.swt(signal, pywt.Wavelet(wavelet), level=level, start_level=start_level)

    """
    tf = [(cAn, cDn), ..., (cA2, cD2), (cA1, cD1)]
    """

    """
    Get the maximum scale to propagate.
    """
    if meta is not None and 'scale' in meta:
        # We get the scale from the previous filter.
        max_scale = meta['scale']
    else:
        # The previous filter was not polite enouth to provide us with that information.
        max_scale = len(tf)

    prop = []
    out = []
    new_meta = []

    for (cA, cD), scale in zip(tf, range(len(tf), 0, -1)):
        # scale takes values in: len(tf), ..., 3,2,1
        
        if not frequency_decreasing_path or scale <= max_scale:
            prop.append(cD)
            m = {'scale': scale}
            new_meta.append(m)
        
    out = [cA] # output approximate of last level

    return {'prop': prop, 'out': out, 'meta': new_meta}

