"""PixMapWrapper - defines the PixMapWrapper class, which wraps an opaque
QuickDraw PixMap data structure in a handy Python class.  Also provides
methods to convert to/from pixel data (from, e.g., the img module) or a
Python Imaging Library Image object.

J. Strout <joe@strout.net>  February 1999"""


from warnings import warnpy3k
warnpy3k("In 3.x, the PixMapWrapper module is removed.", stacklevel=2)

from Carbon import Qd
from Carbon import QuickDraw
import struct
import MacOS
import img
import imgformat

# PixMap data structure element format (as used with struct)
_pmElemFormat = {
    'baseAddr':'l',     # address of pixel data
    'rowBytes':'H',     # bytes per row, plus 0x8000
    'bounds':'hhhh',    # coordinates imposed over pixel data
        'top':'h',
        'left':'h',
        'bottom':'h',
        'right':'h',
    'pmVersion':'h',    # flags for Color QuickDraw
    'packType':'h',     # format of compression algorithm
    'packSize':'l',     # size after compression
    'hRes':'l',         # horizontal pixels per inch
    'vRes':'l',         # vertical pixels per inch
    'pixelType':'h',    # pixel format
    'pixelSize':'h',    # bits per pixel
    'cmpCount':'h',     # color components per pixel
    'cmpSize':'h',      # bits per component
    'planeBytes':'l',   # offset in bytes to next plane
    'pmTable':'l',      # handle to color table
    'pmReserved':'l'    # reserved for future use
}

# PixMap data structure element offset
_pmElemOffset = {
    'baseAddr':0,
    'rowBytes':4,
    'bounds':6,
        'top':6,
        'left':8,
        'bottom':10,
        'right':12,
    'pmVersion':14,
    'packType':16,
    'packSize':18,
    'hRes':22,
    'vRes':26,
    'pixelType':30,
    'pixelSize':32,
    'cmpCount':34,
    'cmpSize':36,
    'planeBytes':38,
    'pmTable':42,
    'pmReserved':46
}

class PixMapWrapper:
    """PixMapWrapper -- wraps the QD PixMap object in a Python class,
    with methods to easily get/set various pixmap fields.  Note: Use the
    PixMap() method when passing to QD calls."""

    def __init__(self):
        self.__dict__['data'] = ''
        self._header = struct.pack("lhhhhhhhlllhhhhlll",
            id(self.data)+MacOS.string_id_to_buffer,
            0,                      # rowBytes
            0, 0, 0, 0,             # bounds
            0,                      # pmVersion
            0, 0,                   # packType, packSize
            72<<16, 72<<16,         # hRes, vRes
            QuickDraw.RGBDirect,    # pixelType
            16,                     # pixelSize
            2, 5,                   # cmpCount, cmpSize,
            0, 0, 0)                # planeBytes, pmTable, pmReserved
        self.__dict__['_pm'] = Qd.RawBitMap(self._header)

    def _stuff(self, element, bytes):
        offset = _pmElemOffset[element]
        fmt = _pmElemFormat[element]
        self._header = self._header[:offset] \
            + struct.pack(fmt, bytes) \
            + self._header[offset + struct.calcsize(fmt):]
        self.__dict__['_pm'] = None

    def _unstuff(self, element):
        offset = _pmElemOffset[element]
        fmt = _pmElemFormat[element]
        return struct.unpack(fmt, self._header[offset:offset+struct.calcsize(fmt)])[0]

    def __setattr__(self, attr, val):
        if attr == 'baseAddr':
            raise 'UseErr', "don't assign to .baseAddr -- assign to .data instead"
        elif attr == 'data':
            self.__dict__['data'] = val
            self._stuff('baseAddr', id(self.data) + MacOS.string_id_to_buffer)
        elif attr == 'rowBytes':
            # high bit is always set for some odd reason
            self._stuff('rowBytes', val | 0x8000)
        elif attr == 'bounds':
            # assume val is in official Left, Top, Right, Bottom order!
            self._stuff('left',val[0])
            self._stuff('top',val[1])
            self._stuff('right',val[2])
            self._stuff('bottom',val[3])
        elif attr == 'hRes' or attr == 'vRes':
            # 16.16 fixed format, so just shift 16 bits
            self._stuff(attr, int(val) << 16)
        elif attr in _pmElemFormat.keys():
            # any other pm attribute -- just stuff
            self._stuff(attr, val)
        else:
            self.__dict__[attr] = val

    def __getattr__(self, attr):
        if attr == 'rowBytes':
            # high bit is always set for some odd reason
            return self._unstuff('rowBytes') & 0x7FFF
        elif attr == 'bounds':
            # return bounds in official Left, Top, Right, Bottom order!
            return ( \
                self._unstuff('left'),
                self._unstuff('top'),
                self._unstuff('right'),
                self._unstuff('bottom') )
        elif attr == 'hRes' or attr == 'vRes':
            # 16.16 fixed format, so just shift 16 bits
            return self._unstuff(attr) >> 16
        elif attr in _pmElemFormat.keys():
            # any other pm attribute -- just unstuff
            return self._unstuff(attr)
        else:
            return self.__dict__[attr]


    def PixMap(self):
        "Return a QuickDraw PixMap corresponding to this data."
        if not self.__dict__['_pm']:
            self.__dict__['_pm'] = Qd.RawBitMap(self._header)
        return self.__dict__['_pm']

    def blit(self, x1=0,y1=0,x2=None,y2=None, port=None):
        """Draw this pixmap into the given (default current) grafport."""
        src = self.bounds
        dest = [x1,y1,x2,y2]
        if x2 is None:
            dest[2] = x1 + src[2]-src[0]
        if y2 is None:
            dest[3] = y1 + src[3]-src[1]
        if not port: port = Qd.GetPort()
        Qd.CopyBits(self.PixMap(), port.GetPortBitMapForCopyBits(), src, tuple(dest),
                QuickDraw.srcCopy, None)

    def fromstring(self,s,width,height,format=imgformat.macrgb):
        """Stuff this pixmap with raw pixel data from a string.
        Supply width, height, and one of the imgformat specifiers."""
        # we only support 16- and 32-bit mac rgb...
        # so convert if necessary
        if format != imgformat.macrgb and format != imgformat.macrgb16:
            # (LATER!)
            raise "NotImplementedError", "conversion to macrgb or macrgb16"
        self.data = s
        self.bounds = (0,0,width,height)
        self.cmpCount = 3
        self.pixelType = QuickDraw.RGBDirect
        if format == imgformat.macrgb:
            self.pixelSize = 32
            self.cmpSize = 8
        else:
            self.pixelSize = 16
            self.cmpSize = 5
        self.rowBytes = width*self.pixelSize/8

    def tostring(self, format=imgformat.macrgb):
        """Return raw data as a string in the specified format."""
        # is the native format requested?  if so, just return data
        if (format == imgformat.macrgb and self.pixelSize == 32) or \
           (format == imgformat.macrgb16 and self.pixelsize == 16):
            return self.data
        # otherwise, convert to the requested format
        # (LATER!)
            raise "NotImplementedError", "data format conversion"

    def fromImage(self,im):
        """Initialize this PixMap from a PIL Image object."""
        # We need data in ARGB format; PIL can't currently do that,
        # but it can do RGBA, which we can use by inserting one null
        # up frontpm =
        if im.mode != 'RGBA': im = im.convert('RGBA')
        data = chr(0) + im.tostring()
        self.fromstring(data, im.size[0], im.size[1])

    def toImage(self):
        """Return the contents of this PixMap as a PIL Image object."""
        import Image
        # our tostring() method returns data in ARGB format,
        # whereas Image uses RGBA; a bit of slicing fixes this...
        data = self.tostring()[1:] + chr(0)
        bounds = self.bounds
        return Image.fromstring('RGBA',(bounds[2]-bounds[0],bounds[3]-bounds[1]),data)

def test():
    import MacOS
    import EasyDialogs
    import Image
    path = EasyDialogs.AskFileForOpen("Image File:")
    if not path: return
    pm = PixMapWrapper()
    pm.fromImage( Image.open(path) )
    pm.blit(20,20)
    return pm
