"""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 macfs
import StringIO
import aetypes
from aetypes import mkenum, mktype
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 = macfs.FSSpecType
AliasType = macfs.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', '')
		
	t = type(x)
	if t == AEDescType:
		return x
	if t == FSSType:
		return AE.AECreateDesc('fss ', x.data)
	if t == AliasType:
		return AE.AECreateDesc('alis', x.data)
	if t == IntType:
		return AE.AECreateDesc('long', struct.pack('l', x))
	if t == FloatType:
		return AE.AECreateDesc('doub', struct.pack('d', x))
	if t == StringType:
		return AE.AECreateDesc('TEXT', x)
	if t == UnicodeType:
		data = t.encode('utf16')
		if data[:2] == '\xfe\xff':
			data = data[2:]
		return AE.AECreateDesc('utxt', data)
	if t == ListType:
		list = AE.AECreateList('', 0)
		for item in x:
			list.AEPutDesc(0, pack(item))
		return list
	if t == DictionaryType:
		record = AE.AECreateList('', 1)
		for key, value in x.items():
			packkey(record, key, value)
			#record.AEPutParamDesc(key, pack(value))
		return record
	if t == InstanceType and 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 macfs.RawAlias(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 macfs.RawFSSpec(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)
	#
	# 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):
	want = dict['want'].type
	module = __import__(modulename)
	codenamemapper = module._classdeclarations
	classtype = codenamemapper.get(want, None)
	newobj = mkobject(dict)
	if classtype:
		newobj.__class__ = classtype
	return newobj

def _test():
	"""Test program. Pack and unpack various things"""
	objs = [
		'a string',
		12,
		12.0,
		None,
		['a', 'list', 'of', 'strings'],
		{'key1': 'value1', 'key2':'value2'},
		macfs.FSSpec(':'),
		macfs.FSSpec(':').NewAliasMinimal(),
		aetypes.Enum('enum'),
		aetypes.Type('type'),
		aetypes.Keyword('kwrd'),
		aetypes.Range(1, 10),
		aetypes.Comparison(1, '<   ', 10),
		aetypes.Logical('not ', 1),
		# Cannot do StyledText
		# Cannot do AEText
		aetypes.IntlText(0, 0, 'international text'),
		aetypes.IntlWritingCode(0,0),
		aetypes.QDPoint(50,100),
		aetypes.QDRectangle(50,100,150,200),
		aetypes.RGBColor(0x7000, 0x6000, 0x5000),
		aetypes.Unknown('xxxx', 'unknown type data'),
		aetypes.Character(1),
		aetypes.Character(2, aetypes.Line(2)),
	]
	for o in objs:
		print 'BEFORE', o, `o`
		packed = pack(o)
		unpacked = unpack(packed)
		print 'AFTER ', unpacked, `unpacked`
	import sys
	sys.exit(1)
	
if __name__ == '__main__':
	_test()
	
