"""Tools for use in AppleEvent clients and servers:
conversion between AE types and python types

pack(x) converts a Python object to an AEDesc object
unpack(desc) does the reverse
coerce(x, wanted_sample) coerces a python object to another python object
"""

#
# This code was originally written by Guido, and modified/extended by Jack
# to include the various types that were missing. The reference used is
# Apple Event Registry, chapter 9.
#

import struct
import string
import types
from string import strip
from types import *
from Carbon import AE
from Carbon.AppleEvents import *
import MacOS
import Carbon.File
import StringIO
import aetypes
from aetypes import mkenum, ObjectSpecifier
import os

# These ones seem to be missing from AppleEvents
# (they're in AERegistry.h)

#typeColorTable = 'clrt'
#typeDrawingArea = 'cdrw'
#typePixelMap = 'cpix'
#typePixelMapMinus = 'tpmm'
#typeRotation = 'trot'
#typeTextStyles = 'tsty'
#typeStyledText = 'STXT'
#typeAEText = 'tTXT'
#typeEnumeration = 'enum'

#
# Some AE types are immedeately coerced into something
# we like better (and which is equivalent)
#
unpacker_coercions = {
    typeComp : typeFloat,
    typeColorTable : typeAEList,
    typeDrawingArea : typeAERecord,
    typeFixed : typeFloat,
    typeExtended : typeFloat,
    typePixelMap : typeAERecord,
    typeRotation : typeAERecord,
    typeStyledText : typeAERecord,
    typeTextStyles : typeAERecord,
};

#
# Some python types we need in the packer:
#
AEDescType = AE.AEDescType
FSSType = Carbon.File.FSSpecType
FSRefType = Carbon.File.FSRefType
AliasType = Carbon.File.AliasType

def packkey(ae, key, value):
    if hasattr(key, 'which'):
        keystr = key.which
    elif hasattr(key, 'want'):
        keystr = key.want
    else:
        keystr = key
    ae.AEPutParamDesc(keystr, pack(value))

def pack(x, forcetype = None):
    """Pack a python object into an AE descriptor"""

    if forcetype:
        if type(x) is StringType:
            return AE.AECreateDesc(forcetype, x)
        else:
            return pack(x).AECoerceDesc(forcetype)

    if x == None:
        return AE.AECreateDesc('null', '')

    if isinstance(x, AEDescType):
        return x
    if isinstance(x, FSSType):
        return AE.AECreateDesc('fss ', x.data)
    if isinstance(x, FSRefType):
        return AE.AECreateDesc('fsrf', x.data)
    if isinstance(x, AliasType):
        return AE.AECreateDesc('alis', x.data)
    if isinstance(x, IntType):
        return AE.AECreateDesc('long', struct.pack('l', x))
    if isinstance(x, FloatType):
        return AE.AECreateDesc('doub', struct.pack('d', x))
    if isinstance(x, StringType):
        return AE.AECreateDesc('TEXT', x)
    if isinstance(x, UnicodeType):
        data = x.encode('utf16')
        if data[:2] == '\xfe\xff':
            data = data[2:]
        return AE.AECreateDesc('utxt', data)
    if isinstance(x, ListType):
        list = AE.AECreateList('', 0)
        for item in x:
            list.AEPutDesc(0, pack(item))
        return list
    if isinstance(x, DictionaryType):
        record = AE.AECreateList('', 1)
        for key, value in x.items():
            packkey(record, key, value)
            #record.AEPutParamDesc(key, pack(value))
        return record
    if type(x) == types.ClassType and issubclass(x, ObjectSpecifier):
        # Note: we are getting a class object here, not an instance
        return AE.AECreateDesc('type', x.want)
    if hasattr(x, '__aepack__'):
        return x.__aepack__()
    if hasattr(x, 'which'):
        return AE.AECreateDesc('TEXT', x.which)
    if hasattr(x, 'want'):
        return AE.AECreateDesc('TEXT', x.want)
    return AE.AECreateDesc('TEXT', repr(x)) # Copout

def unpack(desc, formodulename=""):
    """Unpack an AE descriptor to a python object"""
    t = desc.type

    if unpacker_coercions.has_key(t):
        desc = desc.AECoerceDesc(unpacker_coercions[t])
        t = desc.type # This is a guess by Jack....

    if t == typeAEList:
        l = []
        for i in range(desc.AECountItems()):
            keyword, item = desc.AEGetNthDesc(i+1, '****')
            l.append(unpack(item, formodulename))
        return l
    if t == typeAERecord:
        d = {}
        for i in range(desc.AECountItems()):
            keyword, item = desc.AEGetNthDesc(i+1, '****')
            d[keyword] = unpack(item, formodulename)
        return d
    if t == typeAEText:
        record = desc.AECoerceDesc('reco')
        return mkaetext(unpack(record, formodulename))
    if t == typeAlias:
        return Carbon.File.Alias(rawdata=desc.data)
    # typeAppleEvent returned as unknown
    if t == typeBoolean:
        return struct.unpack('b', desc.data)[0]
    if t == typeChar:
        return desc.data
    if t == typeUnicodeText:
        return unicode(desc.data, 'utf16')
    # typeColorTable coerced to typeAEList
    # typeComp coerced to extended
    # typeData returned as unknown
    # typeDrawingArea coerced to typeAERecord
    if t == typeEnumeration:
        return mkenum(desc.data)
    # typeEPS returned as unknown
    if t == typeFalse:
        return 0
    if t == typeFloat:
        data = desc.data
        return struct.unpack('d', data)[0]
    if t == typeFSS:
        return Carbon.File.FSSpec(rawdata=desc.data)
    if t == typeFSRef:
        return Carbon.File.FSRef(rawdata=desc.data)
    if t == typeInsertionLoc:
        record = desc.AECoerceDesc('reco')
        return mkinsertionloc(unpack(record, formodulename))
    # typeInteger equal to typeLongInteger
    if t == typeIntlText:
        script, language = struct.unpack('hh', desc.data[:4])
        return aetypes.IntlText(script, language, desc.data[4:])
    if t == typeIntlWritingCode:
        script, language = struct.unpack('hh', desc.data)
        return aetypes.IntlWritingCode(script, language)
    if t == typeKeyword:
        return mkkeyword(desc.data)
    if t == typeLongInteger:
        return struct.unpack('l', desc.data)[0]
    if t == typeLongDateTime:
        a, b = struct.unpack('lL', desc.data)
        return (long(a) << 32) + b
    if t == typeNull:
        return None
    if t == typeMagnitude:
        v = struct.unpack('l', desc.data)
        if v < 0:
            v = 0x100000000L + v
        return v
    if t == typeObjectSpecifier:
        record = desc.AECoerceDesc('reco')
        # If we have been told the name of the module we are unpacking aedescs for,
        # we can attempt to create the right type of python object from that module.
        if formodulename:
            return mkobjectfrommodule(unpack(record, formodulename), formodulename)
        return mkobject(unpack(record, formodulename))
    # typePict returned as unknown
    # typePixelMap coerced to typeAERecord
    # typePixelMapMinus returned as unknown
    # typeProcessSerialNumber returned as unknown
    if t == typeQDPoint:
        v, h = struct.unpack('hh', desc.data)
        return aetypes.QDPoint(v, h)
    if t == typeQDRectangle:
        v0, h0, v1, h1 = struct.unpack('hhhh', desc.data)
        return aetypes.QDRectangle(v0, h0, v1, h1)
    if t == typeRGBColor:
        r, g, b = struct.unpack('hhh', desc.data)
        return aetypes.RGBColor(r, g, b)
    # typeRotation coerced to typeAERecord
    # typeScrapStyles returned as unknown
    # typeSessionID returned as unknown
    if t == typeShortFloat:
        return struct.unpack('f', desc.data)[0]
    if t == typeShortInteger:
        return struct.unpack('h', desc.data)[0]
    # typeSMFloat identical to typeShortFloat
    # typeSMInt indetical to typeShortInt
    # typeStyledText coerced to typeAERecord
    if t == typeTargetID:
        return mktargetid(desc.data)
    # typeTextStyles coerced to typeAERecord
    # typeTIFF returned as unknown
    if t == typeTrue:
        return 1
    if t == typeType:
        return mktype(desc.data, formodulename)
    #
    # The following are special
    #
    if t == 'rang':
        record = desc.AECoerceDesc('reco')
        return mkrange(unpack(record, formodulename))
    if t == 'cmpd':
        record = desc.AECoerceDesc('reco')
        return mkcomparison(unpack(record, formodulename))
    if t == 'logi':
        record = desc.AECoerceDesc('reco')
        return mklogical(unpack(record, formodulename))
    return mkunknown(desc.type, desc.data)

def coerce(data, egdata):
    """Coerce a python object to another type using the AE coercers"""
    pdata = pack(data)
    pegdata = pack(egdata)
    pdata = pdata.AECoerceDesc(pegdata.type)
    return unpack(pdata)

#
# Helper routines for unpack
#
def mktargetid(data):
    sessionID = getlong(data[:4])
    name = mkppcportrec(data[4:4+72])
    location = mklocationnamerec(data[76:76+36])
    rcvrName = mkppcportrec(data[112:112+72])
    return sessionID, name, location, rcvrName

def mkppcportrec(rec):
    namescript = getword(rec[:2])
    name = getpstr(rec[2:2+33])
    portkind = getword(rec[36:38])
    if portkind == 1:
        ctor = rec[38:42]
        type = rec[42:46]
        identity = (ctor, type)
    else:
        identity = getpstr(rec[38:38+33])
    return namescript, name, portkind, identity

def mklocationnamerec(rec):
    kind = getword(rec[:2])
    stuff = rec[2:]
    if kind == 0: stuff = None
    if kind == 2: stuff = getpstr(stuff)
    return kind, stuff

def mkunknown(type, data):
    return aetypes.Unknown(type, data)

def getpstr(s):
    return s[1:1+ord(s[0])]

def getlong(s):
    return (ord(s[0])<<24) | (ord(s[1])<<16) | (ord(s[2])<<8) | ord(s[3])

def getword(s):
    return (ord(s[0])<<8) | (ord(s[1])<<0)

def mkkeyword(keyword):
    return aetypes.Keyword(keyword)

def mkrange(dict):
    return aetypes.Range(dict['star'], dict['stop'])

def mkcomparison(dict):
    return aetypes.Comparison(dict['obj1'], dict['relo'].enum, dict['obj2'])

def mklogical(dict):
    return aetypes.Logical(dict['logc'], dict['term'])

def mkstyledtext(dict):
    return aetypes.StyledText(dict['ksty'], dict['ktxt'])

def mkaetext(dict):
    return aetypes.AEText(dict[keyAEScriptTag], dict[keyAEStyles], dict[keyAEText])

def mkinsertionloc(dict):
    return aetypes.InsertionLoc(dict[keyAEObject], dict[keyAEPosition])

def mkobject(dict):
    want = dict['want'].type
    form = dict['form'].enum
    seld = dict['seld']
    fr   = dict['from']
    if form in ('name', 'indx', 'rang', 'test'):
        if want == 'text': return aetypes.Text(seld, fr)
        if want == 'cha ': return aetypes.Character(seld, fr)
        if want == 'cwor': return aetypes.Word(seld, fr)
        if want == 'clin': return aetypes.Line(seld, fr)
        if want == 'cpar': return aetypes.Paragraph(seld, fr)
        if want == 'cwin': return aetypes.Window(seld, fr)
        if want == 'docu': return aetypes.Document(seld, fr)
        if want == 'file': return aetypes.File(seld, fr)
        if want == 'cins': return aetypes.InsertionPoint(seld, fr)
    if want == 'prop' and form == 'prop' and aetypes.IsType(seld):
        return aetypes.Property(seld.type, fr)
    return aetypes.ObjectSpecifier(want, form, seld, fr)

# Note by Jack: I'm not 100% sure of the following code. This was
# provided by Donovan Preston, but I wonder whether the assignment
# to __class__ is safe. Moreover, shouldn't there be a better
# initializer for the classes in the suites?
def mkobjectfrommodule(dict, modulename):
    if type(dict['want']) == types.ClassType and issubclass(dict['want'], ObjectSpecifier):
        # The type has already been converted to Python. Convert back:-(
        classtype = dict['want']
        dict['want'] = aetypes.mktype(classtype.want)
    want = dict['want'].type
    module = __import__(modulename)
    codenamemapper = module._classdeclarations
    classtype = codenamemapper.get(want, None)
    newobj = mkobject(dict)
    if classtype:
        assert issubclass(classtype, ObjectSpecifier)
        newobj.__class__ = classtype
    return newobj

def mktype(typecode, modulename=None):
    if modulename:
        module = __import__(modulename)
        codenamemapper = module._classdeclarations
        classtype = codenamemapper.get(typecode, None)
        if classtype:
            return classtype
    return aetypes.mktype(typecode)
