#! /usr/bin/env python

# A Python function that generates dialog boxes with a text message,
# optional bitmap, and any number of buttons.
# Cf. Ousterhout, Tcl and the Tk Toolkit, Figs. 27.2-3, pp. 269-270.

from Tkinter import *

mainWidget = None

def dialog(master, title, text, bitmap, default, *args):

    # 1. Create the top-level window and divide it into top
    # and bottom parts.

    w = Toplevel(master, {'class': 'Dialog'})
    w.title(title)
    w.iconname('Dialog')

    top = Frame(w, {'relief': 'raised', 'bd': 1,
                    Pack: {'side': 'top', 'fill': 'both'}})
    bot = Frame(w, {'relief': 'raised', 'bd': 1,
                    Pack: {'side': 'bottom', 'fill': 'both'}})

    # 2. Fill the top part with the bitmap and message.

    msg = Message(top,
                  {'width': '3i',
                   'text': text,
                   'font': '-Adobe-Times-Medium-R-Normal-*-180-*',
                   Pack: {'side': 'right', 'expand': 1,
                          'fill': 'both',
                          'padx': '3m', 'pady': '3m'}})
    if bitmap:
        bm = Label(top, {'bitmap': bitmap,
                         Pack: {'side': 'left',
                                'padx': '3m', 'pady': '3m'}})

    # 3. Create a row of buttons at the bottom of the dialog.

    buttons = []
    i = 0
    for but in args:
        b = Button(bot, {'text': but,
                         'command': ('set', 'button', i)})
        buttons.append(b)
        if i == default:
            bd = Frame(bot, {'relief': 'sunken', 'bd': 1,
                             Pack: {'side': 'left', 'expand': 1,
                                    'padx': '3m', 'pady': '2m'}})
            b.lift()
            b.pack ({'in': bd, 'side': 'left',
                     'padx': '2m', 'pady': '2m',
                     'ipadx': '2m', 'ipady': '1m'})
        else:
            b.pack ({'side': 'left', 'expand': 1,
                     'padx': '3m', 'pady': '3m',
                     'ipady': '2m', 'ipady': '1m'})
        i = i+1

    # 4. Set up a binding for <Return>, if there's a default,
    # set a grab, and claim the focus too.

    if default >= 0:
        w.bind('<Return>',
               lambda e, b=buttons[default], i=default:
               (b.flash(),
                b.setvar('button', i)))

    oldFocus = w.tk.call('focus') # XXX
    w.grab_set()
    w.focus()

    # 5. Wait for the user to respond, then restore the focus
    # and return the index of the selected button.

    w.waitvar('button')
    w.destroy()
    w.tk.call('focus', oldFocus) # XXX
    return w.getint(w.getvar('button'))

def strdialog(master, title, text, bitmap, default, *args):

    # 1. Create the top-level window and divide it into top
    # and bottom parts.

    w = Toplevel(master, {'class': 'Dialog'})
    w.title(title)
    w.iconname('Dialog')

    top = Frame(w, {'relief': 'raised', 'bd': 1,
                    Pack: {'side': 'top', 'fill': 'both'}})
    if args:
        bot = Frame(w, {'relief': 'raised', 'bd': 1,
                    Pack: {'side': 'bottom', 'fill': 'both'}})

    # 2. Fill the top part with the bitmap, message and input field.

    if bitmap:
        bm = Label(top, {'bitmap': bitmap,
                         Pack: {'side': 'left',
                                'padx': '3m', 'pady': '3m'}})

    msg = Message(top,
                  {'width': '3i',
                   'text': text,
                   'font': '-Adobe-Times-Medium-R-Normal-*-180-*',
                   Pack: {'side': 'left', 
                          'fill': 'both',
                          'padx': '3m', 'pady': '3m'}})

    field = Entry(top,
                  {'relief':'sunken',
                   Pack:{'side':'left',
                         'fill':'x',
                         'expand':1,
                         'padx':'3m', 'pady':'3m'}})
    # 3. Create a row of buttons at the bottom of the dialog.

    buttons = []
    i = 0
    for but in args:
        b = Button(bot, {'text': but,
                         'command': ('set', 'button', i)})
        buttons.append(b)
        if i == default:
            bd = Frame(bot, {'relief': 'sunken', 'bd': 1,
                             Pack: {'side': 'left', 'expand': 1,
                                    'padx': '3m', 'pady': '2m'}})
            b.lift()
            b.pack ({'in': bd, 'side': 'left',
                     'padx': '2m', 'pady': '2m',
                     'ipadx': '2m', 'ipady': '1m'})
        else:
            b.pack ({'side': 'left', 'expand': 1,
                     'padx': '3m', 'pady': '3m',
                     'ipady': '2m', 'ipady': '1m'})
        i = i+1

    # 4. Set up a binding for <Return>, if there's a default,
    # set a grab, and claim the focus too.

    if not args:
        w.bind('<Return>', lambda arg, top=top: top.setvar('button', 0))
        field.bind('<Return>', lambda arg, top=top: top.setvar('button', 0))
    elif default >= 0:
        w.bind('<Return>',
               lambda e, b=buttons[default], i=default:
               (b.flash(),
                b.setvar('button', i)))
        field.bind('<Return>',
               lambda e, b=buttons[default], i=default:
               (b.flash(),
                b.setvar('button', i)))

    oldFocus = w.tk.call('focus') # XXX
    w.grab_set()
    field.focus()

    # 5. Wait for the user to respond, then restore the focus
    # and return the index of the selected button.

    w.waitvar('button')
    v = field.get()
    w.destroy()
    w.tk.call('focus', oldFocus) # XXX
    if args:
        return v, w.getint(w.getvar('button'))
    else:
        return v

def message(str):
    i = dialog(mainWidget, 'Message', str, '', 0, 'OK')

def askyn(str):
    i = dialog(mainWidget, 'Question', str, '', 0, 'No', 'Yes')
    return i

def askync(str):
    i = dialog(mainWidget, 'Question', str, '', 0, 'Cancel', 'No', 'Yes')
    return i-1

def askstr(str):
    i = strdialog(mainWidget, 'Question', str, '', 0)
    return i

def askfile(str):       # XXXX For now...
    i = strdialog(mainWidget, 'Question', str, '', 0)
    return i
    
# The rest is the test program.

def _go():
    i = dialog(mainWidget,
               'Not Responding',
               "The file server isn't responding right now; "
               "I'll keep trying.",
               '',
               -1,
               'OK')
    print 'pressed button', i
    i = dialog(mainWidget,
               'File Modified',
               'File "tcl.h" has been modified since '
               'the last time it was saved. '
               'Do you want to save it before exiting the application?',
               'warning',
               0,
               'Save File',
               'Discard Changes',
               'Return To Editor')
    print 'pressed button', i
    print message('Test of message')
    print askyn('Test of yes/no')
    print askync('Test of yes/no/cancel')
    print askstr('Type a string:')
    print strdialog(mainWidget, 'Question', 'Another string:', '',
                  0, 'Save', 'Save as text')

def _test():
    import sys
    global mainWidget
    mainWidget = Frame()
    Pack.config(mainWidget)
    start = Button(mainWidget,
                   {'text': 'Press Here To Start', 'command': _go})
    start.pack()
    endit = Button(mainWidget,
                   {'text': 'Exit',
                    'command': 'exit',
                    Pack: {'fill' : 'both'}})
    mainWidget.mainloop()

if __name__ == '__main__':
    _test()
