from PyQt5 import QtWidgets
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QTextEdit, QApplication

from core.repositories import SessionRepository
from ui.qt.widgets.frame_notes_ui import Ui_frameNotes


class FrameNotes(QtWidgets.QFrame):
    notesChanged = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.dirty = False
        self.playlist = None
        self.createWidgets()

    def createWidgets(self):
        self.ui = Ui_frameNotes()
        self.ui.setupUi(self)

        # Setup the QTextEdit editor configuration
        self.ui.sessionNotes.setAutoFormatting(QTextEdit.AutoAll)
        self.ui.sessionNotes.selectionChanged.connect(self.update_format)

        # Initialize default font size.
        font = QFont('Verdana', 12)
        self.ui.sessionNotes.setFont(font)

        # We need to repeat the size to init the current format.
        self.ui.sessionNotes.setFontPointSize(12)

        self.ui.btnBold.toggled.connect(self.toggleBold)
        self.ui.btnItalic.toggled.connect(self.toggleItalic)
        self.ui.btnUnderline.toggled.connect(self.toggleUnderlined)

        self.ui.btnUndo.clicked.connect(self.ui.sessionNotes.undo)
        self.ui.btnRedo.clicked.connect(self.ui.sessionNotes.redo)

        self.ui.sessionNotes.textChanged.connect(self.notes_changed)
        QtWidgets.qApp.focusChanged.connect(self.focus_changed)

        # A list of all format-related widgets/actions, so we can disable/enable signals when updating.
        self._format_actions = [
            self.ui.btnBold,
            self.ui.btnItalic,
            self.ui.btnUnderline,
        ]

        self.update_format()

    def toggleBold(self, active):
        self.ui.sessionNotes.setFontWeight(QFont.Bold if active else QFont.Normal)

    def toggleItalic(self, active):
        self.ui.sessionNotes.setFontItalic(active)

    def toggleUnderlined(self, active):
        self.ui.sessionNotes.setFontUnderline(active)

    def _block_signals(self, objects, b):
        for o in objects:
            o.blockSignals(b)

    def update_format(self):
        """
        Update the font format toolbar/actions when a new text selection is made. This is neccessary to keep
        toolbars/etc. in sync with the current edit state.
        :return:
        """
        # # Disable signals for all format widgets, so changing values here does not trigger further formatting.
        self._block_signals(self._format_actions, True)
        self.ui.btnItalic.setChecked(self.ui.sessionNotes.fontItalic())
        self.ui.btnItalic.setChecked(self.ui.sessionNotes.fontUnderline())
        self.ui.btnBold.setChecked(self.ui.sessionNotes.fontWeight() == QFont.Bold)
        self._block_signals(self._format_actions, False)

    def notes(self):
        return self.ui.sessionNotes.toHtml()

    def set_notes(self, html):
        self.ui.sessionNotes.textChanged.disconnect(self.notes_changed)
        self.ui.sessionNotes.setHtml(html)
        self.ui.sessionNotes.textChanged.connect(self.notes_changed)

    def set_playlist(self, playlist):
        self.playlist = playlist
        self.set_notes(playlist.notes)

    def focus_changed(self, old, now):
        if old is self.ui.sessionNotes and self.dirty:
            self.save()

    def notes_changed(self):
        self.dirty = True

    def save(self):
        print("save notes")
        notes = self.notes()
        session_repo = SessionRepository()
        self.playlist.notes = notes
        session_repo.commit()
        self.dirty = False
