"A sort of application framework for the Mac"

DEBUG=0

import MacOS
import traceback

from Carbon.AE import *
from Carbon.AppleEvents import *
from Carbon.Ctl import *
from Carbon.Controls import *
from Carbon.Dlg import *
from Carbon.Dialogs import *
from Carbon.Evt import *
from Carbon.Events import *
from Carbon.Menu import *
from Carbon.Menus import *
from Carbon.Qd import *
from Carbon.QuickDraw import *
#from Carbon.Res import *
#from Carbon.Resources import *
#from Carbon.Snd import *
#from Carbon.Sound import *
from Carbon.Win import *
from Carbon.Windows import *
import types

import EasyDialogs

kHighLevelEvent = 23	# Don't know what header file this should come from
SCROLLBARWIDTH = 16		# Again, not a clue...

# Trick to forestall a set of SIOUX menus being added to our menubar
SIOUX_APPLEMENU_ID=32000


# Map event 'what' field to strings
eventname = {}
eventname[1] = 'mouseDown'
eventname[2] = 'mouseUp'
eventname[3] = 'keyDown'
eventname[4] = 'keyUp'
eventname[5] = 'autoKey'
eventname[6] = 'updateEvt'
eventname[7] = 'diskEvt'
eventname[8] = 'activateEvt'
eventname[15] = 'osEvt'
eventname[23] = 'kHighLevelEvent'

# Map part codes returned by WhichWindow() to strings
partname = {}
partname[0] = 'inDesk'
partname[1] = 'inMenuBar'
partname[2] = 'inSysWindow'
partname[3] = 'inContent'
partname[4] = 'inDrag'
partname[5] = 'inGrow'
partname[6] = 'inGoAway'
partname[7] = 'inZoomIn'
partname[8] = 'inZoomOut'

#
# The useable portion of the screen
#	## but what happens with multiple screens? jvr
screenbounds = qd.screenBits.bounds
screenbounds = screenbounds[0]+4, screenbounds[1]+4, \
	screenbounds[2]-4, screenbounds[3]-4
	
next_window_x = 16		# jvr
next_window_y = 44		# jvr

def windowbounds(width, height):
	"Return sensible window bounds"
	global next_window_x, next_window_y
	r, b = next_window_x+width, next_window_y+height
	if r > screenbounds[2]:
		next_window_x = 16
	if b > screenbounds[3]:
		next_window_y = 44
	l, t = next_window_x, next_window_y
	r, b = next_window_x+width, next_window_y+height
	next_window_x, next_window_y = next_window_x + 8, next_window_y + 20	# jvr
	return l, t, r, b

_watch = None
def setwatchcursor():
	global _watch
	
	if _watch == None:
		_watch = GetCursor(4).data
	SetCursor(_watch)
	
def setarrowcursor():
	SetCursor(qd.arrow)

class Application:
	
	"Application framework -- your application should be a derived class"
	
	def __init__(self, nomenubar=0):
		self._doing_asyncevents = 0
		self.quitting = 0
		self.needmenubarredraw = 0
		self._windows = {}
		if nomenubar:
			self.menubar = None
		else:
			self.makemenubar()
			
	def __del__(self):
		if self._doing_asyncevents:
			self._doing_asyncevents = 0
			MacOS.SetEventHandler()
	
	def makemenubar(self):
		self.menubar = MenuBar(self)
		AppleMenu(self.menubar, self.getabouttext(), self.do_about)
		self.makeusermenus()

	def makeusermenus(self):
		self.filemenu = m = Menu(self.menubar, "File")
		self._quititem = MenuItem(m, "Quit", "Q", self._quit)
	
	def _quit(self, *args):
		self.quitting = 1
		
	def cleanup(self):
		for w in self._windows.values():
			w.do_close()
		return self._windows == {}
		
	def appendwindow(self, wid, window):
		self._windows[wid] = window
		
	def removewindow(self, wid):
		del self._windows[wid]
	
	def getabouttext(self):
		return "About %s..." % self.__class__.__name__
	
	def do_about(self, id, item, window, event):
		EasyDialogs.Message("Hello, world!" + "\015(%s)" % self.__class__.__name__)
	
	# The main event loop is broken up in several simple steps.
	# This is done so you can override each individual part,
	# if you have a need to do extra processing independent of the
	# event type.
	# Normally, however, you'd just define handlers for individual
	# events.
	
	schedparams = (0, 0)	# By default disable Python's event handling
	default_wait = None		# By default we wait GetCaretTime in WaitNextEvent
	
	def mainloop(self, mask = everyEvent, wait = None):
		self.quitting = 0
		saveparams = apply(MacOS.SchedParams, self.schedparams)
		try:
			while not self.quitting:
				try:
					self.do1event(mask, wait)
				except (Application, SystemExit):
					# Note: the raising of "self" is old-fashioned idiom to
					# exit the mainloop. Calling _quit() is better for new
					# applications.
					break
		finally:
			apply(MacOS.SchedParams, saveparams)
	
	def dopendingevents(self, mask = everyEvent):
		"""dopendingevents - Handle all pending events"""
		while self.do1event(mask, wait=0):
			pass
	
	def do1event(self, mask = everyEvent, wait = None):
		ok, event = self.getevent(mask, wait)
		if IsDialogEvent(event):
			if self.do_dialogevent(event):
				return
		if ok:
			self.dispatch(event)
		else:
			self.idle(event)
			
	def idle(self, event):
		pass
	
	def getevent(self, mask = everyEvent, wait = None):
		if self.needmenubarredraw:
			DrawMenuBar()
			self.needmenubarredraw = 0
		if wait is None:
			wait = self.default_wait
			if wait is None:
				wait = GetCaretTime()
		ok, event = WaitNextEvent(mask, wait)
		return ok, event
			
	def dispatch(self, event):
		# The following appears to be double work (already done in do1event)
		# but we need it for asynchronous event handling
		if IsDialogEvent(event):
			if self.do_dialogevent(event):
				return
		(what, message, when, where, modifiers) = event
		if eventname.has_key(what):
			name = "do_" + eventname[what]
		else:
			name = "do_%d" % what
		try:
			handler = getattr(self, name)
		except AttributeError:
			handler = self.do_unknownevent
		handler(event)
		
	def asyncevents(self, onoff):
		"""asyncevents - Set asynchronous event handling on or off"""
		old = self._doing_asyncevents
		if old:
			MacOS.SetEventHandler()
			apply(MacOS.SchedParams, self.schedparams)
		if onoff:
			MacOS.SetEventHandler(self.dispatch)
			doint, dummymask, benice, howoften, bgyield = \
			       self.schedparams
			MacOS.SchedParams(doint, everyEvent, benice,
					  howoften, bgyield)
		self._doing_asyncevents = onoff
		return old
			
	def do_dialogevent(self, event):
		gotone, dlg, item = DialogSelect(event)
		if gotone:
			window = dlg.GetDialogWindow()
			if self._windows.has_key(window):
				self._windows[window].do_itemhit(item, event)
			else:
				print 'Dialog event for unknown dialog'
			return 1
		return 0
	
	def do_mouseDown(self, event):
		(what, message, when, where, modifiers) = event
		partcode, wid = FindWindow(where)

		#
		# Find the correct name.
		#
		if partname.has_key(partcode):
			name = "do_" + partname[partcode]
		else:
			name = "do_%d" % partcode

		if wid == None:
			# No window, or a non-python window	
			try:
				handler = getattr(self, name)
			except AttributeError:
				# Not menubar or something, so assume someone
				# else's window
				MacOS.HandleEvent(event)
				return		
		elif self._windows.has_key(wid):
			# It is a window. Hand off to correct window.
			window = self._windows[wid]
			try:
				handler = getattr(window, name)
			except AttributeError:
				handler = self.do_unknownpartcode
		else:
			# It is a python-toolbox window, but not ours.
			handler = self.do_unknownwindow
		handler(partcode, wid, event)

	def do_inSysWindow(self, partcode, window, event):
		MacOS.HandleEvent(event)
	
	def do_inDesk(self, partcode, window, event):
		MacOS.HandleEvent(event)
	
	def do_inMenuBar(self, partcode, window, event):
		if not self.menubar:
			MacOS.HandleEvent(event)
			return
		(what, message, when, where, modifiers) = event
		result = MenuSelect(where)
		id = (result>>16) & 0xffff	# Hi word
		item = result & 0xffff		# Lo word
		self.do_rawmenu(id, item, window, event)
	
	def do_rawmenu(self, id, item, window, event):
		try:
			self.do_menu(id, item, window, event)
		finally:
			HiliteMenu(0)
	
	def do_menu(self, id, item, window, event):
		MacOS.OutputSeen()
		self.menubar.dispatch(id, item, window, event)
	
	
	def do_unknownpartcode(self, partcode, window, event):
		(what, message, when, where, modifiers) = event
		if DEBUG: print "Mouse down at global:", where
		if DEBUG: print "\tUnknown part code:", partcode
		if DEBUG: print "\tEvent:", self.printevent(event)
		MacOS.HandleEvent(event)
		
	def do_unknownwindow(self, partcode, window, event):
		if DEBUG: print 'Unknown window:', window
		MacOS.HandleEvent(event)
	
	def do_keyDown(self, event):
		self.do_key(event)
	
	def do_autoKey(self, event):
		if not event[-1] & cmdKey:
			self.do_key(event)
	
	def do_key(self, event):
		(what, message, when, where, modifiers) = event
		c = chr(message & charCodeMask)
		if self.menubar:
			result = MenuEvent(event)
			id = (result>>16) & 0xffff	# Hi word
			item = result & 0xffff		# Lo word
			if id:
				self.do_rawmenu(id, item, None, event)
				return
			# Otherwise we fall-through
		if modifiers & cmdKey:
			if c == '.':
				raise self
			else:
				if not self.menubar:
					MacOS.HandleEvent(event)
				return
		else:
			# See whether the front window wants it
			w = FrontWindow()
			if w and self._windows.has_key(w):
				window = self._windows[w]
				try:
					do_char = window.do_char
				except AttributeError:
					do_char = self.do_char
				do_char(c, event)
			# else it wasn't for us, sigh...
	
	def do_char(self, c, event):
		if DEBUG: print "Character", `c`
	
	def do_updateEvt(self, event):
		(what, message, when, where, modifiers) = event
		wid = WhichWindow(message)
		if wid and self._windows.has_key(wid):
			window = self._windows[wid]
			window.do_rawupdate(wid, event)
		else:
			MacOS.HandleEvent(event)
	
	def do_activateEvt(self, event):
		(what, message, when, where, modifiers) = event
		wid = WhichWindow(message)
		if wid and self._windows.has_key(wid):
			window = self._windows[wid]
			window.do_activate(modifiers & 1, event)
		else:
			MacOS.HandleEvent(event)
	
	def do_osEvt(self, event):
		(what, message, when, where, modifiers) = event
		which = (message >> 24) & 0xff
		if which == 1:	# suspend/resume
			self.do_suspendresume(event)
		else:
			if DEBUG:
				print 'unknown osEvt:',
				self.printevent(event)
	
	def do_suspendresume(self, event):
		(what, message, when, where, modifiers) = event
		wid = FrontWindow()
		if wid and self._windows.has_key(wid):
			window = self._windows[wid]
			window.do_activate(message & 1, event)
	
	def do_kHighLevelEvent(self, event):
		(what, message, when, where, modifiers) = event
		if DEBUG: 
			print "High Level Event:",
			self.printevent(event)
		try:
			AEProcessAppleEvent(event)
		except:
			pass
			#print "AEProcessAppleEvent error:"
			#traceback.print_exc()
	
	def do_unknownevent(self, event):
		if DEBUG:
			print "Unhandled event:",
			self.printevent(event)
	
	def printevent(self, event):
		(what, message, when, where, modifiers) = event
		nicewhat = `what`
		if eventname.has_key(what):
			nicewhat = eventname[what]
		print nicewhat,
		if what == kHighLevelEvent:
			h, v = where
			print `ostypecode(message)`, hex(when), `ostypecode(h | (v<<16))`,
		else:
			print hex(message), hex(when), where,
		print hex(modifiers)


class MenuBar:
	"""Represent a set of menus in a menu bar.
	
	Interface:
	
	- (constructor)
	- (destructor)
	- addmenu
	- addpopup (normally used internally)
	- dispatch (called from Application)
	"""
	
	nextid = 1	# Necessarily a class variable
	
	def getnextid(self):
		id = MenuBar.nextid
		MenuBar.nextid = id+1
		return id
	
	def __init__(self, parent=None):
		self.parent = parent
		ClearMenuBar()
		self.bar = GetMenuBar()
		self.menus = {}
	
	# XXX necessary?
	def close(self):
		self.parent = None
		self.bar = None
		self.menus = None
	
	def addmenu(self, title, after = 0, id=None):
		if id == None:
			id = self.getnextid()
		if DEBUG: print 'Newmenu', title, id # XXXX
		m = NewMenu(id, title)
		m.InsertMenu(after)
		if after >= 0:
			if self.parent:
				self.parent.needmenubarredraw = 1
			else:
				DrawMenuBar()
		return id, m
		
	def delmenu(self, id):
		if DEBUG: print 'Delmenu', id # XXXX
		DeleteMenu(id)
	
	def addpopup(self, title = ''):
		return self.addmenu(title, -1)

# Useless:	
#	def install(self):
#		if not self.bar: return
#		SetMenuBar(self.bar)
#		if self.parent:
#			self.parent.needmenubarredraw = 1
#		else:
#			DrawMenuBar()
	
	def fixmenudimstate(self):
		for m in self.menus.keys():
			menu = self.menus[m]
			if menu.__class__ == FrameWork.AppleMenu:
				continue
			for i in range(len(menu.items)):
				label, shortcut, callback, kind = menu.items[i]
				if type(callback) == types.StringType:
					wid = Win.FrontWindow()
					if wid and self.parent._windows.has_key(wid):
						window = self.parent._windows[wid]
						if hasattr(window, "domenu_" + callback):
							menu.menu.EnableMenuItem(i + 1)
						elif hasattr(self.parent, "domenu_" + callback):
							menu.menu.EnableMenuItem(i + 1)
						else:
							menu.menu.DisableMenuItem(i + 1)
					elif hasattr(self.parent, "domenu_" + callback):
						menu.menu.EnableMenuItem(i + 1)
					else:
						menu.menu.DisableMenuItem(i + 1)
				elif callback:
					pass
					
	def dispatch(self, id, item, window, event):
		if self.menus.has_key(id):
			self.menus[id].dispatch(id, item, window, event)
		else:
			if DEBUG: print "MenuBar.dispatch(%d, %d, %s, %s)" % \
				(id, item, window, event)
	

# XXX Need a way to get menus as resources and bind them to callbacks

class Menu:
	"One menu."
	
	def __init__(self, bar, title, after=0, id=None):
		self.bar = bar
		self.id, self.menu = self.bar.addmenu(title, after, id)
		bar.menus[self.id] = self
		self.items = []
		self._parent = None
		
	def delete(self):
		self.bar.delmenu(self.id)
		del self.bar.menus[self.id]
		self.menu.DisposeMenu()
		del self.bar
		del self.items
		del self.menu
		del self.id
		del self._parent
		
	def additem(self, label, shortcut=None, callback=None, kind=None):
		self.menu.AppendMenu('x')		# add a dummy string
		self.items.append((label, shortcut, callback, kind))
		item = len(self.items)
		self.menu.SetMenuItemText(item, label)		# set the actual text
		if shortcut and type(shortcut) == type(()):
			modifiers, char = shortcut[:2]
			self.menu.SetItemCmd(item, ord(char))
			self.menu.SetMenuItemModifiers(item, modifiers)
			if len(shortcut) > 2:
				self.menu.SetMenuItemKeyGlyph(item, shortcut[2])
		elif shortcut:	
			self.menu.SetItemCmd(item, ord(shortcut))
		return item
		
	def delitem(self, item):
		if item != len(self.items):
			raise 'Can only delete last item of a menu'
		self.menu.DeleteMenuItem(item)
		del self.items[item-1]
	
	def addcheck(self, label, shortcut=None, callback=None):
		return self.additem(label, shortcut, callback, 'check')
	
	def addradio(self, label, shortcut=None, callback=None):
		return self.additem(label, shortcut, callback, 'radio')
	
	def addseparator(self):
		self.menu.AppendMenu('(-')
		self.items.append(('', None, None, 'separator'))
	
	def addsubmenu(self, label, title=''):
		sub = Menu(self.bar, title, -1)
		item = self.additem(label, '\x1B', None, 'submenu')
		self.menu.SetItemMark(item, sub.id)
		sub._parent = self
		sub._parent_item = item
		return sub
	
	def dispatch(self, id, item, window, event):
		title, shortcut, callback, mtype = self.items[item-1]
		if callback:
			if not self.bar.parent or type(callback) <> types.StringType:
				menuhandler = callback
			else: 
				# callback is string
				wid = Win.FrontWindow()
				if wid and self.bar.parent._windows.has_key(wid):
					window = self.bar.parent._windows[wid]
					if hasattr(window, "domenu_" + callback):
						menuhandler = getattr(window, "domenu_" + callback)
					elif hasattr(self.bar.parent, "domenu_" + callback):
						menuhandler = getattr(self.bar.parent, "domenu_" + callback)
					else:
						# nothing we can do. we shouldn't have come this far
						# since the menu item should have been disabled...
						return
				elif hasattr(self.bar.parent, "domenu_" + callback):
					menuhandler = getattr(self.bar.parent, "domenu_" + callback)
				else:
					# nothing we can do. we shouldn't have come this far
					# since the menu item should have been disabled...
					return
			menuhandler(id, item, window, event)

	def enable(self, onoff):
		if onoff:
			self.menu.EnableMenuItem(0)
			if self._parent:
				self._parent.menu.EnableMenuItem(self._parent_item)
		else:
			self.menu.DisableMenuItem(0)
			if self._parent:
				self._parent.menu.DisableMenuItem(self._parent_item)
		if self.bar and self.bar.parent:
				self.bar.parent.needmenubarredraw = 1
			
class PopupMenu(Menu):
	def __init__(self, bar):
		Menu.__init__(self, bar, '(popup)', -1)
		
	def popup(self, x, y, event, default=1, window=None):
		# NOTE that x and y are global coordinates, and they should probably
		# be topleft of the button the user clicked (not mouse-coordinates),
		# so the popup nicely overlaps.
		reply = self.menu.PopUpMenuSelect(x, y, default)
		if not reply:
			return
		id = (reply & 0xffff0000) >> 16
		item = reply & 0xffff
		if not window:
			wid = Win.FrontWindow()
			try:
				window = self.bar.parent._windows[wid]
			except:
				pass # If we can't find the window we pass None
		self.dispatch(id, item, window, event)

class MenuItem:
	def __init__(self, menu, title, shortcut=None, callback=None, kind=None):
		self.item = menu.additem(title, shortcut, callback)
		self.menu = menu
		
	def delete(self):
		self.menu.delitem(self.item)
		del self.menu
		del self.item
		
	def check(self, onoff):
		self.menu.menu.CheckMenuItem(self.item, onoff)

	def enable(self, onoff):
		if onoff:
			self.menu.menu.EnableMenuItem(self.item)
		else:
			self.menu.menu.DisableMenuItem(self.item)
			
	def settext(self, text):
		self.menu.menu.SetMenuItemText(self.item, text)
		
	def setstyle(self, style):
		self.menu.menu.SetItemStyle(self.item, style)
		
	def seticon(self, icon):
		self.menu.menu.SetItemIcon(self.item, icon)
		
	def setcmd(self, cmd):
		self.menu.menu.SetItemCmd(self.item, cmd)
		
	def setmark(self, cmd):
		self.menu.menu.SetItemMark(self.item, cmd)
		

class RadioItem(MenuItem):
	def __init__(self, menu, title, shortcut=None, callback=None):
		MenuItem.__init__(self, menu, title, shortcut, callback, 'radio')

class CheckItem(MenuItem):
	def __init__(self, menu, title, shortcut=None, callback=None):
		MenuItem.__init__(self, menu, title, shortcut, callback, 'check')

def Separator(menu):
	menu.addseparator()

def SubMenu(menu, label, title=''):
	return menu.addsubmenu(label, title)


class AppleMenu(Menu):
	
	def __init__(self, bar, abouttext="About me...", aboutcallback=None):
		Menu.__init__(self, bar, "\024", id=SIOUX_APPLEMENU_ID)
		if MacOS.runtimemodel == 'ppc':
			self.additem(abouttext, None, aboutcallback)
			self.addseparator()
			self.menu.AppendResMenu('DRVR')
		else:
			# Additem()'s tricks do not work for "apple" menu under Carbon
			self.menu.InsertMenuItem(abouttext, 0)
			self.items.append((abouttext, None, aboutcallback, None))
	
	def dispatch(self, id, item, window, event):
		if item == 1:
			Menu.dispatch(self, id, item, window, event)
		elif MacOS.runtimemodel == 'ppc':
			name = self.menu.GetMenuItemText(item)
			OpenDeskAcc(name)

class Window:
	"""A single window belonging to an application"""
	
	def __init__(self, parent):
		self.wid = None
		self.parent = parent
		
	def open(self, bounds=(40, 40, 400, 400), resid=None):
		if resid <> None:
			self.wid = GetNewWindow(resid, -1)
		else:
			self.wid = NewWindow(bounds, self.__class__.__name__, 1,
				8, -1, 1, 0)	# changed to proc id 8 to include zoom box. jvr
		self.do_postopen()
		
	def do_postopen(self):
		"""Tell our parent we exist"""
		self.parent.appendwindow(self.wid, self)
		
	def close(self):
		self.do_postclose()
			
	def do_postclose(self):
		self.parent.removewindow(self.wid)
		self.parent = None
		self.wid = None
		
	def SetPort(self):
		# Convinience method
		SetPort(self.wid)
		
	def GetWindow(self):
		return self.wid
	
	def do_inDrag(self, partcode, window, event):
		where = event[3]
		window.DragWindow(where, self.draglimit)
	
	draglimit = screenbounds
	
	def do_inGoAway(self, partcode, window, event):
		where = event[3]
		if window.TrackGoAway(where):
			self.close()
	
	def do_inZoom(self, partcode, window, event):
		(what, message, when, where, modifiers) = event
		if window.TrackBox(where, partcode):
			window.ZoomWindow(partcode, 1)
			rect = window.GetWindowUserState()				# so that zoom really works... jvr
			self.do_postresize(rect[2] - rect[0], rect[3] - rect[1], window)	# jvr
	
	def do_inZoomIn(self, partcode, window, event):
		SetPort(window) # !!!
		self.do_inZoom(partcode, window, event)
	
	def do_inZoomOut(self, partcode, window, event):
		SetPort(window) # !!!
		self.do_inZoom(partcode, window, event)
	
	def do_inGrow(self, partcode, window, event):
		(what, message, when, where, modifiers) = event
		result = window.GrowWindow(where, self.growlimit)
		if result:
			height = (result>>16) & 0xffff	# Hi word
			width = result & 0xffff		# Lo word
			self.do_resize(width, height, window)
	
	growlimit = (50, 50, screenbounds[2] - screenbounds[0], screenbounds[3] - screenbounds[1])	# jvr
	
	def do_resize(self, width, height, window):
		l, t, r, b = self.wid.GetWindowPort().portRect			# jvr, forGrowIcon
		self.SetPort()							# jvr
		self.wid.InvalWindowRect((r - SCROLLBARWIDTH + 1, b - SCROLLBARWIDTH + 1, r, b))	# jvr
		window.SizeWindow(width, height, 1)		# changed updateFlag to true jvr
		self.do_postresize(width, height, window)
	
	def do_postresize(self, width, height, window):
		SetPort(window)
		self.wid.InvalWindowRect(window.GetWindowPort().portRect)
	
	def do_inContent(self, partcode, window, event):
		#
		# If we're not frontmost, select ourselves and wait for
		# the activate event.
		#
		if FrontWindow() <> window:
			window.SelectWindow()
			return
		# We are. Handle the event.
		(what, message, when, where, modifiers) = event
		SetPort(window)
		local = GlobalToLocal(where)
		self.do_contentclick(local, modifiers, event)
		
	def do_contentclick(self, local, modifiers, event):
		if DEBUG:
			print 'Click in contents at %s, modifiers %s'%(local, modifiers)
	
	def do_rawupdate(self, window, event):
		if DEBUG: print "raw update for", window
		SetPort(window)
		window.BeginUpdate()
		self.do_update(window, event)
		window.EndUpdate()
	
	def do_update(self, window, event):
		if DEBUG:
			import time
			for i in range(8):
				time.sleep(0.1)
				InvertRgn(window.GetWindowPort().visRgn)
			FillRgn(window.GetWindowPort().visRgn, qd.gray)
		else:
			EraseRgn(window.GetWindowPort().visRgn)
		
	def do_activate(self, activate, event):
		if DEBUG: print 'Activate %d for %s'%(activate, self.wid)
		
class ControlsWindow(Window):

	def do_rawupdate(self, window, event):
		if DEBUG: print "raw update for", window
		SetPort(window)
		window.BeginUpdate()
		self.do_update(window, event)
		#DrawControls(window)					# jvr
		UpdateControls(window, window.GetWindowPort().visRgn)	# jvr
		window.DrawGrowIcon()
		window.EndUpdate()
	
	def do_controlhit(self, window, control, pcode, event):
		if DEBUG: print "control hit in", window, "on", control, "; pcode =", pcode

	def do_inContent(self, partcode, window, event):
		if FrontWindow() <> window:
			window.SelectWindow()
			return
		(what, message, when, where, modifiers) = event
		SetPort(window)  # XXXX Needed?
		local = GlobalToLocal(where)
		pcode, control = FindControl(local, window)
		if pcode and control:
			self.do_rawcontrolhit(window, control, pcode, local, event)
		else:
			if DEBUG: print "FindControl(%s, %s) -> (%s, %s)" % \
				(local, window, pcode, control)
			self.do_contentclick(local, modifiers, event)
			
	def do_rawcontrolhit(self, window, control, pcode, local, event):
		pcode = control.TrackControl(local)
		if pcode:
			self.do_controlhit(window, control, pcode, event)
			
class ScrolledWindow(ControlsWindow):
	def __init__(self, parent):
		self.barx = self.bary = None
		self.barx_enabled = self.bary_enabled = 1
		self.activated = 1
		ControlsWindow.__init__(self, parent)

	def scrollbars(self, wantx=1, wanty=1):
		SetPort(self.wid)
		self.barx = self.bary = None
		self.barx_enabled = self.bary_enabled = 1
		x0, y0, x1, y1 = self.wid.GetWindowPort().portRect
		vx, vy = self.getscrollbarvalues()
		if vx == None: self.barx_enabled, vx = 0, 0
		if vy == None: self.bary_enabled, vy = 0, 0
		if wantx:
			rect = x0-1, y1-(SCROLLBARWIDTH-1), x1-(SCROLLBARWIDTH-2), y1+1
			self.barx = NewControl(self.wid, rect, "", 1, vx, 0, 32767, 16, 0)
			if not self.barx_enabled: self.barx.HiliteControl(255)
##			self.wid.InvalWindowRect(rect)
		if wanty:
			rect = x1-(SCROLLBARWIDTH-1), y0-1, x1+1, y1-(SCROLLBARWIDTH-2)
			self.bary = NewControl(self.wid, rect, "", 1, vy, 0, 32767, 16, 0)
			if not self.bary_enabled: self.bary.HiliteControl(255)
##			self.wid.InvalWindowRect(rect)
			
	def do_postclose(self):
		self.barx = self.bary = None
		ControlsWindow.do_postclose(self)
		
	def do_activate(self, onoff, event):
		self.activated = onoff
		if onoff:
			if self.barx and self.barx_enabled:
				self.barx.ShowControl()	# jvr
			if self.bary and self.bary_enabled:
				self.bary.ShowControl()	# jvr
		else:
			if self.barx:
				self.barx.HideControl()	# jvr; An inactive window should have *hidden*
							# scrollbars, not just dimmed (no matter what
							# BBEdit does... look at the Finder)
			if self.bary:
				self.bary.HideControl()	# jvr
		self.wid.DrawGrowIcon()			# jvr
			
	def do_postresize(self, width, height, window):
		l, t, r, b = self.wid.GetWindowPort().portRect
		self.SetPort()
		if self.barx:
			self.barx.HideControl()		# jvr
			self.barx.MoveControl(l-1, b-(SCROLLBARWIDTH-1))
			self.barx.SizeControl((r-l)-(SCROLLBARWIDTH-3), SCROLLBARWIDTH)	# jvr
		if self.bary:
			self.bary.HideControl()		# jvr
			self.bary.MoveControl(r-(SCROLLBARWIDTH-1), t-1)
			self.bary.SizeControl(SCROLLBARWIDTH, (b-t)-(SCROLLBARWIDTH-3))	# jvr
		if self.barx:
			self.barx.ShowControl()		# jvr
			self.wid.ValidWindowRect((l, b - SCROLLBARWIDTH + 1, r - SCROLLBARWIDTH + 2, b))	# jvr
		if self.bary:
			self.bary.ShowControl()		# jvr
			self.wid.ValidWindowRect((r - SCROLLBARWIDTH + 1, t, r, b - SCROLLBARWIDTH + 2))	# jvr
		self.wid.InvalWindowRect((r - SCROLLBARWIDTH + 1, b - SCROLLBARWIDTH + 1, r, b))	# jvr, growicon

			
	def do_rawcontrolhit(self, window, control, pcode, local, event):
		if control == self.barx:
			which = 'x'
		elif control == self.bary:
			which = 'y'
		else:
			return 0
		if pcode in (inUpButton, inDownButton, inPageUp, inPageDown):
			# We do the work for the buttons and grey area in the tracker
			dummy = control.TrackControl(local, self.do_controltrack)
		else:
			# but the thumb is handled here
			pcode = control.TrackControl(local)
			if pcode == inThumb:
				value = control.GetControlValue()
				print 'setbars', which, value #DBG
				self.scrollbar_callback(which, 'set', value)
				self.updatescrollbars()
			else:
				print 'funny part', pcode #DBG
		return 1
		
	def do_controltrack(self, control, pcode):
		if control == self.barx:
			which = 'x'
		elif control == self.bary:
			which = 'y'
		else:
			return

		if pcode == inUpButton:
			what = '-'
		elif pcode == inDownButton:
			what = '+'
		elif pcode == inPageUp:
			what = '--'
		elif pcode == inPageDown:
			what = '++'
		else:
			return
		self.scrollbar_callback(which, what, None)
		self.updatescrollbars()
		
	def updatescrollbars(self):
		SetPort(self.wid)
		vx, vy = self.getscrollbarvalues()
		if self.barx:
			if vx == None:
				self.barx.HiliteControl(255)
				self.barx_enabled = 0
			else:
				if not self.barx_enabled:
					self.barx_enabled = 1
					if self.activated:
						self.barx.HiliteControl(0)
				self.barx.SetControlValue(vx)
		if self.bary:
			if vy == None:
				self.bary.HiliteControl(255)
				self.bary_enabled = 0
			else:
				if not self.bary_enabled:
					self.bary_enabled = 1
					if self.activated:
						self.bary.HiliteControl(0)
				self.bary.SetControlValue(vy)
			
	# Auxiliary function: convert standard text/image/etc coordinate
	# to something palatable as getscrollbarvalues() return
	def scalebarvalue(self, absmin, absmax, curmin, curmax):
		if curmin <= absmin and curmax >= absmax:
			return None
		if curmin <= absmin:
			return 0
		if curmax >= absmax:
			return 32767
		perc = float(curmin-absmin)/float(absmax-absmin)
		return int(perc*32767)
			
	# To be overridden:
	
	def getscrollbarvalues(self):
		return 0, 0
		
	def scrollbar_callback(self, which, what, value):
		print 'scroll', which, what, value
	
class DialogWindow(Window):
	"""A modeless dialog window"""
	
	def open(self, resid):
		self.dlg = GetNewDialog(resid, -1)
		self.wid = self.dlg.GetDialogWindow()
		self.do_postopen()
		
	def close(self):
		self.do_postclose()
		
	def do_postclose(self):
		self.dlg = None
		Window.do_postclose(self)
		
	def do_itemhit(self, item, event):
		print 'Dialog %s, item %d hit'%(self.dlg, item)
		
	def do_rawupdate(self, window, event):
		pass

def ostypecode(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 TestApp(Application):
	
	"This class is used by the test() function"
	
	def makeusermenus(self):
		self.filemenu = m = Menu(self.menubar, "File")
		self.saveitem = MenuItem(m, "Save", "S", self.save)
		Separator(m)
		self.optionsmenu = mm = SubMenu(m, "Options")
		self.opt1 = CheckItem(mm, "Arguments", "A")
		self.opt2 = CheckItem(mm, "Being hit on the head lessons", (kMenuOptionModifier, "A"))
		self.opt3 = CheckItem(mm, "Complaints", (kMenuOptionModifier|kMenuNoCommandModifier, "A"))
		Separator(m)
		self.quititem = MenuItem(m, "Quit", "Q", self.quit)
	
	def save(self, *args):
		print "Save"
	
	def quit(self, *args):
		raise self


def test():
	"Test program"
	app = TestApp()
	app.mainloop()


if __name__ == '__main__':
	test()
