#
# The Python Imaging Library.
# $Id: //modules/pil/PIL/ImageWin.py#6 $
#
# a Windows DIB display interface
#
# History:
# 1996-05-20 fl   Created
# 1996-09-20 fl   Fixed subregion exposure
# 1997-09-21 fl   Added draw primitive (for tzPrint)
#
# Copyright (c) Secret Labs AB 1997-2002.
# Copyright (c) Fredrik Lundh 1996-2002.
#
# See the README file for information on usage and redistribution.
#

import Image

##
# The <b>ImageWin</b> module contains support to create and display
# images under Windows 95/98, NT, 2000 and later.

class HDC:
    def __init__(self, dc):
        self.dc = dc
    def __int__(self):
        return self.dc

class HWND:
    def __init__(self, wnd):
        self.wnd = wnd
    def __int__(self):
        return self.wnd

##
# Create a Windows bitmap with the given mode and size.  The mode can
# be one of "1", "L", "P", or "RGB".
#
# If the display requires a palette, this constructor creates a
# suitable palette and associates it with the image. For an "L" image,
# 128 greylevels are allocated. For an "RGB" image, a 6x6x6 colour
# cube is used, together with 20 greylevels.
#
# To make sure that palettes work properly under Windows, you must
# call the <b>palette</b> method upon certain events from Windows.

class Dib:

    ##
    # Create Windows bitmap.
    #
    # @param image Either a PIL image, or a mode string.  If a
    #    mode string is used, a size must also be given.  The
    #    mode can be one of "1", "L", "P", or "RGB".
    # @param size If the first argument is a mode string, this
    #    defines the size of the image.

    def __init__(self, image, size=None):
        if hasattr(image, "mode") and hasattr(image, "size"):
            mode = image.mode
            size = image.size
        else:
            mode = image
            image = None
        if mode not in ["1", "L", "P", "RGB"]:
            mode = Image.getmodebase(mode)
        self.image = Image.core.display(mode, size)
        self.mode = mode
        self.size = size
        if image:
            self.paste(image)

    ##
    # Copy the bitmap contents to a device context.
    #
    # @param handle Device context (HDC), cast to a Python integer,
    #    or a HDC or HWND instance.  In PythonWin, you can use the
    #    <b>GetHandleAttrib</b> method of the <b>CDC</b> class to get
    #    a suitable handle.

    def expose(self, handle):
        if isinstance(handle, HWND):
            dc = self.image.getdc(handle)
            try:
                result = self.image.expose(dc)
            finally:
                self.image.releasedc(handle, dc)
        else:
            result = self.image.expose(handle)
        return result

    def draw(self, handle, dst, src=None):
        if not src:
            src = (0,0) + self.size
        if isinstance(handle, HWND):
            dc = self.image.getdc(handle)
            try:
                result = self.image.draw(dc, dst, src)
            finally:
                self.image.releasedc(handle, dc)
        else:
            result = self.image.draw(handle, dst, src)
        return result

    ##
    # Installs the palette associated with the image in the
    # given device context.
    # <p>
    # This method should be called upon <b>QUERYNEWPALETTE</b>
    # and <b>PALETTECHANGED</b> events from Windows. If this
    # method returns a non-zero value, one or more display
    # palette entries were changed, and the image should be
    # redrawn.
    #
    # @param dc Device context (HDC), cast to a Python integer,
    #     or an HDC or HWND instance.
    # @return A true value if one or more entries were changed
    #    (this indicates that the image should be redrawn).

    def query_palette(self, dc):
        if isinstance(handle, HWND):
            dc = self.image.getdc(handle)
            try:
                result = self.image.query_palette(dc)
            finally:
                self.image.releasedc(handle, dc)
        else:
            result = self.image.query_palette(handle)
        return result

    ##
    # Paste a PIL image into the bitmap image.
    #
    # @param im A PIL image.  The size must match the target region.
    #    If the mode does not match, the image is converted to the
    #    mode of the bitmap image.
    # @param box A 4-tuple defining the left, upper, right, and
    #    lower pixel coordinate.  If None is given instead of a
    #    tuple, all of the image is assumed.

    def paste(self, im, box=None):
        im.load()
        if self.mode != im.mode:
            im = im.convert(self.mode)
        if box:
            self.image.paste(im.im, box)
        else:
            self.image.paste(im.im)
