# This script will generate the AppleEvents interface for Python.
# It uses the "bgen" package to generate C code.
# It execs the file aegen.py which contain the function definitions
# (aegen.py was generated by aescan.py, scanning the <AppleEvents.h> header file).


from macsupport import *


AEArrayType = Type("AEArrayType", "c")
AESendMode = Type("AESendMode", "l")
AESendPriority = Type("AESendPriority", "h")
AEInteractAllowed = Type("AEInteractAllowed", "b")
AEReturnID = Type("AEReturnID", "h")
AETransactionID = Type("AETransactionID", "l")



AEEventClass = OSTypeType('AEEventClass')
AEEventID = OSTypeType('AEEventID')
AEKeyword = OSTypeType('AEKeyword')
DescType = OSTypeType('DescType')


AEDesc = OpaqueType('AEDesc')
AEDesc_ptr = OpaqueType('AEDesc')

AEAddressDesc = OpaqueType('AEAddressDesc', 'AEDesc')
AEAddressDesc_ptr = OpaqueType('AEAddressDesc', 'AEDesc')

AEDescList = OpaqueType('AEDescList', 'AEDesc')
AEDescList_ptr = OpaqueType('AEDescList', 'AEDesc')

AERecord = OpaqueType('AERecord', 'AEDesc')
AERecord_ptr = OpaqueType('AERecord', 'AEDesc')

AppleEvent = OpaqueType('AppleEvent', 'AEDesc')
AppleEvent_ptr = OpaqueType('AppleEvent', 'AEDesc')


class EHType(Type):
	def __init__(self, name = 'EventHandler', format = ''):
		Type.__init__(self, name, format)
	def declare(self, name):
		Output("AEEventHandlerUPP %s__proc__ = upp_GenericEventHandler;", name)
		Output("PyObject *%s;", name)
	def getargsFormat(self):
		return "O"
	def getargsArgs(self, name):
		return "&%s" % name
	def passInput(self, name):
		return "%s__proc__, (long)%s" % (name, name)
	def passOutput(self, name):
		return "&%s__proc__, (long *)&%s" % (name, name)
	def mkvalueFormat(self):
		return "O"
	def mkvalueArgs(self, name):
		return name
	def cleanup(self, name):
		Output("Py_INCREF(%s); /* XXX leak, but needed */", name)

class EHNoRefConType(EHType):
	def passInput(self, name):
		return "upp_GenericEventHandler"

EventHandler = EHType()
EventHandlerNoRefCon = EHNoRefConType()


IdleProcPtr = FakeType("upp_AEIdleProc")
AEIdleUPP = IdleProcPtr
EventFilterProcPtr = FakeType("(AEFilterUPP)0")
AEFilterUPP = EventFilterProcPtr
NMRecPtr = FakeType("(NMRecPtr)0")
EventHandlerProcPtr = FakeType("upp_GenericEventHandler")
AEEventHandlerUPP = EventHandlerProcPtr
AlwaysFalse = FakeType("0")


AEFunction = OSErrFunctionGenerator
AEMethod = OSErrMethodGenerator


includestuff = includestuff + """
#include <AppleEvents.h>
#include <AEObjects.h>

static pascal OSErr GenericEventHandler(); /* Forward */

AEEventHandlerUPP upp_GenericEventHandler;

static pascal Boolean AEIdleProc(EventRecord *theEvent, long *sleepTime, RgnHandle *mouseRgn)
{
	if ( PyOS_InterruptOccurred() )
		return 1;
	if ( PyMac_HandleEvent(theEvent) < 0 ) {
		PySys_WriteStderr("Exception in user event handler during AE processing\\n");
		PyErr_Clear();
	}
	return 0;
}

AEIdleUPP upp_AEIdleProc;
"""

finalstuff = finalstuff + """
static pascal OSErr
GenericEventHandler(const AppleEvent *request, AppleEvent *reply, unsigned long refcon)
{
	PyObject *handler = (PyObject *)refcon;
	AEDescObject *requestObject, *replyObject;
	PyObject *args, *res;
	if ((requestObject = (AEDescObject *)AEDesc_New((AppleEvent *)request)) == NULL) {
		return -1;
	}
	if ((replyObject = (AEDescObject *)AEDesc_New(reply)) == NULL) {
		Py_DECREF(requestObject);
		return -1;
	}
	if ((args = Py_BuildValue("OO", requestObject, replyObject)) == NULL) {
		Py_DECREF(requestObject);
		Py_DECREF(replyObject);
		return -1;
	}
	res = PyEval_CallObject(handler, args);
	requestObject->ob_itself.descriptorType = 'null';
	requestObject->ob_itself.dataHandle = NULL;
	replyObject->ob_itself.descriptorType = 'null';
	replyObject->ob_itself.dataHandle = NULL;
	Py_DECREF(args);
	if (res == NULL)
		return -1;
	Py_DECREF(res);
	return noErr;
}
"""

initstuff = initstuff + """
	upp_AEIdleProc = NewAEIdleProc(AEIdleProc);
	upp_GenericEventHandler = NewAEEventHandlerProc(GenericEventHandler);
"""

module = MacModule('AE', 'AE', includestuff, finalstuff, initstuff)

class AEDescDefinition(GlobalObjectDefinition):

	def __init__(self, name, prefix = None, itselftype = None):
		GlobalObjectDefinition.__init__(self, name, prefix or name, itselftype or name)
		self.argref = "*"

	def outputFreeIt(self, name):
		Output("AEDisposeDesc(&%s);", name)

	def outputGetattrHook(self):
		Output("""
if (strcmp(name, "type") == 0)
	return PyMac_BuildOSType(self->ob_itself.descriptorType);
if (strcmp(name, "data") == 0) {
	PyObject *res;
#if !TARGET_API_MAC_CARBON
	char state;
	state = HGetState(self->ob_itself.dataHandle);
	HLock(self->ob_itself.dataHandle);
	res = PyString_FromStringAndSize(
		*self->ob_itself.dataHandle,
		GetHandleSize(self->ob_itself.dataHandle));
	HUnlock(self->ob_itself.dataHandle);
	HSetState(self->ob_itself.dataHandle, state);
#else
	Size size;
	char *ptr;
	OSErr err;
	
	size = AEGetDescDataSize(&self->ob_itself);
	if ( (res = PyString_FromStringAndSize(NULL, size)) == NULL )
		return NULL;
	if ( (ptr = PyString_AsString(res)) == NULL )
		return NULL;
	if ( (err=AEGetDescData(&self->ob_itself, ptr, size)) < 0 )
		return PyMac_Error(err);	
#endif
	return res;
}
if (strcmp(name, "__members__") == 0)
	return Py_BuildValue("[ss]", "data", "type");
""")


aedescobject = AEDescDefinition('AEDesc')
module.addobject(aedescobject)

functions = []
aedescmethods = []

execfile('aegen.py')
##execfile('aedatamodelgen.py')

for f in functions: module.add(f)
for f in aedescmethods: aedescobject.add(f)

SetOutputFileName('AEmodule.c')
module.generate()
