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

# Copyright (c) 2006 - 2007 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing a LED widget.

It was inspired by KLed.
"""

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

class E4Led(QWidget):
    """
    Class implementing a LED widget.
    """
    def __init__(self, parent = None, color = None):
        """
        Constructor
        
        @param parent reference to parent widget (QWidget)
        @param color color of the LED (QColor)
        """
        QWidget.__init__(self, parent)
        
        if color is None:
            color = QColor("green")
        
        self.__led_on = True
        self.__dark_factor = 300
        self.__offcolor = color.dark(self.__dark_factor)
        self.__led_color = color
        self.__framedLed = True
        
        self.setColor(color)
        
    def paintEvent(self, evt):
        """
        Protected slot handling the paint event.
        
        @param evt paint event object (QPaintEvent)
        """
        self.__paintRound()
        
    def __getBestRoundSize(self):
        """
        Private method to calculate the width of the LED.
        
        @return new width of the LED (integer)
        """
        width = min(self.width(), self.height())
        width -= 2  # leave one pixel border
        return width > -1 and width or 0
        
    def __paintRound(self):
        """
        Private method to paint a round raised LED.
        """
        # Initialize coordinates, width and height of the LED
        width = self.__getBestRoundSize()
        
        # Calculate the gradient for the LED
        wh = width / 2
        color = self.__led_on and self.__led_color or self.__offcolor
        gradient = QRadialGradient(wh, wh, wh, 0.8 * wh, 0.8 * wh)
        gradient.setColorAt(0.0, color.light(200))
        gradient.setColorAt(0.6, color)
        if self.__framedLed:
            gradient.setColorAt(0.9, color.dark())
            gradient.setColorAt(1.0, self.palette().color(QPalette.Dark))
        else:
            gradient.setColorAt(1.0, color.dark())
        
        # now do the drawing
        paint = QPainter(self)
        paint.setRenderHint(QPainter.Antialiasing, True)
        paint.setBrush(QBrush(gradient))
        paint.setPen(Qt.NoPen)
        paint.drawEllipse(1, 1, width, width)
        paint.end()
        
    def isOn(self):
        """
        Public method to return the LED state.
        
        @return flag indicating the light state (boolean)
        """
        return self.__led_on
        
    def color(self):
        """
        Public method to return the LED color.
        
        @return color of the LED (QColor)
        """
        return self.__led_color
        
    def setOn(self, state):
        """
        Public slot to set the LED to on.
        
        @param state new state of the LED (boolean)
        """
        if self.__led_on != state:
            self.__led_on = state
            self.update()
        
    def setColor(self, color):
        """
        Public slot to set the LED color.
        
        @param color color for the LED (QColor)
        """
        if self.__led_color != color:
            self.__led_color = color
            self.__offcolor = color.dark(self.__dark_factor)
            self.update()
        
    def setDarkFactor(self, darkfactor):
        """
        Public method to set the dark factor.
        
        @param darkfactor value to set for the dark factor (integer)
        """
        if self.__dark_factor != darkfactor:
            self.__dark_factor = darkfactor
            self.__offcolor = self.__led_color.dark(darkfactor)
            self.update()
        
    def darkFactor(self):
        """
        Public method to return the dark factor.
        
        @return the current dark factor (integer)
        """
        return self.__dark_factor
        
    def toggle(self):
        """
        Public slot to toggle the LED state.
        """
        self.setOn(not self.__led_on)
        
    def on(self):
        """
        Public slot to set the LED to on.
        """
        self.setOn(True)
        
    def off(self):
        """
        Public slot to set the LED to off.
        """
        self.setOn(False)
        
    def setFramed(self, framed):
        """
        Public slot to set the __framedLed attribute.
        
        @param framed flag indicating the framed state (boolean)
        """
        if self.__framedLed != framed:
            self.__framedLed = framed
            self.__off_map = None
            self.__on_map = None
            self.update()
        
    def isFramed(self):
        """
        Public method to return the framed state.
        
        @return flag indicating the current framed state (boolean)
        """
        return self.__framedLed
        
    def sizeHint(self):
        """
        Public method to give a hint about our desired size.
        
        @return size hint (QSize)
        """
        return QSize(18, 18)
        
    def minimumSizeHint(self):
        """
        Public method to give a hint about our minimum size.
        
        @return size hint (QSize)
        """
        return QSize(18, 18)
