from types import *
# NB Don't import Tk!
from Tkinter import TkVersion, TclVersion, TclError, \
     _cnfmerge

TEMPLATE = """
def %(name)s(*args, **kw):
    from Tkinter import %(name)s
    original = apply(%(name)s, args, kw)
    def filter(name):
	return name[0] != '_' or name in ('__getitem__',
					  '__setitem__',
					  '__str__')
    from Bastion import Bastion
    bastion = Bastion(original, filter=filter)
    if hasattr(original, '_w'):
	bastion._w = original._w	# XXX This defeats the purpose :-(
	bastion.tk = original.tk	# XXX This too :-(
	bastion.children = original.children # XXX And this :-(
	bastion.master = original.master # XXX And so on :-(
    return bastion
"""

for name in ('Event', 'StringVar', 'IntVar', 'DoubleVar',
     'BooleanVar', 'mainloop', 'getint', 'getdouble', 'getboolean',
     'Misc', 'Wm', 'Pack', 'Place', 'Toplevel', 'Button', 'Canvas',
     'Checkbutton', 'Entry', 'Frame', 'Label', 'Listbox', 'Menu',
     'Menubutton', 'Message', 'Radiobutton', 'Scale', 'Scrollbar',
     'Text', 'Image', 'PhotoImage', 'BitmapImage', 'OptionMenu',
     'image_names', 'image_types'):
     exec TEMPLATE % {'name': name}

del TEMPLATE, name
    
from Tkconstants import *

from Tkinter import tkinter

class _DumbTkinter:
    """Helper class to provide interfaces to low-level handler functions"""
    READABLE = 1
    WRITABLE = 2
    createfilehandler = tkinter.createfilehandler
    deletefilehandler = tkinter.deletefilehandler
    createtimerhandler = tkinter.createtimerhandler

tkinter = _DumbTkinter()

def _castrate(tk):
    """Remove all Tcl commands that can affect the file system.

    This way, if someone breaks through the bastion around Tk, all
    they can do is screw up Grail.  (Though if they are really clever,
    they may be able to catch some of the user's keyboard input, or do
    other subversive things.)

    """
    if not hasattr(tk, 'eval'): return # For Rivet
    def rm(name, tk=tk):
	try:
	    tk.call('rename', name, '')
	except TclError:
	    pass
    # Make sure the menu support commands are autoloaded, since we need them
    tk.eval("auto_load tkMenuInvoke")
    rm('exec')
    rm('cd')
    rm('open') # This is what breaks the menu support commands
    rm('send')
