"""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.
#

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

import struct
import types
from types import *
from Carbon import AE
from Carbon.AppleEvents import *
import MacOS
import Carbon.File
import aetypes
from aetypes import mkenum, ObjectSpecifier

# 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
try:
    FSSType = Carbon.File.FSSpecType
except AttributeError:
    class FSSType:
        pass
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 is 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 t in unpacker_coercions:
        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)
