# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial

from typing import List, Optional

from PySide6.QtCore import QSignalBlocker, Qt, Signal, Slot
from PySide6.QtWidgets import (QButtonGroup, QCheckBox, QGridLayout, QGroupBox,
                               QLabel, QWidget)


class CheckBoxPanel(QGroupBox):
    """A Panel presenting check boxes in a grid."""

    changed = Signal()

    def __init__(self, title: str, checkbox_data: list,
                 columns: int = 5, parent: Optional[QWidget] = None):
        """Create the panel. checkbox_data is a list
           - string
                   representing a header
           - tuple(keyword, checkbox text, tooltip, checked)
                   representing a checkbox"""
        super(CheckBoxPanel, self).__init__(title, parent)
        self._checkbox_data = checkbox_data
        self._button_group = QButtonGroup(self)
        self._button_group.setExclusive(False)
        self._button_group.buttonToggled.connect(self._changed)
        main_layout = QGridLayout(self)
        self._checkboxes = []  # (checkbox, keyword)
        row = 0
        col = 0
        for c in checkbox_data:
            if isinstance(c, str):  # header
                col = 0
                row += 1
                label = QLabel(f"{c}:", self)
                label.setAlignment(Qt.AlignLeft)
                if row > 0:
                    row += 1
                main_layout.addWidget(label, row, col)
                col += 1
            else:
                checkbox = QCheckBox(c[1], self)
                self._button_group.addButton(checkbox)
                checkbox.setChecked(c[2])
                checkbox.setToolTip(c[3])
                self._checkboxes.append((checkbox, c[0]))
                main_layout.addWidget(checkbox, row, col)
                col += 1
                if col >= columns:
                    col = 0
                    row += 1

    def set_selection(self, selection: List[str]) -> None:
        """Set the selection from a list of keywords"""
        with QSignalBlocker(self):
            if selection:
                for c in self._checkboxes:
                    c[0].setChecked(c[1] in selection)
            else:
                self.uncheck_all()

    def uncheck_all(self) -> None:
        for c in self._checkboxes:
            c[0].setChecked(False)

    def selection(self) -> List[str]:
        """Return the selection as list of keywords"""
        result = []
        for c in self._checkboxes:
            if c[0].isChecked():
                result.append(c[1])
        return result

    @Slot()
    def _changed(self) -> None:
        self.changed.emit()

    @Slot()
    def restore_defaults(self) -> None:
        b = 0
        buttons = self._button_group.buttons()
        for c in self._checkbox_data:
            if not isinstance(c, str):
                buttons[b].setChecked(c[2])
                b += 1
