"""MiniAEFrame - A minimal AppleEvent Application framework.

There are two classes:
	AEServer -- a mixin class offering nice AE handling.
	MiniApplication -- a very minimal alternative to FrameWork.py,
		only suitable for the simplest of AppleEvent servers.
"""

import sys
import traceback
import MacOS
import AE
from AppleEvents import *
import Evt
from Events import *
import Menu
import Win
from Windows import *
import Qd

import aetools
import EasyDialogs

kHighLevelEvent = 23				# Not defined anywhere for Python yet?


class MiniApplication:
	
	"""A minimal FrameWork.Application-like class"""
	
	def __init__(self):
		self.quitting = 0
		# Initialize menu
		self.appleid = 1
		self.quitid = 2
		Menu.ClearMenuBar()
		self.applemenu = applemenu = Menu.NewMenu(self.appleid, "\024")
		applemenu.AppendMenu("%s;(-" % self.getaboutmenutext())
		if MacOS.runtimemodel == 'ppc':
			applemenu.AppendResMenu('DRVR')
		applemenu.InsertMenu(0)
		self.quitmenu = Menu.NewMenu(self.quitid, "File")
		self.quitmenu.AppendMenu("Quit")
		self.quitmenu.SetItemCmd(1, ord("Q"))
		self.quitmenu.InsertMenu(0)
		Menu.DrawMenuBar()
	
	def __del__(self):
		self.close()
	
	def close(self):
		pass
	
	def mainloop(self, mask = everyEvent, timeout = 60*60):
		while not self.quitting:
			self.dooneevent(mask, timeout)
	
	def _quit(self):
		self.quitting = 1
	
	def dooneevent(self, mask = everyEvent, timeout = 60*60):
			got, event = Evt.WaitNextEvent(mask, timeout)
			if got:
				self.lowlevelhandler(event)
	
	def lowlevelhandler(self, event):
		what, message, when, where, modifiers = event
		h, v = where
		if what == kHighLevelEvent:
			msg = "High Level Event: %s %s" % \
				(`code(message)`, `code(h | (v<<16))`)
			try:
				AE.AEProcessAppleEvent(event)
			except AE.Error, err:
				print 'AE error: ', err
				print 'in', msg
				traceback.print_exc()
			return
		elif what == keyDown:
			c = chr(message & charCodeMask)
			if modifiers & cmdKey:
				if c == '.':
					raise KeyboardInterrupt, "Command-period"
				if c == 'q':
					MacOS.OutputSeen()
					self.quitting = 1
					return
		elif what == mouseDown:
			partcode, window = Win.FindWindow(where)
			if partcode == inMenuBar:
				result = Menu.MenuSelect(where)
				id = (result>>16) & 0xffff	# Hi word
				item = result & 0xffff		# Lo word
				if id == self.appleid:
					if item == 1:
						EasyDialogs.Message(self.getabouttext())
					elif item > 1 and hasattr(Menu, 'OpenDeskAcc'):
						name = self.applemenu.GetMenuItemText(item)
						Menu.OpenDeskAcc(name)
				elif id == self.quitid and item == 1:
					MacOS.OutputSeen()
					self.quitting = 1
				Menu.HiliteMenu(0)
				return
		# Anything not handled is passed to Python/SIOUX
		MacOS.HandleEvent(event)
	
	def getabouttext(self):
		return self.__class__.__name__
	
	def getaboutmenutext(self):
		return "About %s\311" % self.__class__.__name__


class AEServer:
	
	def __init__(self):
		self.ae_handlers = {}
	
	def installaehandler(self, classe, type, callback):
		AE.AEInstallEventHandler(classe, type, self.callback_wrapper)
		self.ae_handlers[(classe, type)] = callback
	
	def close(self):
		for classe, type in self.ae_handlers.keys():
			AE.AERemoveEventHandler(classe, type)
	
	def callback_wrapper(self, _request, _reply):
		_parameters, _attributes = aetools.unpackevent(_request)
		_class = _attributes['evcl'].type
		_type = _attributes['evid'].type
		
		if self.ae_handlers.has_key((_class, _type)):
			_function = self.ae_handlers[(_class, _type)]
		elif self.ae_handlers.has_key((_class, '****')):
			_function = self.ae_handlers[(_class, '****')]
		elif self.ae_handlers.has_key(('****', '****')):
			_function = self.ae_handlers[('****', '****')]
		else:
			raise 'Cannot happen: AE callback without handler', (_class, _type)
		
		# XXXX Do key-to-name mapping here
		
		_parameters['_attributes'] = _attributes
		_parameters['_class'] = _class
		_parameters['_type'] = _type
		if _parameters.has_key('----'):
			_object = _parameters['----']
			del _parameters['----']
			# The try/except that used to be here can mask programmer errors.
			# Let the program crash, the programmer can always add a **args
			# to the formal parameter list.
			rv = apply(_function, (_object,), _parameters)
		else:
			#Same try/except comment as above
			rv = apply(_function, (), _parameters)
		
		if rv == None:
			aetools.packevent(_reply, {})
		else:
			aetools.packevent(_reply, {'----':rv})


def code(x):
	"Convert a long int to the 4-character code it really is"
	s = ''
	for i in range(4):
		x, c = divmod(x, 256)
		s = chr(c) + s
	return s

class _Test(AEServer, MiniApplication):
	"""Mini test application, handles required events"""
	
	def __init__(self):
		MiniApplication.__init__(self)
		AEServer.__init__(self)
		self.installaehandler('aevt', 'oapp', self.open_app)
		self.installaehandler('aevt', 'quit', self.quit)
		self.installaehandler('****', '****', self.other)
		self.mainloop()

	def quit(self, **args):
		self._quit()
		
	def open_app(self, **args):
		pass
		
	def other(self, _object=None, _class=None, _type=None, **args):
		print 'AppleEvent', (_class, _type), 'for', _object, 'Other args:', args
		

if __name__ == '__main__':
	_Test()
