import qt

import widget
import widgetfactory
import page
import graph
import containers
import setting
import utils

class Bitmap(widget.Widget):
    """Pixel Bitmap"""

    typename='bitmap'
    allowedparenttypes = [page.Page, containers.Grid, graph.Graph]
    allowusercreation = True
    description = 'Bitmap image'

    def __init__(self, parent, name=None):
        """Initialise object"""
        
        widget.Widget.__init__(self, parent, name=name)

        s = self.settings

        s.add(setting.Filename('filename','',
                               descr='Filename of the image'))
        
        s.add( setting.Distance( 'left',
                                 '0',
                                 descr = 'Offset from the left of the parent'))
        s.add( setting.Distance( 'top',
                                 '0',
                                 descr = 'Offset from the top of the parent') )  
        s.add( setting.Distance( 'width',
                                 '0',
                                 descr = 'Width of the bitmap'))
        s.add( setting.Distance( 'height',
                                 '0',
                                 descr = 'Height of the bitmap') )
        s.add( setting.Bool( 'preserveAspect',
                              True,
                              descr = 'Maintain aspect ratio of image') )
        #tuple of the form filename, data
        self._loadedData = None
        #caches for the last dimension settings so we know if they have changed
        self._lastWidth = {}
        self._lastHeight = {}
        self.readDefaults()
        
    def _getImageData(self):
        currentData = self._loadedData
        filename = self.settings.get('filename').toText()

        if currentData and currentData[0] == filename:
            return currentData[1]
        else:
            if filename:
                image = qt.QImage()
                if image.load(qt.QString(filename)):
                    self._loadedData = filename, image
                    return image
            
        self._loadedData = None
        return None
                
    def draw(self, parentposn, painter, outerbounds = None):
        
        s = self.settings
        margins = ( s.get('left').convert(painter),
                    s.get('top').convert(painter), 0, 0)

        bounds = self.computeBounds(parentposn, painter, margins=margins)
        
        pos = qt.QPoint(bounds[0], bounds[1])

        image = self._getImageData()

        if not image:
            return
        
        width = s.get('width').convert(painter)
        height = s.get('height').convert(painter)

        if width > 0 or height > 0:
            if width == 0:
                width = image.width()
                s.width = str(width) +'px'
            if height == 0:
                height == image.height()
                s.height = str(height) + 'px'
            aspect = s.preserveAspect

            if aspect:
                #Change the unaltered dimension of the image to preserve
                #aspect ratio
                if self._lastWidth != s.get('width').__dict__:
                    width = float(s.get('width').convert(painter, 'px',
                                                         False))
                    height = image.height() * width/image.width()
                    unit = s.get('height').getUnit()
                    s.height = str(height) + 'px'
                    s.get('height').setUnit(painter, unit)

                elif self._lastHeight != s.get('height').__dict__:
                    height = float(s.get('height').convert(painter, 'px',
                                                           False))
                    width = image.width() * height/image.height()
                    unit = s.get('width').getUnit()
                    s.width = str(width) + 'px'
                    s.get('width').setUnit(painter, unit)
        else:
            width  = image.width()
            height = image.height()
            s.width = str(width) +'px'
            s.height = str(height) + 'px'

        #Update the cached copy of the settings
        self._lastHeight = s.get('height').__dict__.copy()
        self._lastWidth = s.get('width').__dict__.copy()
        
        image = image.smoothScale(width, height, qt.QImage.ScaleFree)
        self._lastModified = None
        painter.drawImage(pos, image)

# allow users to make Image objects
widgetfactory.thefactory.register( Bitmap )
