"""This module contains classes of graphoelements.

These graphoelements can be generated by the package "detect".

"""
from copy import deepcopy

from numpy import empty, asarray, sum, mean

from .datatype import Data


class Ripple:
    def __init__(self):
        pass


class SlowWave:
    def __init__(self):
        pass


class Spindles:
    """Class containing all the spindles in one dataset.

    Attributes
    ----------
    chan_name : ndarray (dtype='U')
        list of channels
    mean : ndarray (dtype='float')
        mean of each channel
    std : ndarray (dtype='float')
        standard deviation of each channel
    det_value : ndarray (dtype='float')
        value used for detection for each channel
    sel_value : ndarray (dtype='float')
        value used for selection for each channel
    spindle : list of dict
        list of spindles, where each spindle contains:
            - start_time : float
                start time of the spindle
            - end_time : float
                end time of the spindle
            - peak_time : float
                time of the highest value
            - peak_val : float
                the highest value
            - chan': str
                channel label

    """
    def __init__(self):
        self.chan_name = None
        self.mean = None
        self.std = None
        self.det_value = None
        self.sel_value = None

        self.spindle = []
        one_spindle = {'start_time': None,
                       'end_time': None,
                       'chan': [],
                       'peak_val': None,
                       'peak_time': None,
                       }
        self.spindle.append(one_spindle)

    def __iter__(self):
        for one_spindle in self.spindle:
            yield one_spindle

    def __call__(self, func=None):

        spindles = []
        for one_sp in self.spindle:
            if func(one_sp):
                spindles.append(one_sp)

        output = deepcopy(self)
        output.spindle = spindles

        return output

    def to_data(self, parameter, operator=mean):

        data = Data()
        data.axis = {'chan': empty(1, dtype='O')}
        data.axis['chan'][0] = self.chan_name
        data.data = empty(1, dtype='O')

        values = []
        for one_chan in self.chan_name:
            if parameter == 'count':
                value = sum(1 for x in self.spindle if x['chan'] == one_chan)
            else:
                value = operator([x[parameter] for x in self.spindle
                                  if x['chan'] == one_chan])
            values.append(value)

        data.data[0] = asarray(values)
        return data
