# new plotting tool top level module
# Robbie Valentine
# 6/1/2020


import wx
import numpy as np
import wx.lib.agw.aui as aui
import matplotlib as mpl
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar
from pnl_FileBrowser import panel_FileBrowser

# Pane/panel dimensions
PLOT_PANEL_Y = 500
FILE_BROWSER_X = 150
FILE_BROWSER_Y = 100
NOTEBOOK_Y = 200

# SW Versioning
SW_VERSION = {
    "MAJOR": '0',
    "MINOR": '1',
    "PATCH": '0'
}
S_SW_VER = str(SW_VERSION['MAJOR'] + "." + SW_VERSION['MINOR'] + "." + SW_VERSION['PATCH'])



#
# Panel holding matplotlib plot/graph
# - These plots should hold the graph and functions for
# - manipulating the graph
class PlotPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)

        # create default x,y vectors
        x = np.arange(0, 3, 0.01)
        y = np.sin(np.pi*x)

        #  Create plot components
        self.figure = mpl.figure.Figure(figsize=(2, 2))         # create figure
        self.axes = self.figure.add_subplot(111)                # save handle to subplot axes - set to a single plot
        self.line = self.axes.plot(x, y)[0]                     # get line item - what I assign data points to
        self.canvas = FigureCanvas(self, -1, self.figure)       # create canvas to display plotted data
        self.toolbar = NavigationToolbar(self.canvas)           # create toolbar
        self.toolbar.Realize()

        # create sizers and add objects to them
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, wx.EXPAND)
        sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
        self.SetSizer(sizer)

        # setup axis labels
        self.axes.set_xlabel("x-axis")
        self.axes.set_ylabel("y-axis")



        #self.line.set_xdata(x)
        #self.line.set_ydata(y)
        #self.axes.plot(x, y)
        #self.canvas.draw()
        #self.axes.plot(x, y)

    #
    # write data to line object and refresh canvas
    #
    def plot_data(self, x, y):
        self.line.set_xdata(x)
        self.line.set_ydata(y)
        self.canvas.draw()






#
# Main application frame
#
class MyFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent, -1, "Frame", size=(1200, 800))
        self.Center(wx.BOTH)
        self.mgr = aui.AuiManager()
        self.mgr.SetManagedWindow(self)

        # init conditions
        self.theta = 0.01       # for testing only

        # create notebook for button controls etc...
        self.nb_controls = aui.AuiNotebook(self, -1)
        self.nb_plot = aui.AuiNotebook(self, -1)

        # create panels
        self.p1 = wx.Panel(self, wx.NewId(), name='p1')
        self.plot_panel1 = PlotPanel(self)
        self.plot_panel2 = PlotPanel(self)
        self.p3 = wx.Panel(self, wx.NewId(), name='p3')
        #self.file_browser = wx.Panel(self, wx.NewId(), name='p4')
        self.file_browser = panel_FileBrowser(self)

        # create plot notebook and add to aui pane
        self.nb_plot.AddPage(page=self.plot_panel1, caption='plot panel 1')
        self.nb_plot.AddPage(page=self.plot_panel2, caption='plot panel 2')

        self.mgr.AddPane(self.nb_plot, aui.AuiPaneInfo().Name("Plot_Panel").Caption("Plot Panel").Top()
                         .CaptionVisible(False).Floatable(False).CloseButton(False).Dockable(False).CenterPane())

        # Create file browser pane
        self.mgr.AddPane(self.file_browser, aui.AuiPaneInfo().Name("File_Browser").Caption("File_Browser")
                                        .Left().MinSize((FILE_BROWSER_X, FILE_BROWSER_Y))
                                        .BestSize((FILE_BROWSER_X, FILE_BROWSER_Y)).Floatable(False)
                                        .MaxSize((FILE_BROWSER_X, FILE_BROWSER_Y)).Dockable(False))

        # Add notebook pages for user control panels
        self.nb_controls.AddPage(page=self.p1, caption='p1')
        self.nb_controls.AddPage(page=self.p3, caption='p3')

        self.mgr.AddPane(self.nb_controls, aui.AuiPaneInfo().Name("control_notebook").Caption("Control Notebook")
                         .Bottom().MinSize((-1, NOTEBOOK_Y-10)).BestSize((-1, NOTEBOOK_Y-5)).Dockable(False)
                         .MaxSize((-1, NOTEBOOK_Y)).Floatable(False).CloseButton(False).CaptionVisible(False))


        # Style change required to use function calls to remove tab 'x' or close tab button
        self.nb_controls.SetAGWWindowStyleFlag(aui.AUI_NB_CLOSE_ON_ALL_TABS)
        self.nb_controls.SetCloseButton(0, False)
        self.nb_controls.SetCloseButton(1, False)


        # Create example buttons
        id1 = wx.NewId()
        id2 = wx.NewId()
        b1 = wx.Button(parent=self.p1, id=id1, pos=(5, 0), size=(100, 30), label='Save')
        b2 = wx.Button(parent=self.p1, id=id2, pos=(5, 40), size=(100, 30), label='Load')
        b3 = wx.Button(parent=self.p3, id=wx.NewId(), pos=(5, 5), size=(100, 30), label='sel p1')

        # Bindings
        self.Bind(wx.EVT_BUTTON, self.OnB1, b1)
        self.Bind(wx.EVT_BUTTON, self.OnB2, b2)
        self.Bind(wx.EVT_BUTTON, self.OnB3, b3)
        self.Bind(aui.EVT_AUI_PANE_ACTIVATED, self.onPaineActivated)
        self.Bind(wx.EVT_CLOSE, self.onClose)

        # Display pane1
        self.mgr.ShowPane("P1", True)
        self.mgr.Update()



    # currently not used
    def Init(self):
        fh = open("perspective.txt", "r")
        string = fh.read()
        self.mgr.LoadPerspective(string, update=True)
        fh.close()


    def OnB1(self,evt):
        string = self.mgr.SavePerspective()
        fh = open("perspective.txt", "w")
        fh.write(string)
        fh.close()

    def OnB2(self,evt):
        fh = open("perspective.txt", "r")
        stringg = fh.read()
        self.mgr.LoadPerspective(stringg, update=True)
        fh.close()


    def OnB3(self,evt):
        x = np.arange(0, 3, 0.01)
        y = np.sin(np.pi*x + self.theta)
        self.theta += 0.1

        self.plot_panel1.plot_data(x, y)
        #self.plot_panel2.draw(x, y)






    def onPaineActivated(self, evt):
        print('Pane activated')



    def onClose(self, evt):
        self.mgr.UnInit()
        evt.Skip()



app = wx.App(0)
MyFrame(None).Show()
app.MainLoop()



