"""About Dialog for IDLE

"""

from Tkinter import *
import string, os
import textView
import idlever

class AboutDialog(Toplevel):
    """Modal about dialog for idle

    """
    def __init__(self,parent,title):
        Toplevel.__init__(self, parent)
        self.configure(borderwidth=5)
        self.geometry("+%d+%d" % (parent.winfo_rootx()+30,
                                  parent.winfo_rooty()+30))
        self.bg = "#707070"
        self.fg = "#ffffff"
        self.CreateWidgets()
        self.resizable(height=FALSE, width=FALSE)
        self.title(title)
        self.transient(parent)
        self.grab_set()
        self.protocol("WM_DELETE_WINDOW", self.Ok)
        self.parent = parent
        self.buttonOk.focus_set()
        self.bind('<Return>',self.Ok) #dismiss dialog
        self.bind('<Escape>',self.Ok) #dismiss dialog
        self.wait_window()

    def CreateWidgets(self):
        frameMain = Frame(self, borderwidth=2, relief=SUNKEN)
        frameButtons = Frame(self)
        frameButtons.pack(side=BOTTOM, fill=X)
        frameMain.pack(side=TOP, expand=TRUE, fill=BOTH)
        self.buttonOk = Button(frameButtons, text='Close',
                               command=self.Ok)
        self.buttonOk.pack(padx=5, pady=5)
        #self.picture = Image('photo', data=self.pictureData)
        frameBg = Frame(frameMain, bg=self.bg)
        frameBg.pack(expand=TRUE, fill=BOTH)
        labelTitle = Label(frameBg, text='IDLE', fg=self.fg, bg=self.bg,
                           font=('courier', 24, 'bold'))
        labelTitle.grid(row=0, column=0, sticky=W, padx=10, pady=10)
        #labelPicture = Label(frameBg, text='[picture]')
        #image=self.picture, bg=self.bg)
        #labelPicture.grid(row=1, column=1, sticky=W, rowspan=2,
        #                  padx=0, pady=3)
        byline = "Python's Integrated DeveLopment Environment" + 5*'\n'
        labelDesc = Label(frameBg, text=byline, justify=LEFT,
                          fg=self.fg, bg=self.bg)
        labelDesc.grid(row=2, column=0, sticky=W, columnspan=3, padx=10, pady=5)
        labelEmail = Label(frameBg, text='email:  idle-dev@python.org',
                           justify=LEFT, fg=self.fg, bg=self.bg)
        labelEmail.grid(row=6, column=0, columnspan=2,
                        sticky=W, padx=10, pady=0)
        labelWWW = Label(frameBg, text='www:  http://www.python.org/idle/',
                         justify=LEFT, fg=self.fg, bg=self.bg)
        labelWWW.grid(row=7, column=0, columnspan=2, sticky=W, padx=10, pady=0)
        Frame(frameBg, borderwidth=1, relief=SUNKEN,
              height=2, bg=self.bg).grid(row=8, column=0, sticky=EW,
                                         columnspan=3, padx=5, pady=5)
        labelPythonVer = Label(frameBg, text='Python version:  ' + \
                               sys.version.split()[0], fg=self.fg, bg=self.bg)
        labelPythonVer.grid(row=9, column=0, sticky=W, padx=10, pady=0)
        # handle weird tk version num in windoze python >= 1.6 (?!?)
        tkVer = repr(TkVersion).split('.')
        tkVer[len(tkVer)-1] = str('%.3g' % (float('.'+tkVer[len(tkVer)-1])))[2:]
        if tkVer[len(tkVer)-1] == '':
            tkVer[len(tkVer)-1] = '0'
        tkVer = string.join(tkVer,'.')
        labelTkVer = Label(frameBg, text='Tk version:  '+
                           tkVer, fg=self.fg, bg=self.bg)
        labelTkVer.grid(row=9, column=1, sticky=W, padx=2, pady=0)
        py_button_f = Frame(frameBg, bg=self.bg)
        py_button_f.grid(row=10, column=0, columnspan=2, sticky=NSEW)
        buttonLicense = Button(py_button_f, text='License', width=8,
                               highlightbackground=self.bg,
                               command=self.ShowLicense)
        buttonLicense.pack(side=LEFT, padx=10, pady=10)
        buttonCopyright = Button(py_button_f, text='Copyright', width=8,
                                 highlightbackground=self.bg,
                                 command=self.ShowCopyright)
        buttonCopyright.pack(side=LEFT, padx=10, pady=10)
        buttonCredits = Button(py_button_f, text='Credits', width=8,
                               highlightbackground=self.bg,
                               command=self.ShowPythonCredits)
        buttonCredits.pack(side=LEFT, padx=10, pady=10)
        Frame(frameBg, borderwidth=1, relief=SUNKEN,
              height=2, bg=self.bg).grid(row=11, column=0, sticky=EW,
                                         columnspan=3, padx=5, pady=5)
        idle_v = Label(frameBg, text='IDLE version:   ' + idlever.IDLE_VERSION,
                       fg=self.fg, bg=self.bg)
        idle_v.grid(row=12, column=0, sticky=W, padx=10, pady=0)
        idle_button_f = Frame(frameBg, bg=self.bg)
        idle_button_f.grid(row=13, column=0, columnspan=3, sticky=NSEW)
        idle_about_b = Button(idle_button_f, text='README', width=8,
                                highlightbackground=self.bg,
                                command=self.ShowIDLEAbout)
        idle_about_b.pack(side=LEFT, padx=10, pady=10)
        idle_news_b = Button(idle_button_f, text='NEWS', width=8,
                                highlightbackground=self.bg,
                                command=self.ShowIDLENEWS)
        idle_news_b.pack(side=LEFT, padx=10, pady=10)
        idle_credits_b = Button(idle_button_f, text='Credits', width=8,
                                highlightbackground=self.bg,
                                command=self.ShowIDLECredits)
        idle_credits_b.pack(side=LEFT, padx=10, pady=10)

    def ShowLicense(self):
        self.display_printer_text(license, 'About - License')

    def ShowCopyright(self):
        self.display_printer_text(copyright, 'About - Copyright')

    def ShowPythonCredits(self):
        self.display_printer_text(credits, 'About - Python Credits')

    def ShowIDLECredits(self):
        self.ViewFile('About - Credits','CREDITS.txt', 'iso-8859-1')

    def ShowIDLEAbout(self):
        self.ViewFile('About - Readme', 'README.txt')

    def ShowIDLENEWS(self):
        self.ViewFile('About - NEWS', 'NEWS.txt')

    def display_printer_text(self, printer, title):
        printer._Printer__setup()
        data = '\n'.join(printer._Printer__lines)
        textView.TextViewer(self, title, None, data)

    def ViewFile(self, viewTitle, viewFile, encoding=None):
        fn = os.path.join(os.path.abspath(os.path.dirname(__file__)), viewFile)
        if encoding:
            import codecs
            try:
                textFile = codecs.open(fn, 'r')
            except IOError:
                import tkMessageBox
                tkMessageBox.showerror(title='File Load Error',
                                       message='Unable to load file %r .' % (fn,),
                                       parent=self)
                return
            else:
                data = textFile.read()
        else:
            data = None
        textView.TextViewer(self, viewTitle, fn, data=data)

    def Ok(self, event=None):
        self.destroy()

if __name__ == '__main__':
    # test the dialog
    root = Tk()
    def run():
        import aboutDialog
        aboutDialog.AboutDialog(root, 'About')
    Button(root, text='Dialog', command=run).pack()
    root.mainloop()
