from PyQt5.QtGui import QColor, QPalette
from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QFileDialog, QFrame, QPushButton

from functools import partial
import os


def change_color(widget, color, alpha=255, resource=None):
    """
    alpha: valid range is 0 to 255
    """
    if type(widget) is QPushButton:
        # FIXME cant change the color using QPalette()
        widget.setStyleSheet(f"background-color: rgba(%i,%i,%i,%i);" % (color.red(),
                                                                        color.green(),
                                                                        color.blue(),
                                                                        alpha))
        return

    if resource is None:
        if type(widget) is QFrame:
            resource = QPalette.Background
        elif type(wiget) is QPushButton:
            resource = QPalette.Button
        else:
            resource = QPalette.Base

    pal = widget.palette()
    color.setAlpha(alpha)
    pal.setColor(resource, color)
    widget.setAutoFillBackground(True)
    widget.setPalette(pal)


def string_abbrev(data, maxlen):
    """
    Abbreviate the last string until the string is smaller than passed max length
    """
    idx = -1
    while len(data) > maxlen:
        v = data.split(' ')
        v[idx] = "%s." % v[idx][0]
        data = ' '.join(v)
        idx -= 1
    return data


class PenaltyGroup(QObject):
    # 1. penalty type: h, hc, ch
    # 2. name of the widget
    # 3. team: aka or ao
    # 4. active or inactive
    signalPenalty = pyqtSignal(str, str, str, bool)

    def __init__(self, parent, team, *args, **kwargs):
        kwargs.setdefault('parent', parent)
        parent.signalStarted.connect(self.__changed)
        super().__init__(*args, **kwargs)
        self.team = team
        self.__penalties = []
        self.__boxes = []
        for name in ('ch1', 'ch2', 'ch3', 'hc', 'h'):
            widget_name = f'{name}_{team}'
            w = getattr(parent, widget_name)
            self.__boxes.append(w)
            setattr(self, name, w)

            if name == 'h':
                w.stateChanged.connect(partial(self.cb_h, w, widget_name))
            elif name == 'hc':
                w.stateChanged.connect(partial(self.cb_hc, w, widget_name))
            else:
                w.stateChanged.connect(partial(self.cb_chx, w, widget_name))

        self.disable()

    def __changed(self, started):
        if started:
            self.__reset(True)
        else:
            self.disable()

    def __reset(self, enable):
        self.__toggle_chs([False]*5, enable=enable)
        self.__penalties = []

    def reset(self):
        self.__reset(None)

    @property
    def __get_penalties(self):
        return [self.ch1.isChecked(), self.ch2.isChecked(), self.ch3.isChecked()]

    @property
    def status(self):
        return [w.isChecked() for w in self.__boxes]

    def cb_chx(self, widget, widget_name):
        self.signalPenalty.emit('ch', widget_name, self.team, widget.isChecked())

    def __toggle_chs(self, values, enable=False):
        """
        Set enable=None to skip call of setEnabled()
        """
        for index in range(0, len(values)):
            widget = self.__boxes[index]
            widget.blockSignals(True)
            widget.setChecked(values[index])
            if enable is not None:
                widget.setEnabled(enable)
            widget.blockSignals(False)

    def cb_hc(self, widget, widget_name):
        checked = widget.isChecked()
        if checked:
            self.__penalties = self.__get_penalties
            self.__toggle_chs([True]*3)
        else:
            self.__toggle_chs(self.__penalties, enable=True)
            self.__penalties = []

        self.signalPenalty.emit('hc', widget_name, self.team, widget.isChecked())

    def cb_h(self, widget, widget_name):
        self.__toggle_chs([True]*4)
        self.signalPenalty.emit('h', widget_name, self.team, widget.isChecked())

    def disable(self):
        for w in self.__boxes:
            w.setEnabled(False)

    def setEnabled(self, enable):
        for w in self.__boxes:
            w.setEnabled(enable)


def open_file(parent, title, filters, **kwargs):
    path = kwargs.pop('path', os.getcwd())
    return QFileDialog.getOpenFileName(parent, title, path, filters)


def change_point_size(widget, sz, family=None, bold=None):
    font = widget.font()
    font.setPointSize(sz)
    if family:
        font.setFamily(family)
    if bold in (True, False):
        font.setBold(bold)
    widget.setFont(font)
