"A sort of application framework for the Mac"

DEBUG=0

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

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.Help 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

try:
    MyFrontWindow = FrontNonFloatingWindow
except NameError:
    MyFrontWindow = FrontWindow

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 = GetQDGlobalsScreenBits().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 is None:
        _watch = GetCursor(4).data
    SetCursor(_watch)

def setarrowcursor():
    SetCursor(GetQDGlobalsArrow())

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 = {}
        self._helpmenu = None
        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 gethelpmenu(self):
        if self._helpmenu is None:
            self._helpmenu = HelpMenu(self.menubar)
        return self._helpmenu

    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
        if hasattr(MacOS, 'SchedParams'):
            saveparams = 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:
            if hasattr(MacOS, 'SchedParams'):
                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 what in eventname:
            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"""
        if MacOS.runtimemodel == 'macho':
            raise 'Unsupported in MachoPython'
        old = self._doing_asyncevents
        if old:
            MacOS.SetEventHandler()
            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 window in self._windows:
                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 partcode in partname:
            name = "do_" + partname[partcode]
        else:
            name = "do_%d" % partcode

        if wid is 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
                if hasattr(MacOS, 'HandleEvent'):
                    MacOS.HandleEvent(event)
                return
        elif wid in self._windows:
            # 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):
        if hasattr(MacOS, 'HandleEvent'):
            MacOS.HandleEvent(event)

    def do_inDesk(self, partcode, window, event):
        if hasattr(MacOS, 'HandleEvent'):
            MacOS.HandleEvent(event)

    def do_inMenuBar(self, partcode, window, event):
        if not self.menubar:
            if hasattr(MacOS, 'HandleEvent'):
                MacOS.HandleEvent(event)
            return
        (what, message, when, where, modifiers) = event
        result = MenuSelect(where)
        id = (result>>16) & 0xffff      # Hi word
        if id >= 0x8000:
            id = -65536 + id
        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):
        if hasattr(MacOS, 'OutputSeen'):
            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)
        if hasattr(MacOS, 'HandleEvent'):
            MacOS.HandleEvent(event)

    def do_unknownwindow(self, partcode, window, event):
        if DEBUG: print 'Unknown window:', window
        if hasattr(MacOS, 'HandleEvent'):
            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:
                    if hasattr(MacOS, 'HandleEvent'):
                        MacOS.HandleEvent(event)
                return
        else:
            # See whether the front window wants it
            w = MyFrontWindow()
            if w and w in self._windows:
                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", repr(c)

    def do_updateEvt(self, event):
        (what, message, when, where, modifiers) = event
        wid = WhichWindow(message)
        if wid and wid in self._windows:
            window = self._windows[wid]
            window.do_rawupdate(wid, event)
        else:
            if hasattr(MacOS, 'HandleEvent'):
                MacOS.HandleEvent(event)

    def do_activateEvt(self, event):
        (what, message, when, where, modifiers) = event
        wid = WhichWindow(message)
        if wid and wid in self._windows:
            window = self._windows[wid]
            window.do_activate(modifiers & 1, event)
        else:
            if hasattr(MacOS, 'HandleEvent'):
                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 = MyFrontWindow()
        if wid and wid in self._windows:
            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 = repr(what)
        if what in eventname:
            nicewhat = eventname[what]
        print nicewhat,
        if what == kHighLevelEvent:
            h, v = where
            print repr(ostypecode(message)), hex(when), repr(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 is 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 = MyFrontWindow()
                    if wid and wid in self.parent._windows:
                        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 id in self.menus:
            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)
        if isinstance(label, unicode):
            self.menu.SetMenuItemTextWithCFString(item, label)
        else:
            self.menu.SetMenuItemText(item, label)
        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 = MyFrontWindow()
                if wid and wid in self.bar.parent._windows:
                    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 >> 16) & 0xffff
        item = reply & 0xffff
        if not window:
            wid = MyFrontWindow()
            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 HelpMenu(Menu):
    def __init__(self, bar):
        # Note we don't call Menu.__init__, we do the necessary things by hand
        self.bar = bar
        self.menu, index = HMGetHelpMenu()
        self.id = self.menu.GetMenuID()
        bar.menus[self.id] = self
        # The next line caters for the entries the system already handles for us
        self.items = [None]*(index-1)
        self._parent = None


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().GetPortBounds()           # 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().GetPortBounds())

    def do_inContent(self, partcode, window, event):
        #
        # If we're not frontmost, select ourselves and wait for
        # the activate event.
        #
        if MyFrontWindow() != 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, GetQDGlobalsGray())
        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 MyFrontWindow() != 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().GetPortBounds()
        vx, vy = self.getscrollbarvalues()
        if vx is None: self.barx_enabled, vx = 0, 0
        if vy is 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().GetPortBounds()
        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 is 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 is 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.itemeh = MenuItem(m, "Enable Help", None, self.enablehelp)
        self.itemdbg = MenuItem(m, "Debug", None, self.debug)
        Separator(m)
        self.quititem = MenuItem(m, "Quit", "Q", self.quit)

    def save(self, *args):
        print "Save"

    def quit(self, *args):
        raise self

    def enablehelp(self, *args):
        hm = self.gethelpmenu()
        self.nohelpitem = MenuItem(hm, "There isn't any", None, self.nohelp)

    def nohelp(self, *args):
        print "I told you there isn't any!"

    def debug(self, *args):
        import pdb
        pdb.set_trace()


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


if __name__ == '__main__':
    test()
