
#----------------------------------------------------------------------

class PyOnDemandOutputWindow:
    def __init__(self, title = "wxPython: stdout/stderr"):
        self.frame  = None
        self.title  = title
        self.parent = None

    def SetParent(self, parent):
        self.parent = parent

    def OnCloseWindow(self, event):
        if self.frame != None:
            self.frame.Destroy()
        self.frame = None
        self.text  = None

    # These methods provide the file-like output behaviour.
    def write(self, str):
        if not wx.Thread_IsMain():
            # Aquire the GUI mutex before making GUI calls.  Mutex is released
            # when locker is deleted at the end of this function.
            locker = wx.MutexGuiLocker()

        if not self.frame:
            self.frame = wx.Frame(self.parent, -1, self.title,
                                 style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
            self.text  = wxTextCtrl(self.frame, -1, "",
                                    style = wx.TE_MULTILINE | wx.TE_READONLY)
            self.frame.SetSize((450, 300))
            self.frame.Show(True)
            EVT_CLOSE(self.frame, self.OnCloseWindow)
        self.text.AppendText(str)

    def close(self):
        if self.frame != None:
            if not wx.Thread_IsMain():
                locker = wx.MutexGuiLocker()
            self.frame.Close()


#----------------------------------------------------------------------
# The main application class.  Derive from this and implement an OnInit
# method that creates a frame and then calls self.SetTopWindow(frame)

_defRedirect = (wx.Platform == '__WXMSW__' or wx.Platform == '__WXMAC__')

class App(wx.PyApp):
    outputWindowClass = PyOnDemandOutputWindow

    def __init__(self, redirect=_defRedirect, filename=None, useBestVisual=False):
        wx.PyApp.__init__(self)

        if wx.Platform == "__WXMAC__":
            try:
                import MacOS
                if not MacOS.WMAvailable():
                    print """\
This program needs access to the screen. Please run with 'pythonw',
not 'python', and only when you are logged in on the main display of
your Mac."""
                    _sys.exit(1)
            except:
                pass

        # This has to be done before OnInit
        self.SetUseBestVisual(useBestVisual)

        # Set the default handler for SIGINT.  This fixes a problem
        # where if Ctrl-C is pressed in the console that started this
        # app then it will not appear to do anything, (not even send
        # KeyboardInterrupt???)  but will later segfault on exit.  By
        # setting the default handler then the app will exit, as
        # expected (depending on platform.)
        try:
            import signal
            signal.signal(signal.SIGINT, signal.SIG_DFL)
        except:
            pass

        # Save and redirect the stdio to a window?
        self.stdioWin = None
        self.saveStdio = (_sys.stdout, _sys.stderr)
        if redirect:
            self.RedirectStdio(filename)

        # This finishes the initialization of wxWindows and then calls
        # the OnInit that should be present in the derived class
        self._BootstrapApp()


    def __del__(self):
        try:
            self.RestoreStdio()  # Just in case the MainLoop was overridden
        except:
            pass


    def SetTopWindow(self, frame):
        if self.stdioWin:
            self.stdioWin.SetParent(frame)
        wx.PyApp.SetTopWindow(self, frame)


    def MainLoop(self):
        wx.PyApp.MainLoop(self)
        self.RestoreStdio()


    def RedirectStdio(self, filename):
        if filename:
            _sys.stdout = _sys.stderr = open(filename, 'a')
        else:
            self.stdioWin = self.outputWindowClass()
            _sys.stdout = _sys.stderr = self.stdioWin


    def RestoreStdio(self):
        _sys.stdout, _sys.stderr = self.saveStdio



# change from wxPyApp_ to wxApp_
App_GetMacSupportPCMenuShortcuts = _core.PyApp_GetMacSupportPCMenuShortcuts
App_GetMacAboutMenuItemId        = _core.PyApp_GetMacAboutMenuItemId
App_GetMacPreferencesMenuItemId  = _core.PyApp_GetMacPreferencesMenuItemId
App_GetMacExitMenuItemId         = _core.PyApp_GetMacExitMenuItemId
App_GetMacHelpMenuTitleName      = _core.PyApp_GetMacHelpMenuTitleName
App_SetMacSupportPCMenuShortcuts = _core.PyApp_SetMacSupportPCMenuShortcuts
App_SetMacAboutMenuItemId        = _core.PyApp_SetMacAboutMenuItemId
App_SetMacPreferencesMenuItemId  = _core.PyApp_SetMacPreferencesMenuItemId
App_SetMacExitMenuItemId         = _core.PyApp_SetMacExitMenuItemId
App_SetMacHelpMenuTitleName      = _core.PyApp_SetMacHelpMenuTitleName
App_GetComCtl32Version           = _core.PyApp_GetComCtl32Version

#----------------------------------------------------------------------------

class PySimpleApp(wx.App):
    def __init__(self, redirect=False, filename=None):
        wx.App.__init__(self, redirect, filename)
    def OnInit(self):
        wx.InitAllImageHandlers()
        return True


class PyWidgetTester(wx.App):
    def __init__(self, size = (250, 100)):
        self.size = size
        wx.App.__init__(self, 0)

    def OnInit(self):
        self.frame = wxFrame(None, -1, "Widget Tester", pos=(0,0), size=self.size)
        self.SetTopWindow(self.frame)
        return True

    def SetWidget(self, widgetClass, *args):
        w = widgetClass(self.frame, *args)
        self.frame.Show(True)

#----------------------------------------------------------------------------
# DO NOT hold any other references to this object.  This is how we
# know when to cleanup system resources that wxWin is holding.  When
# the sys module is unloaded, the refcount on sys.__wxPythonCleanup
# goes to zero and it calls the wxApp_CleanUp function.

class __wxPyCleanup:
    def __init__(self):
        self.cleanup = _core.App_CleanUp
    def __del__(self):
        self.cleanup()

_sys.__wxPythonCleanup = __wxPyCleanup()

## # another possible solution, but it gets called too early...
## if sys.version[0] == '2':
##     import atexit
##     atexit.register(_core.wxApp_CleanUp)
## else:
##     sys.exitfunc = _core.wxApp_CleanUp


#----------------------------------------------------------------------------
