
import numpy
import os, sys, pickle
from subprocess import Popen, PIPE

import hark


class plotQuickSpecKivy(hark.node.PythonNode):
    GUI_SCRIPT_NAME = 'plotQuickSpecKivyGui.py'

    def __init__(self):
        #super().__init__(['FFT', 'WINDOW_LENGTH', 'UPDATE_INTERVAL'], ['OUTPUT'])
        super().__init__('FFT', 'OUTPUT')

        script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), self.GUI_SCRIPT_NAME)
        python_exec = sys.executable
        self.proc = Popen([python_exec, script_path], stdin=PIPE)

        # self.specgram = [numpy.array([])]
        self.specgram = []
        self.windowlen = 600

        self.interval = 10
        self.channel = 0
        self.count = 0

    def __del__(self):
        self.proc.kill()

    def update(self, data):
        pickle.dump(data, self.proc.stdin)

    def gendata(self, data):
        # construct spectrum data
        for i in range(len(self.specgram)):
            tmp = 20 * numpy.log10(numpy.array(numpy.abs(data[i][:])) + 1)[numpy.newaxis, :]

            if len(self.specgram[i]) == 0:
                self.specgram[i] = numpy.zeros(((self.windowlen - 1), len(data[i][:])))
            self.specgram[i] = numpy.r_[self.specgram[i], tmp]

            if len(self.specgram[i]) > self.windowlen:
                self.specgram[i] = self.specgram[i][len(self.specgram[i])-self.windowlen:]

        # update spectrogram
        if self.count % self.interval == 0:
            arr = numpy.array(self.specgram[self.channel])
            self.update({'spectrum': arr, 'offset': self.count})
            """
            for i in range(len(self.specgram)):
                arr = numpy.array(self.specgram[i])
                # arr = numpy.fliplr(arr)
                # arr = numpy.flipud(arr)
                self.update({'spectrum': arr, 'offset': self.count})
            """

    def forward(self, **kwargs):
        if self.count == 0:
            # set Parameters
            if 'WINDOW_LENGTH' in kwargs:
                if isinstance(kwargs['WINDOW_LENGTH'], int):
                    self.windowlen = kwargs['WINDOW_LENGTH']
            if 'UPDATE_INTERVAL' in kwargs:
                if isinstance(kwargs['UPDATE_INTERVAL'], int):
                    self.interval = kwargs['UPDATE_INTERVAL']
            if 'SELECT_CHANNEL' in kwargs:
                if isinstance(kwargs['SELECT_CHANNEL'], int):
                    self.channel = kwargs['SELECT_CHANNEL']
            # check input terminal
            #if not isinstance(kwargs['FFT'], numpy.ndarray):
            #    try:
            #        raise AttributeError("There is an error in the network file. The type of input data to the plotQuickSpecKivy node must be Vector<std::complex<float> >.")
            #    except AttributeError as e:
            #        print(e)
            # check parameter range of SELECT_CHANNEL
            if (self.channel < 0) or (len(kwargs['FFT']) <= self.channel):
                try:
                    raise IndexError("The number of channels entered is {}, but the value specified in the SELECT_CHANNEL parameter is {}. The range of values ​​that can be set for the SELECT_CHANNEL parameter is between '0' and 'number of input channels - 1'.".format(len(kwargs['FFT']), self.channel))
                except IndexError as e:
                    print(e)
            # initialize array by input matrix size
            self.specgram = [numpy.array([]) for i in range(len(kwargs['FFT']))]
        self.gendata(kwargs['FFT'])

        self.count += 1
        return {'OUTPUT': kwargs['FFT']}

