# -*- coding:utf-8 -*-

"""
This file is part of OpenSesame.

OpenSesame is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

OpenSesame is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with OpenSesame.  If not, see <http://www.gnu.org/licenses/>.
"""
from libopensesame.py3compat import *
from qtpy import QtCore, QtGui, QtWidgets
from libqtopensesame.widgets.base_widget import BaseWidget
from libqtopensesame.misc.translate import translation_context
_ = translation_context(u'font_widget', category=u'core')


class FontWidgetBase(BaseWidget):

    """A font selection widget"""
    max_size = 64
    font_list = [
        u'mono', u'sans', u'serif', u'arabic',
        u'chinese-japanese-korean', u'hebrew', u'hindi',
        _(u'other ...')
    ]

    font_changed = QtCore.Signal(['QString', int, bool, bool])

    def _apply(self):
        """Applies the controls."""
        self.family = self.ui.combobox_family.currentText()
        self.size = self.ui.spinbox_size.value()
        self.italic = self.ui.checkbox_italic.isChecked()
        self.bold = self.ui.checkbox_bold.isChecked()
        self.ui.label_example.setFont(self.get_font())
        self.font_changed.emit(
            self.family,
            self.size,
            self.italic,
            self.bold
        )

    def apply_family(self):
        """
        Applies the controls and optionally presents a full font selection
        dialog if the user has selected 'other ...'
        """
        if self.ui.combobox_family.currentText() == _(
                u'other ...',
                context=u'font_widget'
        ):
            font, ok = QtWidgets.QFontDialog.getFont(
                self.get_font(),
                parent=self._parent
            )
            if ok:
                self.family = str(font.family())
            else:
                self.family = self.experiment.var.get(
                    u'font_family',
                    _eval=False
                )
            self.update_family_combobox()
        self._apply()

    def get_font(self):
        """
        returns:
                type: QFont
        """
        font = QtGui.QFont(
            self.family,
            italic=self.italic,
            weight=QtGui.QFont.Bold if self.bold else QtGui.QFont.Normal
        )
        font.setPixelSize(min(self.max_size, self.size))
        return font

    def set_font(self, family=None, italic=None, bold=None, size=None):
        r"""Sets the widget to the specified font. For keywords, see
        initialize().
        """
        self.ui.combobox_family.activated.disconnect()
        self.ui.checkbox_italic.clicked.disconnect()
        self.ui.checkbox_bold.clicked.disconnect()
        self.ui.spinbox_size.editingFinished.disconnect()
        self.initialize(
            family=family,
            italic=italic,
            bold=bold,
            size=size,
            parent=self._parent
        )

    def initialize(
            self,
            experiment=None,
            family=None,
            italic=None,
            bold=None,
            size=None,
            parent=None
    ):
        r"""Initializes the widget.

        Parameters
        ----------
        experiment
            The experiment.
        family, optional
            The font family or None to use experiment default.
        italic, optional
            The font italic state or None to use experiment default.
        bold, optional
            font bold state or None to use experiment default.
        size, optional
            The font size or None to use experiment default.
        parent, optional
            A parent QWidget.
        """
        self._parent = parent if parent is not None else self.main_window
        if experiment is None:
            experiment = self.experiment
        self.family = experiment.var.get(u'font_family', _eval=False) \
            if family is None else family
        self.italic = experiment.var.get(u'font_italic', _eval=False) == u'yes' \
            if italic is None else italic
        self.bold = experiment.var.get(u'font_bold', _eval=False) == u'yes' \
            if bold is None else bold
        self.size = experiment.var.get(u'font_size', _eval=False) \
            if size is None else size
        if not isinstance(self.size, int) or self.size <= 0:
            self.size = 18
        if self.ui.combobox_family.findText(self.family) < 0:
            self.ui.combobox_family.addItem(self.family)
        self.ui.combobox_family.setCurrentIndex(
            self.ui.combobox_family.findText(self.family))
        self.ui.checkbox_italic.setChecked(self.italic)
        self.ui.checkbox_bold.setChecked(self.bold)
        self.ui.spinbox_size.setValue(self.size)
        self._apply()
        self.ui.combobox_family.activated.connect(self.apply_family)
        self.ui.checkbox_italic.clicked.connect(self._apply)
        self.ui.checkbox_bold.clicked.connect(self._apply)
        self.ui.spinbox_size.editingFinished.connect(self._apply)

    def update_family_combobox(self):
        """Updates the family combobox to include a custom font."""
        self.ui.combobox_family.activated.disconnect()
        self.ui.combobox_family.clear()
        l = self.font_list[:]
        if self.family not in l:
            l += [self.family]
        self.ui.combobox_family.insertItems(0, l)
        self.ui.combobox_family.setCurrentIndex(
            self.ui.combobox_family.findText(self.family))
        self.ui.combobox_family.activated.connect(self.apply_family)


class FontWidgetHorizontal(FontWidgetBase):

    def __init__(self, parent):
        """
        Constructor.

        Arguments:
        experiment	--	The experiment.

        Keywords arguments:
        parent		--	The parent QWidget. (default=None)
        """
        super().__init__(parent, ui=u'widgets.font_widget_horizontal')


class FontWidget(FontWidgetBase):

    def __init__(self, parent):
        """
        Constructor.

        Arguments:
        experiment	--	The experiment.

        Keywords arguments:
        parent		--	The parent QWidget. (default=None)
        """
        super().__init__(parent, ui=u'widgets.font_widget')


# Alias for backwards compatibility
font_widget = FontWidget
font_widget_base = FontWidgetBase
font_widget_horizontal = FontWidgetHorizontal
