from __future__ import print_function, division, unicode_literals
from __future__ import absolute_import

import numpy as np, matplotlib.pyplot as plt


class DataLogger(object):
    '''history of input data'''

    def __init__(self, Wtime, ConfDict, sigName):
        '''Args:  Wtime: waiting time between updates
        conf: PicoScope Configuration dictionary
        '''
        # collect relevant configuration parameters
        self.Npoints = 120  # number of points for history

        # get relevant settings from (PicoScope) ConfDict
        self.dT = Wtime / 1000.0  # time interval in s
        self.NChan = ConfDict['NChannels']

        self.ChanLim = []
        CRanges = ConfDict['CRanges']
        COffsets = ConfDict['ChanOffsets']
        for i in range(self.NChan):
            self.ChanLim.append((-CRanges[i] - COffsets[i], CRanges[i] - COffsets[i]))

        self.ChanNams = ConfDict['Channels']
        self.ChanColors = ConfDict['ChanColors']

        # data structures needed throughout the class
        self.Ti = self.dT * np.linspace(-self.Npoints + 1, 0, self.Npoints)
        self.Vhist = np.zeros([self.NChan, self.Npoints])

        # set up a figure to plot actual voltage and samplings from Picoscope
        fig = plt.figure("DataLogger", figsize=(6.0, 3.0))
        fig.subplots_adjust(left=0.15, bottom=0.2, right=0.85, top=0.95, wspace=None, hspace=0.25)
        axes = []
        # history plot
        axes.append(fig.add_subplot(1, 1, 1, facecolor='ivory'))
        if self.NChan > 1:
            axes.append(axes[0].twinx())
        for i, C in enumerate(self.ChanNams):
            if i > 1:
                break  # works for a maximum of 2 Channels only
            axes[i].set_ylim(*self.ChanLim[i])
            axes[i].set_ylabel('Chan ' + C + ' ' + sigName, color=self.ChanColors[i])
            axes[i].grid(True, color=self.ChanColors[i], linestyle='--', alpha=0.3)
        axes[0].set_xlabel('History (s)')

        self.fig = fig
        self.axes = axes

    # -- end def __init__

    def init(self):
        # initialize objects to be animated

        # history graphs
        self.graphs = ()
        for i, C in enumerate(self.ChanNams):
            if i > 1:
                break  # max. of 2 channels
            # intitialize with graph outside range
            (g,) = self.axes[i].plot(
                self.Ti, self.ChanLim[i][1] * 1.1 * np.ones(self.Npoints), color=self.ChanColors[i]
            )
            self.graphs += (g,)

        return self.graphs

    # -- end DataLogger.init()

    def __call__(self, data):
        if data != None:
            n, dat = data

            k = n % self.Npoints
            for i, C in enumerate(self.ChanNams):
                if i > 1:
                    break  # works for 2 channels only
                self.Vhist[i, k] = dat[i]
                # update history graph
                if n > 1:  # !!! fix to avoid permanent display of first object in blit mode
                    self.graphs[i].set_data(
                        self.Ti, np.concatenate((self.Vhist[i, k + 1 :], self.Vhist[i, : k + 1]), axis=0)
                    )

        return self.graphs


# - -end def DataLogger.__call__
# -end class DataLogger
