# -*- coding: utf-8 -*-
# MIT License
#
# Copyright (c) 2016, Dr. Sven Kochmann
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#
# Description:
# 1.2 Measurement settings (GUI program)
#
# This program helps the user to set up the "measurement set" settings (name, location, additional descriptive
# strings) and the recording settings. Settings are saved to an ini file, which is used by the recording script
# later. The recording script will create subfolders 001, 002, etc for each individual measurement.
#

# Import modules
import wx               # wxPython (wxWidgets)
import ConfigParser     # Reading/Writing config files

# Main dialog
class MyDialog(wx.Dialog):
    # Init function (onInitDialog)
    def __init__(self, parent):
        # This layout code was generated by wxFormBuilder
        # -----------------------------------------------
        wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title=u"Output settings", pos=wx.DefaultPosition,
                           size=wx.Size(553, 523), style=wx.DEFAULT_DIALOG_STYLE)

        self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)

        fgSizer2 = wx.FlexGridSizer(0, 2, 0, 0)
        fgSizer2.AddGrowableRow(4)
        fgSizer2.SetFlexibleDirection(wx.BOTH)
        fgSizer2.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)

        self.static_name = wx.StaticText(self, wx.ID_ANY, u"Name of measurement:", wx.DefaultPosition, wx.Size(200, -1),
                                         0)
        self.static_name.Wrap(-1)
        self.static_name.SetMaxSize(wx.Size(200, -1))

        fgSizer2.Add(self.static_name, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        self.text_name = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size(300, -1), 0)
        self.text_name.SetMaxSize(wx.Size(300, -1))

        fgSizer2.Add(self.text_name, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 10)

        self.static_rootdir = wx.StaticText(self, wx.ID_ANY, u"Root directory for measurements:", wx.DefaultPosition,
                                            wx.Size(200, -1), 0)
        self.static_rootdir.Wrap(-1)
        self.static_rootdir.SetMaxSize(wx.Size(200, -1))

        fgSizer2.Add(self.static_rootdir, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        self.dir_rootdir = wx.DirPickerCtrl(self, wx.ID_ANY, wx.EmptyString, u"Select root directory for measurements",
                                            wx.DefaultPosition, wx.Size(300, -1), wx.DIRP_DEFAULT_STYLE)
        self.dir_rootdir.SetMaxSize(wx.Size(300, -1))

        fgSizer2.Add(self.dir_rootdir, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 10)

        self.static_dataline1 = wx.StaticText(self, wx.ID_ANY, u"Additional data line 1 (e.g. chip name):",
                                              wx.DefaultPosition, wx.DefaultSize, 0)
        self.static_dataline1.Wrap(-1)
        fgSizer2.Add(self.static_dataline1, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        self.text_dataline1 = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size(300, -1), 0)
        self.text_dataline1.SetMaxSize(wx.Size(300, -1))

        fgSizer2.Add(self.text_dataline1, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        self.static_dataline2 = wx.StaticText(self, wx.ID_ANY, u"Additional data line 2 (e.g. excitation):",
                                              wx.DefaultPosition, wx.DefaultSize, 0)
        self.static_dataline2.Wrap(-1)
        fgSizer2.Add(self.static_dataline2, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        self.text_dataline2 = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size(300, -1), 0)
        self.text_dataline2.SetMaxSize(wx.Size(300, -1))

        fgSizer2.Add(self.text_dataline2, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        fgSizer2.AddSpacer((0, 0), 1, wx.EXPAND, 5)

        self.m_staticline1 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.Size(300, -1), wx.LI_HORIZONTAL)
        self.m_staticline1.SetMinSize(wx.Size(200, -1))

        fgSizer2.Add(self.m_staticline1, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.FIXED_MINSIZE, 10)

        self.static_outputoptions = wx.StaticText(self, wx.ID_ANY, u"Output options (both video/images)",
                                                  wx.DefaultPosition, wx.DefaultSize, 0)
        self.static_outputoptions.Wrap(-1)
        fgSizer2.Add(self.static_outputoptions, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        self.check_individualchannels = wx.CheckBox(self, wx.ID_ANY,
                                                    u"Combine all input channels to one output channel",
                                                    wx.DefaultPosition, wx.DefaultSize, 0)
        fgSizer2.Add(self.check_individualchannels, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        fgSizer2.AddSpacer((0, 0), 1, wx.EXPAND, 5)

        self.check_scaleindividually = wx.CheckBox(self, wx.ID_ANY, u"Scale channels individually", wx.DefaultPosition,
                                                   wx.DefaultSize, 0)
        fgSizer2.Add(self.check_scaleindividually, 0, wx.ALL, 10)

        fgSizer2.AddSpacer((0, 0), 1, wx.EXPAND, 5)

        self.check_ignorebackground = wx.CheckBox(self, wx.ID_ANY, u"Do not subtract background", wx.DefaultPosition,
                                                  wx.DefaultSize, 0)
        fgSizer2.Add(self.check_ignorebackground, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        self.static_snapshotframes = wx.StaticText(self, wx.ID_ANY, u"Take snapshots every x frames",
                                                   wx.DefaultPosition, wx.DefaultSize, 0)
        self.static_snapshotframes.Wrap(-1)
        fgSizer2.Add(self.static_snapshotframes, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        self.spin_snapshots = wx.SpinCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                          wx.SP_ARROW_KEYS, 0, 1000, 0)
        fgSizer2.Add(self.spin_snapshots, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        self.static_outputvideo = wx.StaticText(self, wx.ID_ANY, u"Output video FPS (Playback)", wx.DefaultPosition,
                                                wx.DefaultSize, 0)
        self.static_outputvideo.Wrap(-1)
        fgSizer2.Add(self.static_outputvideo, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        self.spin_outputFPS = wx.SpinCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize,
                                          wx.SP_ARROW_KEYS, 0, 100, 0)
        fgSizer2.Add(self.spin_outputFPS, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        self.static_outputcodec = wx.StaticText(self, wx.ID_ANY, u"Output video codec", wx.DefaultPosition,
                                                wx.DefaultSize, 0)
        self.static_outputcodec.Wrap(-1)
        fgSizer2.Add(self.static_outputcodec, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)

        self.text_outputcodec = wx.TextCtrl(self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0)
        fgSizer2.Add(self.text_outputcodec, 0, wx.ALIGN_CENTER_VERTICAL | wx.ALL, 10)

        fgSizer2.AddSpacer((0, 0), 1, wx.EXPAND, 5)

        self.m_staticline2 = wx.StaticLine(self, wx.ID_ANY, wx.DefaultPosition, wx.Size(300, -1), wx.LI_HORIZONTAL)
        self.m_staticline2.SetMinSize(wx.Size(200, -1))

        fgSizer2.Add(self.m_staticline2, 0, wx.EXPAND | wx.ALL, 10)

        fgSizer2.AddSpacer((0, 0), 1, wx.EXPAND, 5)

        sizer_dlgbuttons = wx.StdDialogButtonSizer()
        self.sizer_dlgbuttonsSave = wx.Button(self, wx.ID_SAVE)
        sizer_dlgbuttons.AddButton(self.sizer_dlgbuttonsSave)
        self.sizer_dlgbuttonsCancel = wx.Button(self, wx.ID_CANCEL)
        sizer_dlgbuttons.AddButton(self.sizer_dlgbuttonsCancel)
        sizer_dlgbuttons.Realize();

        fgSizer2.Add(sizer_dlgbuttons, 1, wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND, 10)

        self.SetSizer(fgSizer2)
        self.Layout()

        self.Centre(wx.BOTH)

        # Connect Events
        self.Bind(wx.EVT_CLOSE, self.onClose)
        self.sizer_dlgbuttonsCancel.Bind(wx.EVT_BUTTON, self.cancelSettings)
        self.sizer_dlgbuttonsSave.Bind(wx.EVT_BUTTON, self.saveSettings)
        # -----------------------------------------------

        # Read the config file
        Config = ConfigParser.ConfigParser()
        if len(Config.read("output.ini")) > 0:  # File found?
            self.text_name.Value = Config.get("Output", "name")
            self.dir_rootdir.SetPath(Config.get("Output", "rootdir"))
            self.text_dataline1.Value = Config.get("Output", "dataline1")
            self.text_dataline2.Val = Config.get("Output", "dataline2")
            self.spin_snapshots.Value = Config.getint("Output", "snapshots")
            self.spin_outputFPS.Value = Config.getint("Output", "videoFPS")
            self.text_outputcodec.Value = Config.get("Output", "videocodec")

            # Combine channels to one?
            if Config.getboolean("Output", "combinechannels") == True:
                self.check_individualchannels.SetValue(True)

            # Combine channels to one?
            if Config.getboolean("Output", "scaleindividually") == True:
                self.check_scaleindividually.SetValue(True)

            # Combine channels to one?
            if Config.getboolean("Output", "ignorebackground") == True:
                self.check_ignorebackground.SetValue(True)

            # No name?
            if len(self.text_name.Value) == 0:
                self.text_name.Value = "Random experiment"

    # onClose: destroy window
    def onClose(self, evt):
        # Destroy window
        self.Destroy()

    # Close dialog without saving settings
    def cancelSettings(self, event):
        self.Close()
        event.Skip()

    # Close dialog with saving settings
    def saveSettings(self, event):
        Config = ConfigParser.ConfigParser()
        Config.add_section("Output")
        Config.set("Output", "name", self.text_name.Value)
        Config.set("Output", "rootdir", self.dir_rootdir.GetPath())
        Config.set("Output", "dataline1", self.text_dataline1.Value)
        Config.set("Output", "dataline2", self.text_dataline2.Value)
        Config.set("Output", "videocodec", self.text_outputcodec.Value)
        Config.set("Output", "snapshots", self.spin_snapshots.Value)
        Config.set("Output", "videoFPS", self.spin_outputFPS.Value)
        Config.set("Output", "combinechannels", int(self.check_individualchannels.IsChecked()))
        Config.set("Output", "scaleindividually", int(self.check_scaleindividually.IsChecked()))
        Config.set("Output", "ignorebackground", int(self.check_ignorebackground.IsChecked()))
        with open("Output.ini", "w") as fp:
            Config.write(fp)
        self.Close()
        event.Skip()

# Actual main program: Show the above dialog
if __name__=="__main__":
    app = wx.App()
    dlg = MyDialog(None)
    dlg.ShowModal()
    app.ExitMainLoop()

