"""
These are the graphs that can be used to present certain graphs through the pyqtgraph window
"""

import pyqtgraph as pg
import numpy as np
import cnmodel.util.pynrnutilities as PU


def stimulus_graph(win, stim, row, col):
    """
    Presents a graph of
    win: pg.GraphicsWindow()
    stim:(list) dummy sgc stim results
    """
    p1 = win.addPlot(
        title="Stimulus", row=row, col=col, labels={"bottom": "T (ms)", "left": "V"}
    )
    data = zip(stim.time, stim.sound)
    time = []
    stim = []
    for x, y in data:
        if 0.1 < x < 0.25:
            time.append(x * 1000)
            stim.append(y)
    p1.plot(time, stim, pen=pg.mkPen("k", width=0.75))
    return p1


def an_spike_graph(win, pre_cells, row, col):
    """
    Displays the spikes over time as lines with each cell representing a single row a single trial presentation
    :param win: pg.GraphicsWindow()
    :param pre_cells: (list) spike train time values
    :return: exists to allow for further modifications on the pg.GraphicsWindow object
    """
    p2 = win.addPlot(
        title="AN spikes",
        row=row,
        col=col,
        labels={"bottom": "T (ms)", "left": "AN spikes (first trial)"},
    )
    xan = []
    yan = []
    for k in range(len(pre_cells[0])):
        r = pre_cells[0][k]
        xan.extend(r)
        yr = k + np.zeros_like(r) + 0.2
        yan.extend(yr)
    c = pg.PlotCurveItem()
    xp = np.repeat(np.array(xan), 2)
    yp = np.repeat(np.array(yan), 2)
    yp[1::2] = yp[::2] + 0.6
    c.setData(
        xp.flatten(),
        yp.flatten(),
        connect="pairs",
        width=1.0,
        pen=pg.mkPen("k", width=1.5),
    )
    p2.addItem(c)
    return p2


def spike_graph(win, time, vms, row, col, title="cell"):
    """
    Displays the spikes over time as lines with each cell representing a single row a single trial presentation
    :param win: pg.GraphicsWindow()
    :param time: (list) of time that lines up with Vms
    :param vms: voltage trace data as a list
    :return: exists to allow for further modifications on the pg.GraphicsWindow object
    """
    p3 = win.addPlot(
        title=f"{title} Spikes",
        row=row,
        col=col,
        labels={"bottom": "T (ms)", "left": "Trial #"},
    )
    xcn = []
    ycn = []
    for k in range(len(time)):
        bspk = PU.findspikes(time[k], vms[k], -35.0)
        xcn.extend(bspk)
        yr = k + np.zeros_like(bspk) + 0.2
        ycn.extend(yr)
    d = pg.PlotCurveItem()
    xp = np.repeat(np.array(xcn), 2)
    yp = np.repeat(np.array(ycn), 2)
    yp[1::2] = yp[::2] + 0.6
    d.setData(xp.flatten(), yp.flatten(), connect="pairs", pen=pg.mkPen("k", width=1.5))
    p3.addItem(d)

    return p3


def voltage_graph(win, time, vms, row, col):
    """
       Actually displays the voltage trace
       :param win: pg.GraphicsWindow()
       :param time: (list) of time that lines up with Vms
       :param vms: voltage trace data as a list
       :return: exists to allow for further modifications on the pg.GraphicsWindow object
       """
    p4 = win.addPlot(
        title="Pyramidal Vm",
        row=row,
        col=col,
        labels={"bottom": "T (ms)", "left": "Vm (mV)"},
    )
    nrep = len(time)
    if nrep > 3:
        display = 3
    else:
        display = nrep
    for nr in range(display):
        p4.plot(
            time[nr], vms[nr], pen=pg.mkPen(pg.intColor(nr, nrep), hues=nrep, width=1.0)
        )
    return p4


def an_psth_graph(win, pre_cells, row, col):
    p6 = win.addPlot(
        title="AN PSTH",
        row=row,
        col=col,
        labels={"bottom": "T (ms)", "left": "Sp/ms/trial"},
    )
    bins = np.arange(100, 250, 1)
    all_xan = []
    for x in range(len(pre_cells)):
        for y in range(len(pre_cells[x])):
            all_xan.extend(pre_cells[x][y])
    (hist, binedges) = np.histogram(all_xan, bins)
    curve6 = p6.plot(
        binedges,
        hist,
        stepMode=True,
        fillBrush=(0, 0, 0, 255),
        brush=pg.mkBrush("k"),
        fillLevel=0,
    )
    return p6


def cell_psth_graph(win, time, vms, row, col, title="cell"):
    p7 = win.addPlot(
        title=f"{title} PSTH",
        row=row,
        col=col,
        labels={"bottom": "T (ms)", "left": "Sp/ms/trial"},
    )
    spike_times = []
    for k in range(len(time)):
        bspk = PU.findspikes(time[k], vms[k], -35.0)
        spike_times.extend(bspk)
    bins = np.arange(100, 250, 0.1)
    (hist, binedges) = np.histogram(spike_times, bins)
    curve7 = p7.plot(
        binedges,
        hist,
        stepMode=True,
        fillBrush=(0, 0, 0, 255),
        brush=pg.mkBrush("k"),
        fillLevel=0,
    )
    return p7
