#!/usr/bin/env python
# -*- coding:utf-8 -*-

"""
Attempt to help Thierry Brizzi with Aui NB issues.
@ Google Groups > wxPython-users ? Problems with AGW AuiManager

"""

#-Imports-----------------------------------------------------------------------

#--Python Imports.
import os
import sys
from collections import OrderedDict

if sys.version_info[0] == 2:
    PY2 = True
    PY3 = False
elif sys.version_info[0] == 3:
    PY2 = False
    PY3 = True
# import traceback # Format Tracebacks
try:
    if PY2:
        import cPickle as pickle  # Saving of global settings, keyboard shortcuts dictionaries.
    elif PY3:
        import pickle
except ImportError as exc:
    raise exc

#--wxPython Imports.
import wx
from wx.lib.agw import aui

#--win32 Imports. # Apparently T_izzy is using Microsoft Windows for the OS.
from win32api import GetCurrentProcess
from win32con import GR_GDIOBJECTS
from win32process import GetGuiResources


#-Globals-----------------------------------------------------------------------
gAppDir = os.path.realpath(os.path.dirname(sys.argv[0]))
print('gAppDir = %s' % gAppDir)


#read the pickle or ini file
pickleJar = (gAppDir + os.sep + 'tizzy.pkl')
if os.path.exists(pickleJar):
    pkl_file = open(pickleJar, 'rb')
    gGlobalsDict = pickle.load(pkl_file)
    pkl_file.close()
    print('pickleJar found')
else:
    gGlobalsDict = OrderedDict([])

    # you could save to ini, but long strings don't work well with ini's
    #gGlobalsDict = OrderedDict([
    #    # ('FramePerspective', gConfig.get('Startup', 'FramePerspective')),
    #    ('FramePerspective', default_layout),
    #    ])

ID_NB1 = 1001
ID_NB2 = 1002
ID_NB3 = 1003
ID_NB4 = 1004
ID_NB5 = 1005
ID_NB6 = 1006

def GetGDIResources():
    "Return the number of GDI Resource"
    numGDI = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS)
    return numGDI

N_PAGES = 50
OPEN_ONLY = False
AUTO_MODE = False
RELOAD_PERSPECTIVE = True

class MyNotebook(aui.AuiNotebook):
    n_pages = 0

    def __init__(self, parent):
        ## default = (
        ##     aui.AUI_NB_TOP |
        ##     aui.AUI_NB_TAB_MOVE |
        ##     aui.AUI_NB_SCROLL_BUTTONS |
        ##     aui.AUI_NB_CLOSE_ON_ACTIVE_TAB |
        ##     aui.AUI_NB_MIDDLE_CLICK_CLOSE |
        ##     aui.AUI_NB_CLOSE_ON_ALL_TABS
        ## )
        ## style = (
        ##     default |
        ##     aui.AUI_NB_WINDOWLIST_BUTTON |
        ##     aui.AUI_NB_NO_TAB_FOCUS |
        ##     aui.AUI_NB_SMART_TABS |
        ##     aui.AUI_NB_USE_IMAGES_DROPDOWN |
        ##     aui.AUI_NB_ORDER_BY_ACCESS
        ## )


        style= (#aui.AUI_NB_DEFAULT_STYLE |         #AUI_NB_DEFAULT_STYLE = AUI_NB_TOP | AUI_NB_TAB_SPLIT | AUI_NB_TAB_MOVE | AUI_NB_SCROLL_BUTTONS | AUI_NB_CLOSE_ON_ACTIVE_TAB | AUI_NB_MIDDLE_CLICK_CLOSE | AUI_NB_DRAW_DND_TAB
                 aui.AUI_NB_TOP |                 #With this style, tabs are drawn along the top of the notebook
                 # aui.AUI_NB_BOTTOM |              #With this style, tabs are drawn along the bottom of the notebook
                 ## aui.AUI_NB_LEFT |               #With this style, tabs are drawn along the left of the notebook. Not implemented yet.
                 ## aui.AUI_NB_RIGHT |              #With this style, tabs are drawn along the right of the notebook. Not implemented yet.
                 # aui.AUI_NB_CLOSE_BUTTON |        #With this style, a close button is available on the tab bar
                 aui.AUI_NB_CLOSE_ON_ACTIVE_TAB | #With this style, a close button is available on the active tab
                 # aui.AUI_NB_CLOSE_ON_ALL_TABS |   #With this style, a close button is available on all tabs
                 aui.AUI_NB_SCROLL_BUTTONS |      #With this style, left and right scroll buttons are displayed
                 # aui.AUI_NB_TAB_EXTERNAL_MOVE |     #Allows a tab to be moved to another tab control
                 # aui.AUI_NB_TAB_FIXED_WIDTH |     #With this style, all tabs have the same width
                 aui.AUI_NB_TAB_MOVE |            #Allows a tab to be moved horizontally by dragging
                 aui.AUI_NB_TAB_SPLIT |           #Allows the tab control to be split by dragging a tab
                 # aui.AUI_NB_HIDE_ON_SINGLE_TAB |  #Hides the tab window if only one tab is present
                 # aui.AUI_NB_SUB_NOTEBOOK |        #This style is used by AuiManager to create automatic AuiNotebooks
                 # aui.AUI_NB_MIDDLE_CLICK_CLOSE |  #Allows to close AuiNotebook tabs by mouse middle button click
                 # aui.AUI_NB_SMART_TABS |          #Use Smart Tabbing, like Alt + Tab on Windows
                 # aui.AUI_NB_USE_IMAGES_DROPDOWN | #Uses images on dropdown window list menu instead of check items
                 # aui.AUI_NB_CLOSE_ON_TAB_LEFT |   #Draws the tab close button on the left instead of on the right (a la Camino browser)
                 # aui.AUI_NB_TAB_FLOAT |           #Allows the floating of single tabs. Known limitation: when the notebook is more or less full screen, tabs cannot be dragged far enough outside of the notebook to become floating pages
                 aui.AUI_NB_DRAW_DND_TAB |        #Draws an image representation of a tab while dragging (on by default)
                 # aui.AUI_NB_ORDER_BY_ACCESS |     #Tab navigation order by last access time for the tabs
                 # aui.AUI_NB_NO_TAB_FOCUS |        #Don?t draw tab focus rectangle
                 aui.AUI_NB_WINDOWLIST_BUTTON       #With this style, a drop-down list of windows is available
                 )

        super(MyNotebook, self).__init__(parent, agwStyle=style)
        self.Bind(aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self.OnPageClosing)
        self.Bind(aui.EVT_AUINOTEBOOK_PAGE_CLOSED, self.OnPageClosed)

        # create the timer used to
        # open / close the current page
        self._counter = 0
        self._timer = wx.Timer(self)
        if AUTO_MODE :
            self._timer.Start()
        self.Bind(wx.EVT_TIMER, self.OnTimer)

        # @ T_izzy if you want for example your pages to load in a certain order, then saving infos, Ex'paths' to a list, and load them back in exactly that order on startup. LoadAuiPersp, Then UnSplit() the AuiNotebook.
        for i in range(5):
            self.AddNewPage()

    def OnTimer(self, evt):
        """
        Delete the current page and add a new one to effectively show the memory leak.
        """
        if (self.GetPageCount() >= N_PAGES) and not OPEN_ONLY :
            while self.GetPageCount() :
                self.DeletePage(self.GetSelection())
        else :
            self.AddNewPage()
        if self._counter > 1000 :
            self._timer.Stop()
        self._counter += 1

    def AddNewPage(self):
        """
        Add a new page inside the notebook.
        """
        MyNotebook.n_pages += 1
        ### page = MyView(self)
        page = wx.TextCtrl(self, -1, "AuiNotebook Page %s" % MyNotebook.n_pages)
        caption = "Page %s" % MyNotebook.n_pages
        self.AddPage(page, caption, True)

    def OnPageClosing(self, evt):
        """
        Save the layout before closing a tab.
        """
        i_page = evt.GetSelection()
        page = self.GetPage(i_page)
        layout = open("./layout.txt", "w")
        layout.write(page.manager.SavePerspective())
        layout.close()
        evt.Skip()

    def OnPageClosed(self, evt):
        """
        Add a new page when the current one is closed.
        """
        self.AddNewPage()
        evt.Skip()


class MyFrame(wx.Frame) :
    def __init__(self, *args, **kwargs):
        super(MyFrame, self).__init__(*args, **kwargs)

        global gMainWin
        gMainWin = self

        #--- AuiManager
        self._mgr = aui.AuiManager(managed_window=self,
                                   agwFlags = aui.AUI_MGR_ALLOW_FLOATING
                                            # | aui.AUI_MGR_ALLOW_ACTIVE_PANE
                                            # | aui.AUI_MGR_TRANSPARENT_DRAG
                                            | aui.AUI_MGR_TRANSPARENT_HINT
                                            | aui.AUI_MGR_VENETIAN_BLINDS_HINT
                                            # | aui.AUI_MGR_RECTANGLE_HINT
                                            | aui.AUI_MGR_HINT_FADE
                                            # | aui.AUI_MGR_NO_VENETIAN_BLINDS_FADE
                                            # | aui.AUI_MGR_LIVE_RESIZE
                                            | aui.AUI_MGR_ANIMATE_FRAMES
                                            | aui.AUI_MGR_PREVIEW_MINIMIZED_PANES
                                            # | aui.AUI_MGR_AERO_DOCKING_GUIDES
                                            | aui.AUI_MGR_WHIDBEY_DOCKING_GUIDES
                                            | aui.AUI_MGR_SMOOTH_DOCKING
                                            | aui.AUI_MGR_USE_NATIVE_MINIFRAMES # Undocking of toolbar panes buggy when hide/show if don't use this.
                                            # | aui.AUI_MGR_AUTONB_NO_CAPTION
                                            )
        # ... Tell AuiManager to manage this frame
        self._mgr.SetManagedWindow(self)

        self._mgr.SetAutoNotebookStyle(agwStyle = aui.AUI_NB_DRAW_DND_TAB
                                                # | aui.AUI_NB_TOP
                                                # | aui.AUI_NB_LEFT
                                                # | aui.AUI_NB_RIGHT
                                                | aui.AUI_NB_BOTTOM
                                                | aui.AUI_NB_TAB_SPLIT
                                                | aui.AUI_NB_TAB_MOVE
                                                # | aui.AUI_NB_TAB_EXTERNAL_MOVE
                                                # | aui.AUI_NB_TAB_FIXED_WIDTH
                                                | aui.AUI_NB_SCROLL_BUTTONS
                                                | aui.AUI_NB_WINDOWLIST_BUTTON
                                                # | aui.AUI_NB_CLOSE_BUTTON
                                                | aui.AUI_NB_CLOSE_ON_ACTIVE_TAB
                                                # | aui.AUI_NB_CLOSE_ON_ALL_TABS
                                                | aui.AUI_NB_MIDDLE_CLICK_CLOSE
                                                | aui.AUI_NB_SUB_NOTEBOOK
                                                # | aui.AUI_NB_HIDE_ON_SINGLE_TAB
                                                | aui.AUI_NB_SMART_TABS
                                                # | aui.AUI_NB_USE_IMAGES_DROPDOWN
                                                # | aui.AUI_NB_CLOSE_ON_TAB_LEFT
                                                | aui.AUI_NB_TAB_FLOAT
                                                )

        self.notebook = MyNotebook(self)

        self._mgr.AddPane(self.notebook, aui.AuiPaneInfo().CenterPane().
                          Name('gAuiNB').Caption("gAuiNB").MinimizeButton(True).MaximizeButton(True).MinimizeButton(True).PinButton(True).Show())

        self._mgr.AddPane(wx.TextCtrl(self, ID_NB1, 'Frame Pane 1'), aui.AuiPaneInfo().
                          Name('gNB1').Caption("gNB1").MinimizeButton(True).MaximizeButton(True).MinimizeButton(True).PinButton(True).Show())

        self._mgr.AddPane(wx.TextCtrl(self, ID_NB2, 'Frame Pane 2'), aui.AuiPaneInfo().
                          Name('gNB2').Caption("gNB2").MinimizeButton(True).MaximizeButton(True).MinimizeButton(True).PinButton(True).Show())

        self._mgr.AddPane(wx.TextCtrl(self, ID_NB3, 'Frame Pane 3'), aui.AuiPaneInfo().
                          Name('gNB3').Caption("gNB3").MinimizeButton(True).MaximizeButton(True).MinimizeButton(True).PinButton(True).Show())

        self._mgr.AddPane(wx.TextCtrl(self, ID_NB4, 'Frame Pane 4'), aui.AuiPaneInfo().
                          Name('gNB4').Caption("gNB4").MinimizeButton(True).MaximizeButton(True).MinimizeButton(True).PinButton(True).Show())

        self._mgr.AddPane(wx.TextCtrl(self, ID_NB5, 'Frame Pane 5'), aui.AuiPaneInfo().
                          Name('gNB5').Caption("gNB5").MinimizeButton(True).MaximizeButton(True).MinimizeButton(True).PinButton(True).Show())

        self._mgr.AddPane(wx.TextCtrl(self, ID_NB6, 'Frame Pane 6'), aui.AuiPaneInfo().
                          Name('gNB6').Caption("gNB6").MinimizeButton(True).MaximizeButton(True).MinimizeButton(True).PinButton(True).Show())

        self._mgr.Update()

        self.Bind(wx.EVT_CLOSE, self.OnClose) # Don't use an id here!!!

        wx.CallAfter(self.LoadFramePersp)
        wx.CallAfter(self.LoadAuiNBPersp)

    def LoadFramePersp(self):
        if gGlobalsDict:
            self._mgr.LoadPerspective(gGlobalsDict['FramePerspective'])
            self._mgr.Update()

    def LoadAuiNBPersp(self):
        if gGlobalsDict:
            self.notebook.LoadPerspective(gGlobalsDict['NotebookPerspective'])

    def DoSaveWindowSettings(self):
        """
        Saves/Writes all settings before application exits.
        Saved Settings: AUI Frame Perspective, AUI Notebook Perspective,
        Frame Size, Frame Position and the rest of the Config to
        UserConfigurableSettings.ini, .pkl, .etc file for the next startup.

        """

        print('OnSaveWindowSettings - start')

        # Write the tizzy.pkl file.
        data = gGlobalsDict
        output = open(gAppDir + os.sep + 'tizzy.pkl', 'wb')
        pickle.dump(data, output)
        output.close()

        # # Write whatever and else ....
        # pass

        print('OnSaveWindowSettings - end')

    def OnClose(self, event):
        """
        wx.EVT_CLOSE
        The Main Frame Close button has been clicked (The red X), signaling
        the application to quit/close.

        """

        if wx.GetKeyState(wx.WXK_SHIFT):
            print('ShiftDown: Skipping Ask to save any unsaved documents that are open...')
        else:
            # Ask to save any unsaved documents that are open...
            ## doCancelClose = False # ... bla, this & tha. Code specific stuff, you may want... specifics not included. Figure it your yourself.
            pass
            # ... bla, this & tha iff and if an iffy.


        ## self.statusbar.timer.Stop() # STOP all timers!!!!
        #@ Tizzy... Note timers can cause problems with just about anything,
        # especially when closing an app. Kill them all, in threads also. First before proceeding.
        # ...

        # Preserve the clipboard contents before the app has exited, so it can still be used afterwards.
        # wx.TheClipboard.Flush()

        gGlobalsDict['FramePerspective'] = self._mgr.SavePerspective()
        gGlobalsDict['NotebookPerspective'] = self.notebook.SavePerspective()
        self.DoSaveWindowSettings() # Try todo the saving of preferences...

        self._mgr.UnInit()
        event.Skip()
        print('OnClose')
        self.Destroy()


class MyApp(wx.App):

    def OnInit(self) :
        frame = MyFrame(None, size=(1024, 768))
        frame.CenterOnScreen()
        frame.Show(True)
        ## if not AUTO_MODE :
        ##     frame.notebook.AddNewPage()
        return True

if __name__ == "__main__" :
    app = MyApp(False)
    app.MainLoop()
    print("finished")
