# Copyright (c) 2011-2014, B.I.Stepanov Institute of Physics, National Academy
# of Sciences of Belarus.
#
# This program 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 2 of the License, or (at your option) any later
# version.
#
# This program 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
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

from PyQt4.QtCore import *
from PyQt4.QtGui import *

__all__ = ['StatusSignalingWidget']

# *****************************************************************************
class StatusSignalingWidget(QWidget):
    """Base class for widgets that may have status messages associated with
    them.

    Status message is a rich text string supplemented with information of the
    widget's current state. Currently, the following states are available:
      - 'completed': the widget has recently completed an action with success.
      - 'info': the widget is normal operational state, but requires user's
        attention to be drawn to it.
      - 'warning', 'error': the widget is not operational, and requires user's
        attention to be drawn to it.
      - 'progress': the widget is busy executing an action.

    Signals:
      - 'statusMessageChanged': status message associated with the widget has
        changed. Use 'getStatusMessage' to obtain the current message.
      - 'repaintRequested': the widget is about to start an action that may
        take noticeable amount of time but nevertheless is executed in the main
        application thread. This is normally preceded by setting an appropriate
        progress status, and thus may be used to repaint the application window
        so that the progress message is visible to the user while the program
        is in the not-responding mode."""

    # ---- Signals ------------------------------------------------------------
    statusMessageChanged = pyqtSignal()
    repaintRequested = pyqtSignal()

    # ---- Public overridable methods -----------------------------------------
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)

        self.statusMessage = None

    # ---- Public methods -----------------------------------------------------
    def getStatusMessage(self):
        return self.statusMessage

    # ---- Protected overridable methods --------------------------------------
    def setStatusMessage(self, statusMessage):
        """This is the basic implementation of any of the other convenience
        status manipulation methods. Redefine it to modify default behaviour
        of these functions."""

        self.statusMessage = statusMessage
        self.statusMessageChanged.emit()

    # ---- Protected methods --------------------------------------------------
    def clearStatusMessage(self):
        self.setStatusMessage(None)

    def setCompletedMessage(self, text):
        self.setStatusMessage(StatusMessage('completed', text))

    def setInfoMessage(self, text):
        self.setStatusMessage(StatusMessage('info', text))

    def setWarningMessage(self, text):
        self.setStatusMessage(StatusMessage('warning', text))

    def setErrorMessage(self, text):
        self.setStatusMessage(StatusMessage('error', text))

    def setProgressMessage(self, text, requestRepaint = False):
        """Set a progress status message and then fire the 'repaintRequested'
        signal if 'requestRepaint' is set to 'True'."""

        self.setStatusMessage(StatusMessage('progress', text))

        if requestRepaint:
            self.repaintRequested.emit()

# *****************************************************************************
class StatusMessage:
    """A rich text message with a state string informing of its severity."""

    # ---- Private class attributes -------------------------------------------
    # Admissible message state IDs, in order of ascending severity.
    #
    # Progress messages are considered the most severe, as it is usually more
    # important to draw user's attention to the current action being taken than
    # to any previous errors.
    statusesBySeverity = ('completed', 'info', 'warning', 'error', 'progress')

    # ---- Public functions ---------------------------------------------------
    def __init__(self, status, text):

        assert status in self.statusesBySeverity

        self.status = status
        self.text = text

    def getStatus(self):
        return self.status

    def getText(self):
        return self.text

    def getSeverity(self):
        """Return an integer that may be used to assess severity of the message
        state, with greater numbers corresponding to greater severity."""

        return self.statusesBySeverity.index(self.status)
