# Copyright 2021-2022 Teemu Ikonen
# SPDX-License-Identifier: GPL-3.0-only

import gi

import importlib.resources as resources

gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
from gi.repository import Gtk  # noqa: E402


def text_barchart(data, highlights, height=None, width=30):
    """Return a string with a bar chart rendered as text.

    data:   Iterable of (label, value) tuples
    highlights: List/set of labels for which the bar is highlighted
    height  Number of lines in the generated bar chart
    width   Width of the generated bar chart in chars
    """
    sdata = list((d[0] if d[0] else '',
                 int(d[1]) if d[1] else 0) for d in data)
    sdata.sort(key=lambda x: x[1], reverse=True)

    dstr = ''
    axislines = 2  # x-axis needs this many lines
    height = height if height is not None else len(sdata) + axislines
    if (len(sdata) + axislines) < height:
        barlines = len(sdata)
#        # Add empty lines in the beginning
#        dstr += '\n' * (height - len(sdata) - axislines)
    else:
        barlines = height - axislines - 1

    xextra = 7  # Non-block chars in longest line
    max_x = max(x[1] for x in sdata) if sdata else 0
    xstep = 5  # xaxis grows by this step
    max_xaxis = xstep * ((max_x + xstep) // xstep)
    cmaxbar = width - xextra
    scale = cmaxbar / max_x if max_x > 0 else 1.0
    cmax_xaxis = cmaxbar + 3
    for d in sdata[:barlines]:
        block = '\u2585' if d[0] in highlights else '='
        dstr += "%3s\u2502%s %d\n" % (d[0], block*int(scale*d[1]), d[1])
    if barlines < len(sdata):
        dstr += "   \u256a\n"
    elif (len(sdata) - axislines) < height:
        # Add empty lines to y-axis
        dstr += '   \u2502\n' * (height - len(sdata) - axislines)
    dstr += "   \u251c" + '\u2500'*(cmax_xaxis) + '\u2524\n'
    dstr += "   0" + ' '*(cmax_xaxis - 1) + str(max_xaxis)
    return dstr


@Gtk.Template(string=resources.read_text('satellite', 'dataframe.ui'))
class DataFrame(Gtk.Bin):
    __gtype_name__ = 'DataFrame'
    header = Gtk.Template.Child()
    grid = Gtk.Template.Child()

    def __init__(self, rowtitles=[], values=[], **kwargs):
        super().__init__(**kwargs)
        self.set_rowtitles(rowtitles)
        if values:
            self.set_values(values)

    def empty(self):
        self.grid.foreach(lambda x: self.grid.remove(x))
        self.rows = 0

    def set_rowtitles(self, rowtitles):
        self.empty()

        for num, title in enumerate(rowtitles):
            tlabel = Gtk.Label(label=title)
            tlabel.get_style_context().add_class("dim-label")
            tlabel.set_halign(Gtk.Align.END)
            vlabel = Gtk.Label(label="-")
            vlabel.set_halign(Gtk.Align.START)
            self.grid.attach(tlabel, 0, num, 1, 1)
            self.grid.attach(vlabel, 1, num, 1, 1)

        self.rows = len(rowtitles)
        self.grid.show_all()

    def set_values(self, values):
        if len(values) != self.rows:
            raise ValueError("Number of values does not match rows")
        for num, val in enumerate(values):
            label = self.grid.get_child_at(1, num)
            label.set_text(val)
