#!/usr/bin/env python3

"""
tab_hold_buttons.py
"""

__author__ = ["Benjamin Mummery", "Tiago Sarmento"]
__credits__ = ["Benjamin Mummery", "Dónal Murray", "Tim Powell", "Tiago Sarmento"]
__license__ = "GPL"
__version__ = "0.0.1"
__maintainer__ = "Tiago Sarmento"
__email__ = "tiago.sarmento@stfc.ac.uk"
__status__ = "Prototype"

import logging
from PySide2 import QtCore, QtGui, QtWidgets
from widget_library.ok_cancel_buttons_widget import OkButtonWidget, CancelButtonWidget
from widget_library.localised_base_widgets import LocalisedQStackedWidget

# from global_widgets.global_ok_cancel_buttons import okButton, cancelButton
import time


class timerConfirmPopup(QtWidgets.QWidget):
    """Popup when start stop standby buttons are pressed. Counts a certain amount of time before switching on,
    showing a progress bar meanwhile"""

    def __init__(self, NativeUI, message_key, *args, **kwargs):
        super(timerConfirmPopup, self).__init__(*args, **kwargs)

        self.message_key = message_key

        self.setAttribute(
            QtCore.Qt.WA_ShowWithoutActivating
        )  # keep the main page activated to maintain button hold
        self.setWindowFlags(
            QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint
        )  # ensures focus is not stolen by alarm or confirmation

        self.setStyleSheet(
            "background-color:" + NativeUI.colors["page_background"].name() + ";"
            "color: " + NativeUI.colors["page_foreground"].name() + ";"
            "border:none"
        )

        self.stack = LocalisedQStackedWidget()

        # Define progress bar
        vlayout = QtWidgets.QVBoxLayout()
        self.label = QtWidgets.QLabel(NativeUI.text[self.message_key])
        self.label.setStyleSheet(
            "color: " + NativeUI.colors["label_foreground"].name() + ";"
            "background-color:" + NativeUI.colors["page_background"].name() + ";"
            "border: none;"
        )
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        vlayout.addWidget(self.label)

        self.progressBar = QtWidgets.QProgressBar()
        self.progressBar.setMaximum(3000)
        self.progressBar.setFormat("")
        self.progressBar.setStyleSheet(
            "QProgressBar{"
            "   background-color:"
            + NativeUI.colors["button_background_enabled"].name()
            + ";"
            "}"
            "QProgressBar::chunk{"
            "   background-color:" + NativeUI.colors["highlight"].name() + ";"
            "}"
        )

        vlayout.addWidget(self.progressBar)
        self.progressWidg = QtWidgets.QWidget()
        self.progressWidg.setLayout(vlayout)
        self.stack.addWidget(self.progressWidg)

        # Define confirmation message and buttons
        self.completeLayout = QtWidgets.QVBoxLayout()
        self.completeLabel = QtWidgets.QLabel("confirm it")
        self.completeLabel.setAlignment(QtCore.Qt.AlignCenter)

        buttonLayout = QtWidgets.QHBoxLayout()
        self.okButton = OkButtonWidget(NativeUI)
        buttonLayout.addWidget(self.okButton)
        self.cancelButton = CancelButtonWidget(NativeUI)
        self.okButton.setEnabled(True)
        self.cancelButton.setEnabled(True)
        buttonLayout.addWidget(self.cancelButton)

        self.completeLayout.addWidget(self.completeLabel)
        self.completeLayout.addLayout(buttonLayout)

        self.completeWidg = QtWidgets.QWidget()
        self.completeWidg.setLayout(self.completeLayout)
        self.stack.addWidget(self.completeWidg)

        # set layout
        stackLayout = QtWidgets.QVBoxLayout()
        stackLayout.addWidget(self.stack)
        self.setLayout(stackLayout)

        # place popup in screen
        qtRectangle = self.frameGeometry()
        centerPoint = QtWidgets.QDesktopWidget().availableGeometry().center()
        qtRectangle.moveCenter(centerPoint)
        self.move(qtRectangle.topLeft())
        # self.move(QtGui.QApplication.desktop().screen().rect().center() - self.rect().center())

    def reset(self) -> int:
        """
        Reset the popup to its start state - on the progress bar page with the progres
        at zero.
        """
        self.progressBar.setValue(0)
        self.stack.setCurrentWidget(self.progressWidg)
        return 0

    def localise_text(self, text: dict) -> int:
        """
        Set the text for the label.
        """
        self.label.setText(text[self.message_key])
        return 0

    def setFont(self, font: QtGui.QFont) -> int:
        """
        Set the font for the various labels and button text.
        """
        self.label.setFont(font)
        self.completeLabel.setFont(font)
        self.okButton.setFont(font)
        self.cancelButton.setFont(font)
        return 0

    def setButtonSize(self, x: int, y: int, spacing: int = 10) -> int:
        """
        Set the size of the buttons in the widget. Also uses the button height (if set)
        for the progress bar.
        """
        button_list = [self.okButton, self.cancelButton]
        if x is not None and y is not None:
            for button in button_list:
                button.setFixedSize(x - spacing, y)
            self.progressBar.setFixedHeight(y)
        elif x is not None and y is None:
            for button in button_list:
                button.setFixedWidth(x - spacing)
        elif x is None and y is not None:
            for button in button_list:
                button.setFixedHeight(y)
            self.progressBar.setFixedHeight(y)
        else:
            raise AttributeError("setButtonSize called without usable size information")
        return 0


class holdButton(QtWidgets.QPushButton):
    """Subclass push button to count press time and update progress bar. handleClick() is overridden.
    Popup with progress bar appears on click, fills as button is held."""

    on_press = QtCore.Signal(QtWidgets.QWidget)
    on_release = QtCore.Signal()

    def __init__(self, NativeUI, popup, *args, **kwargs):
        super(holdButton, self).__init__(*args, **kwargs)

        self.NativeUI = NativeUI

        self.timeOut = 3000
        self.timeStep = 60

        self.setAutoRepeat(True)
        self.setAutoRepeatDelay(self.timeStep)
        self.setAutoRepeatInterval(self.timeStep)

        self.pressTime = 0
        self.state = 0
        self.complete = False

        self.clicked.connect(self.handleClick)

        self.popUp = popup

        self.popUp.okButton.pressed.connect(self.okButtonPressed)
        self.popUp.cancelButton.pressed.connect(self.closePopup)

    def handleClick(self):
        """
        Override handleClick to count button hold time. Shows popup, sets progress bar,
        and updates it.
        """
        self.now = time.time()
        self.on_press.emit(self.popUp)
        if self.state == 0:
            self.initial = time.time()
        if self.isDown():
            if self.pressTime >= self.timeOut:
                self.complete = True
                logging.debug(self.now - self.initial)
                self.popUp.stack.setCurrentWidget(self.popUp.completeWidg)

            self.pressTime = self.pressTime + self.timeStep
            self.state = 1
            self.popUp.progressBar.setValue(self.pressTime)
            self.popUp.progressBar.update()
        else:
            self.pressTime = 0
            logging.debug(
                "holdButton.handleClick():\nself.complete: %s\nself.state: %s"
                % (self.complete, self.state)
            )
            if self.state == 1:
                logging.debug("holdButton released")
            if not self.complete:
                self.closePopup()
            self.state = 0

    def okButtonPressed(self):
        """Respond to ok button press by sending command corresponding to button type"""
        logging.debug(self.text())
        self.NativeUI.q_send_cmd(
            "GENERAL", self.text()
        )  # text is stand stop or standby
        self.closePopup()
        return 0

    def reset_status(self):
        self.popUp.reset()
        self.pressTime = 0
        self.state = 0
        self.complete = False
        return 0

    def closePopup(self):
        """Reset progress bar and widget stack, and close popup"""
        self.reset_status()
        logging.debug("Emmitting on_release")
        self.on_release.emit()
        return 0


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    widg = holdButton("Standby")
    widg.show()
    sys.exit(app.exec_())
