Exemple #1
0
    def __init__(self, parent, title, rows):
        Dialog.__init__(self, parent)
        if hasattr(sys, "_MEIPASS"):
            ico_str = os.path.join(sys._MEIPASS, 'res/Clock.ico')
        else:
            ico_str = 'res/Clock.ico'

        ico = Path(ico_str)
        if ico.is_file():
            ico = wx.Icon(ico_str, wx.BITMAP_TYPE_ICO)
            self.SetIcon(ico)
        else:
            print("Ico File Not Found")

        self.rows = rows

        self.timeSpin = wx.SpinButton(self, -1, style=wx.SP_VERTICAL)
        self.triggerTime = TimeCtrl(self, -1, format='24HHMM')
        self.triggerTime.BindSpinButton(self.timeSpin)

        self.GetSizer().GetItem(0).GetSizer().Add(self.triggerTime, 1, wx.ALL,
                                                  5)
        self.GetSizer().GetItem(0).GetSizer().Add(self.timeSpin, 0, wx.EXPAND,
                                                  5)
        self.SetTitle(title)
Exemple #2
0
def Ctrl(*args, **kwargs):
    """
    Actually a factory function providing a unifying
    interface for generating masked controls.
    """
    if 'controlType' not in kwargs:
        controlType = TEXT
    else:
        controlType = kwargs['controlType']
        del kwargs['controlType']

    if controlType == TEXT:
        return TextCtrl(*args, **kwargs)

    elif controlType == COMBO:
        return ComboBox(*args, **kwargs)

    elif controlType == IPADDR:
        return IpAddrCtrl(*args, **kwargs)

    elif controlType == TIME:
        return TimeCtrl(*args, **kwargs)

    elif controlType == NUMBER:
        return NumCtrl(*args, **kwargs)

    else:
        raise AttributeError("invalid controlType specified: %s" %
                             repr(controlType))
Exemple #3
0
 def DoCreateResource(self):
     """Creates a new Resource
     
     
     """
     assert self.GetInstance() is None
     w = TimeCtrl(parent=self.GetParentAsWindow(),
                  id=self.GetID(),
                  pos=self.GetPosition(),
                  size=self.GetSize(),
                  style=self.GetStyle())
     if self.GetText('value'):
         w.SetValue(self.GetText('value'))
     else:
         w.SetValue(wx.DateTime.Now())
     self.SetupWindow(w)
     return w
Exemple #4
0
class sheduleDialog(Dialog):
    def __init__(self, parent, title, rows):
        Dialog.__init__(self, parent)
        if hasattr(sys, "_MEIPASS"):
            ico_str = os.path.join(sys._MEIPASS, 'res/Clock.ico')
        else:
            ico_str = 'res/Clock.ico'

        ico = Path(ico_str)
        if ico.is_file():
            ico = wx.Icon(ico_str, wx.BITMAP_TYPE_ICO)
            self.SetIcon(ico)
        else:
            print("Ico File Not Found")

        self.rows = rows

        self.timeSpin = wx.SpinButton(self, -1, style=wx.SP_VERTICAL)
        self.triggerTime = TimeCtrl(self, -1, format='24HHMM')
        self.triggerTime.BindSpinButton(self.timeSpin)

        self.GetSizer().GetItem(0).GetSizer().Add(self.triggerTime, 1, wx.ALL,
                                                  5)
        self.GetSizer().GetItem(0).GetSizer().Add(self.timeSpin, 0, wx.EXPAND,
                                                  5)
        self.SetTitle(title)

    def mdBtnAdd_Click(self, event):

        self.rows.append(self.triggerTime.GetValue())
        self.rows.sort()
        # print(self.rows)
        # self.EndModal(self.rows)
        self.Close()

    def mdBtnCancel_Click(self, event):
        self.Close()
Exemple #5
0
    def __init__(self, parent, control):
        self.control = control
        self.parent = parent
        #wx.Panel.__init__(self,parent,-1)#,style=wx.SUNKEN_BORDER)
        #wx.wizard.WizardPageSimple.__init__(self,parent)
        self.control.setTimelineConfig(self)
        self.sizer = wx.GridBagSizer(5, 5)
        self.fps = 25.00
        self.secs = 10
        self.parent = parent
        self.updated = 0
        self.in_fps = 0
        self.in_framecount = 0
        self.outputsizer = wx.GridBagSizer(5, 5)
        box = wx.StaticBox(self.parent, wx.HORIZONTAL, "Rendering parameters")
        self.outputstaticbox = wx.StaticBoxSizer(box, wx.HORIZONTAL)
        self.outputstaticbox.Add(self.outputsizer)

        self.totalFramesLabel = wx.StaticText(self.parent, -1, "Frames:")
        self.durationLabel = wx.StaticText(self.parent, -1, "Duration:")

        self.totalFrames = wx.TextCtrl(self.parent,
                                       -1,
                                       "250",
                                       size=(50, -1),
                                       style=wx.TE_PROCESS_ENTER)
        self.spin = wx.SpinButton(self.parent,
                                  -1,
                                  style=wx.SP_VERTICAL,
                                  size=(-1, 25))
        self.duration = TimeCtrl(self.parent,
                                 -1,
                                 "00:00:10",
                                 fmt24hr=True,
                                 size=(50, 25),
                                 style=wx.TE_PROCESS_ENTER,
                                 spinButton=self.spin)

        self.totalFrames.Bind(wx.EVT_TEXT, self.updateFrameCount)
        self.duration.Bind(wx.EVT_TEXT, self.updateDuration)

        self.followAspect = wx.CheckBox(
            self.parent, -1, "Don't resize preview, only use aspect ratio.")
        self.followAspect.SetForegroundColour(scripting.COLOR_EXPERIENCED)
        toolTip = wx.ToolTip(
            """If this box is checked, the rendering preview window
will always be sized so that it fits into the screen and
uses the aspect ratio of the final rendered frame. If 
this is unchecked, the preview window will be resized to
be the same size as the final frame.""")
        self.followAspect.SetToolTip(toolTip)
        self.followAspect.SetValue(1)
        box = wx.BoxSizer(wx.HORIZONTAL)
        box.Add(self.duration)
        box.Add(self.spin)

        self.frameSizeLbl = wx.StaticText(self.parent, -1, "Frame size:")
        self.resLst = [(0, 0), (320, 240), (512, 512), (640, 480), (720, 576),
                       (800, 600)]
        self.frameSize = wx.Choice(self.parent,
                                   -1,
                                   choices=[
                                       "Custom", "320 x 240", "512 x 512",
                                       "640 x 480", "720x576 (PAL)",
                                       "720x480 (NTSC)", "800 x 600"
                                   ])
        self.frameSize.SetSelection(4)
        self.frameSize.Bind(wx.EVT_CHOICE, self.onUpdateFrameSize)
        self.outputsizer.Add(self.durationLabel, (0, 0))
        self.outputsizer.Add(box, (0, 1))

        self.outputsizer.Add(self.totalFramesLabel, (1, 0))
        self.outputsizer.Add(self.totalFrames, (1, 1))

        #self.outputsizer.Add(self.fpsLabel,(2,1))
        self.frameRateLbl = wx.StaticText(self.parent, -1, "Frame rate:")
        self.frameRate = wx.TextCtrl(self.parent,
                                     -1,
                                     "%.2f" % self.fps,
                                     style=wx.TE_PROCESS_ENTER)
        self.frameRate.Bind(wx.EVT_TEXT, self.updateFPS)

        self.outputsizer.Add(self.frameRateLbl, (2, 0))
        self.outputsizer.Add(self.frameRate, (2, 1))

        self.custLbl = wx.StaticText(self.parent, -1, "Custom size:")
        self.custXLbl = wx.StaticText(self.parent, -1, "x")
        self.custX = wx.TextCtrl(self.parent, -1, "512", size=(48, -1))
        self.custY = wx.TextCtrl(self.parent, -1, "512", size=(48, -1))
        self.custX.Enable(0)
        self.custY.Enable(0)
        box = wx.BoxSizer(wx.HORIZONTAL)
        box.Add(self.custX)
        box.Add(self.custXLbl)
        box.Add(self.custY)

        self.outputsizer.Add(self.frameSizeLbl, (3, 0))
        self.outputsizer.Add(self.frameSize, (3, 1))
        self.outputsizer.Add(self.custLbl, (4, 0))
        self.outputsizer.Add(box, (4, 1))
        self.outputsizer.Add(self.followAspect, (5, 0))

        self.sizer.Add(self.outputstaticbox, (0, 0), flag=wx.EXPAND | wx.ALL)
        #self.sizer.Add(self.animationstaticbox,(0,1),flag=wx.EXPAND|wx.ALL)

        #self.sline=wx.StaticLine(self)
        #self.sizer.Add(self.sline,(4,0),flag=wx.EXPAND|wx.RIGHT|wx.LEFT)
        #self.sizer.Add(self.useButton,(5,0))

        #self.SetSizer(self.sizer)
        #self.SetAutoLayout(1)
        #self.sizer.Fit(self)
        #self.updateFormat()
        self.useSettings()
Exemple #6
0
class RenderingConfigPanel:
    """
	Description: Contains configuration options for the timeline
	"""
    def __init__(self, parent, control):
        self.control = control
        self.parent = parent
        #wx.Panel.__init__(self,parent,-1)#,style=wx.SUNKEN_BORDER)
        #wx.wizard.WizardPageSimple.__init__(self,parent)
        self.control.setTimelineConfig(self)
        self.sizer = wx.GridBagSizer(5, 5)
        self.fps = 25.00
        self.secs = 10
        self.parent = parent
        self.updated = 0
        self.in_fps = 0
        self.in_framecount = 0
        self.outputsizer = wx.GridBagSizer(5, 5)
        box = wx.StaticBox(self.parent, wx.HORIZONTAL, "Rendering parameters")
        self.outputstaticbox = wx.StaticBoxSizer(box, wx.HORIZONTAL)
        self.outputstaticbox.Add(self.outputsizer)

        self.totalFramesLabel = wx.StaticText(self.parent, -1, "Frames:")
        self.durationLabel = wx.StaticText(self.parent, -1, "Duration:")

        self.totalFrames = wx.TextCtrl(self.parent,
                                       -1,
                                       "250",
                                       size=(50, -1),
                                       style=wx.TE_PROCESS_ENTER)
        self.spin = wx.SpinButton(self.parent,
                                  -1,
                                  style=wx.SP_VERTICAL,
                                  size=(-1, 25))
        self.duration = TimeCtrl(self.parent,
                                 -1,
                                 "00:00:10",
                                 fmt24hr=True,
                                 size=(50, 25),
                                 style=wx.TE_PROCESS_ENTER,
                                 spinButton=self.spin)

        self.totalFrames.Bind(wx.EVT_TEXT, self.updateFrameCount)
        self.duration.Bind(wx.EVT_TEXT, self.updateDuration)

        self.followAspect = wx.CheckBox(
            self.parent, -1, "Don't resize preview, only use aspect ratio.")
        self.followAspect.SetForegroundColour(scripting.COLOR_EXPERIENCED)
        toolTip = wx.ToolTip(
            """If this box is checked, the rendering preview window
will always be sized so that it fits into the screen and
uses the aspect ratio of the final rendered frame. If 
this is unchecked, the preview window will be resized to
be the same size as the final frame.""")
        self.followAspect.SetToolTip(toolTip)
        self.followAspect.SetValue(1)
        box = wx.BoxSizer(wx.HORIZONTAL)
        box.Add(self.duration)
        box.Add(self.spin)

        self.frameSizeLbl = wx.StaticText(self.parent, -1, "Frame size:")
        self.resLst = [(0, 0), (320, 240), (512, 512), (640, 480), (720, 576),
                       (800, 600)]
        self.frameSize = wx.Choice(self.parent,
                                   -1,
                                   choices=[
                                       "Custom", "320 x 240", "512 x 512",
                                       "640 x 480", "720x576 (PAL)",
                                       "720x480 (NTSC)", "800 x 600"
                                   ])
        self.frameSize.SetSelection(4)
        self.frameSize.Bind(wx.EVT_CHOICE, self.onUpdateFrameSize)
        self.outputsizer.Add(self.durationLabel, (0, 0))
        self.outputsizer.Add(box, (0, 1))

        self.outputsizer.Add(self.totalFramesLabel, (1, 0))
        self.outputsizer.Add(self.totalFrames, (1, 1))

        #self.outputsizer.Add(self.fpsLabel,(2,1))
        self.frameRateLbl = wx.StaticText(self.parent, -1, "Frame rate:")
        self.frameRate = wx.TextCtrl(self.parent,
                                     -1,
                                     "%.2f" % self.fps,
                                     style=wx.TE_PROCESS_ENTER)
        self.frameRate.Bind(wx.EVT_TEXT, self.updateFPS)

        self.outputsizer.Add(self.frameRateLbl, (2, 0))
        self.outputsizer.Add(self.frameRate, (2, 1))

        self.custLbl = wx.StaticText(self.parent, -1, "Custom size:")
        self.custXLbl = wx.StaticText(self.parent, -1, "x")
        self.custX = wx.TextCtrl(self.parent, -1, "512", size=(48, -1))
        self.custY = wx.TextCtrl(self.parent, -1, "512", size=(48, -1))
        self.custX.Enable(0)
        self.custY.Enable(0)
        box = wx.BoxSizer(wx.HORIZONTAL)
        box.Add(self.custX)
        box.Add(self.custXLbl)
        box.Add(self.custY)

        self.outputsizer.Add(self.frameSizeLbl, (3, 0))
        self.outputsizer.Add(self.frameSize, (3, 1))
        self.outputsizer.Add(self.custLbl, (4, 0))
        self.outputsizer.Add(box, (4, 1))
        self.outputsizer.Add(self.followAspect, (5, 0))

        self.sizer.Add(self.outputstaticbox, (0, 0), flag=wx.EXPAND | wx.ALL)
        #self.sizer.Add(self.animationstaticbox,(0,1),flag=wx.EXPAND|wx.ALL)

        #self.sline=wx.StaticLine(self)
        #self.sizer.Add(self.sline,(4,0),flag=wx.EXPAND|wx.RIGHT|wx.LEFT)
        #self.sizer.Add(self.useButton,(5,0))

        #self.SetSizer(self.sizer)
        #self.SetAutoLayout(1)
        #self.sizer.Fit(self)
        #self.updateFormat()
        self.useSettings()

    def onUpdateFrameSize(self, evt):
        """
		A callback for when the user changes the frame size
		"""
        sel = evt.GetSelection()
        flag = (sel == 0)
        self.custX.Enable(flag)
        self.custY.Enable(flag)
        evt.Skip()

    def getFrameAmount(self):
        """
		Return the number of frames selected
		"""
        try:
            n = int(self.totalFrames.GetValue())
            return n
        except:
            return 0

    def setFrames(self, n):
        """
		Set the number of frames in the GUI
		"""
        self.totalFrames.SetValue(str(n))
        self.useSettings()

    def setDuration(self, t):
        """
		Set the duration in the GUI
		"""
        if type(t) != types.StringType:
            h = t / 3600
            m = t / 60
            s = t % 60
            t = "%.2d:%.2d:%.2d" % (h, m, s)
        self.duration.SetValue(t)
        self.useSettings()

    def useSettings(self, event=None):
        """
		Use the GUI settings
		"""
        duration = -1
        frameCount = -1
        try:
            # We get a string, but pylint doesn't know that (it thinks we get a wxDateTime)
            # so we cast this to str although it is already an str
            duration = str(self.duration.GetValue())
            hh, mm, ss = map(int, duration.split(":"))
            print hh, mm, ss
            secs = hh * 3600 + mm * 60 + ss
            lib.messenger.send(None, "set_duration", secs)
        except:
            pass
        try:
            frameCount = self.totalFrames.GetValue()
            frameCount = int(frameCount)
            lib.messenger.send(None, "set_frames", frameCount)
        except:
            pass
        if duration != -1 and frameCount != -1:
            self.control.configureTimeline(secs, frameCount)

        x = -1
        y = -1
        try:
            sel = self.frameSize.GetSelection()
            if sel != 0:
                x, y = self.resLst[sel]
            else:
                try:
                    x = int(self.custX.GetValue())
                    y = int(self.custY.GetValue())
                except:
                    return
            #x,y=size.split("x")
            #x=int(x)
            #y=int(y)
            keepAspect = self.followAspect.GetValue()
        except:
            pass
        if x != -1 and y != -1:
            self.control.setFrameSize(x, y)
            lib.messenger.send(None, "set_frame_size", (x, y), keepAspect)

            #self.control.configureTimeline(secs,frameCount)

        #self.parent.sizer.Fit(self.parent)

    def getDurationInSeconds(self):
        """
		return the duration of the movie in seconds
		"""

        if not self.updated:
            return self.secs

        duration = str(self.duration.GetValue())
        try:
            hh, mm, ss = map(int, duration.split(":"))

        except:
            return 0
        secs = hh * 3600.0 + mm * 60.0 + ss
        self.secs = secs
        self.updated = 0
        return secs

    def updateFPS(self, event):
        """
		update the amount of frames based on the Frames Per Second variable
		"""
        if self.in_framecount:
            return
        self.in_fps = 1
        secs = self.getDurationInSeconds()
        try:
            fps = float(self.frameRate.GetValue())
        except:
            self.in_fps = 0
            return
        newframes = secs * fps

        self.totalFrames.SetValue("%d" % newframes)

        self.in_fps = 0

    def updateDuration(self, event):
        """
		update the amount of frames based on the duration of the movie
		"""
        self.updated = 1
        secs = self.getDurationInSeconds()
        if secs == 0:
            return
        newframes = self.fps * secs
        self.totalFrames.ChangeValue("%d" % newframes)
        #self.fpsLabel.SetLabel("%.2f / second"%newfps)

    def updateFrameCount(self, event):
        """
		Update the frame rate based on the duration
		"""
        if self.in_fps:
            return
        self.in_framecount = 1
        try:
            frameCount = int(self.totalFrames.GetValue())
        except:
            self.in_framecount = 0
            return
        if frameCount == 0:
            self.in_framecount = 0
            return
        secs = self.getDurationInSeconds()

        self.fps = frameCount / float(secs)
        self.frameRate.SetValue("%.2f" % self.fps)
        #self.fpsLabel.SetLabel("%.2f / second"%newfps)
        self.in_framecount = 0
Exemple #7
0
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)

        wxID_RBOXMODE = wx.NewId()
        wxID_LEDSAVE = wx.NewId()

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

        self.ledCtrlDlgMainSz = wx.BoxSizer(wx.VERTICAL)

        self.ledCtrlTimeSz = wx.StaticBoxSizer(
            wx.StaticBox(self, wx.ID_ANY, u" LED контрол "), wx.HORIZONTAL)

        ledRButModeChoices = [u"Ръчен", u"Автоматичен"]
        self.ledRButMode = wx.RadioBox(self, wxID_RBOXMODE, u"Режим на работа",
                                       wx.DefaultPosition, wx.DefaultSize,
                                       ledRButModeChoices, 1,
                                       wx.RA_SPECIFY_COLS)
        self.ledRButMode.SetSelection(0)
        self.ledCtrlTimeSz.Add(self.ledRButMode, 0, wx.ALL, 5)
        self.ledRButMode.Bind(wx.EVT_RADIOBOX,
                              self.OnRBoxChange,
                              id=wxID_RBOXMODE)

        self.textTimePickerStart = wx.StaticText(self,
                                                 -1,
                                                 u"Включване в:",
                                                 size=(80, -1))
        self.timePickerStart = TimeCtrl(self,
                                        id=-1,
                                        value='00:00:00',
                                        pos=wx.DefaultPosition,
                                        size=(65, -1),
                                        style=wx.TE_PROCESS_TAB,
                                        validator=wx.DefaultValidator,
                                        name="time",
                                        format='24HHMM',
                                        fmt24hr=False,
                                        displaySeconds=False,
                                        spinButton=None,
                                        min=None,
                                        max=None,
                                        limited=None,
                                        oob_color="Yellow")
        h = self.timePickerStart.GetSize().height
        self.spinTimePickerStart = wx.SpinButton(self, -1, wx.DefaultPosition,
                                                 (-1, h), wx.SP_VERTICAL)
        self.timePickerStart.BindSpinButton(self.spinTimePickerStart)
        self.addWidgets([
            self.textTimePickerStart, self.timePickerStart,
            self.spinTimePickerStart
        ])

        self.textTimePickerStop = wx.StaticText(self,
                                                -1,
                                                u"Изключване в:",
                                                size=(85, -1))
        self.timePickerStop = TimeCtrl(self,
                                       id=-1,
                                       value='00:00:00',
                                       pos=wx.DefaultPosition,
                                       size=(65, -1),
                                       style=wx.TE_PROCESS_TAB,
                                       validator=wx.DefaultValidator,
                                       name="time",
                                       format='24HHMM',
                                       fmt24hr=False,
                                       displaySeconds=False,
                                       spinButton=None,
                                       min=None,
                                       max=None,
                                       limited=None,
                                       oob_color="Yellow")
        h = self.timePickerStop.GetSize().height
        self.spinTimePickerStop = wx.SpinButton(self, -1, wx.DefaultPosition,
                                                (-1, h), wx.SP_VERTICAL)
        self.timePickerStop.BindSpinButton(self.spinTimePickerStop)
        self.addWidgets([
            self.textTimePickerStop, self.timePickerStop,
            self.spinTimePickerStop
        ])

        self.ledCtrlTimeSz.AddSpacer((0, 0), 1, wx.ALL, 5)

        self.ledButtonSave = wx.Button(self, wxID_LEDSAVE, u"Запазване",
                                       wx.DefaultPosition, wx.DefaultSize, 0)
        self.addWidgets([self.ledButtonSave])

        self.ledCtrlDlgMainSz.Add(self.ledCtrlTimeSz, 1, wx.EXPAND, 5)

        self.ledCtrlDlgMainSz.AddSpacer((0, 0), 1, wx.ALL, 5)

        self.timePickerStart.Disable()
        self.textTimePickerStart.Disable()
        self.spinTimePickerStart.Disable()
        self.timePickerStop.Disable()
        self.textTimePickerStop.Disable()
        self.spinTimePickerStop.Disable()
        self.ledButtonSave.Disable()

        self.SetSizer(self.ledCtrlDlgMainSz)
        self.Layout()

        self.Centre(wx.BOTH)
    def __init__(self, parent):
        #wx.Frame.__init__(self,None,title="QJM Game Master")
        wx.Panel.__init__(self, parent)
        self.Bind(wx.EVT_CLOSE, self.OnClose)

        self.SetMinSize((850, 400))
        self.SetSize((800, 600))

        frame_sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(frame_sizer)
        # create a panel
        main_panel = wx.ScrolledWindow(self)
        frame_sizer.Add(main_panel, 1, wx.ALL | wx.EXPAND)
        main_panel.SetScrollRate(0, 5)
        #main_panel = wx.Panel(self)
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        side_sizer = wx.BoxSizer(wx.HORIZONTAL)
        main_sizer.Add(side_sizer, 1, wx.EXPAND | wx.ALL)
        main_panel.SetSizer(main_sizer)

        ### create a menu
        #menubar = wx.MenuBar()
        #filemenu = wx.Menu()
        #editmenu = wx.Menu()
        #reloadmenu = filemenu.Append(wx.ID_ANY,"&Load state")
        #filemenu.AppendSeparator()
        #quitmenu = filemenu.Append(wx.ID_EXIT, "&Quit", "Quit application")
        #dbmenu = editmenu.Append(wx.ID_ANY,"&Database Editor")
        #menubar.Append(filemenu,"&File")
        #menubar.Append(editmenu,"&Edit")
        #self.SetMenuBar(menubar)

        ## menu binds
        #self.Bind(wx.EVT_MENU,self.OnLoad,reloadmenu)
        #self.Bind(wx.EVT_MENU,self.OnClose,quitmenu)
        #self.Bind(wx.EVT_MENU,self.OnDbEdit,dbmenu)

        sides = ["", "NATO", "Warsaw Pact"]
        # attacker info
        attacker_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel,
                                           "Attacker:")
        side_sizer.Add(attacker_sizer, 1, wx.ALL | wx.EXPAND, 5)
        # attacker side selecton
        self.attacker_side = wx.Choice(main_panel, -1, choices=sides)
        self.attacker_side.Bind(wx.EVT_CHOICE, self.OnAttackerSide)
        attacker_sizer.Add(self.attacker_side, 0, wx.EXPAND, 3)
        # attacker listctrl
        self.attacker_list = CheckListCtrl(main_panel)
        attacker_sizer.Add(self.attacker_list, 1, wx.EXPAND, 3)
        self.attacker_list.InsertColumn(0, "Formation", width=180)
        self.attacker_list.InsertColumn(1, "Strength")
        self.attacker_list.Bind(EVT_CHECKLISTCTRL, self.OnAttackerCheck)
        # TLI output
        self.oli_atk = 0  # tracker
        self.attacker_oli = wx.StaticText(
            main_panel,
            -1,
            "Total attacker OLI: {:>9,.0f}".format(0),
        )
        attacker_sizer.Add(self.attacker_oli, 0,
                           wx.CENTRE | wx.EXPAND | wx.ALL, 3)

        # defender info
        defender_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel,
                                           "Defender:")
        side_sizer.Add(defender_sizer, 1, wx.ALL | wx.EXPAND, 5)
        # defender side selecton
        self.defender_side = wx.Choice(main_panel, -1, choices=sides)
        self.defender_side.Bind(wx.EVT_CHOICE, self.OnDefenderSide)
        defender_sizer.Add(self.defender_side, 0, wx.EXPAND, 3)
        # defender listctrl
        self.defender_list = CheckListCtrl(main_panel)
        defender_sizer.Add(self.defender_list, 1, wx.EXPAND, 3)
        self.defender_list.InsertColumn(0, "Formation", width=180)
        self.defender_list.InsertColumn(1, "Strength")
        self.defender_list.Bind(EVT_CHECKLISTCTRL, self.OnDefenderCheck)
        # TLI output
        self.oli_def = 0  # tracker
        self.defender_oli = wx.StaticText(
            main_panel,
            -1,
            "Total defender OLI: {:>9,.0f}".format(0),
        )
        defender_sizer.Add(self.defender_oli, 0,
                           wx.CENTRE | wx.EXPAND | wx.ALL, 3)

        # bind double click for SITREP
        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.ShowSITREP,
                  self.attacker_list)
        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.ShowSITREP,
                  self.defender_list)

        # battle data #########################
        data_sizer = wx.BoxSizer(wx.HORIZONTAL)
        main_sizer.Add(data_sizer, 0, wx.EXPAND | wx.ALL)
        # duration
        duration_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel,
                                           "Duration (hrs):")
        self.duration = wx.SpinCtrl(main_panel, -1, min=4, max=48, initial=4)
        duration_sizer.Add(self.duration, 1, wx.EXPAND | wx.ALL, 3)
        data_sizer.Add(duration_sizer, 0, wx.EXPAND | wx.ALL, 5)
        # terrain
        terrain_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel, "Terrain:")
        roughness = [
            "rugged, heavily wooded", "rugged, mixed", "rugged, bare",
            "rolling, heavily wooded", "rolling, mixed", "rolling, bare",
            "flat, heavily wooded", "flat, mixed", "flat, bare, hard",
            "flat, desert", "desert, sandy dunes", "swamp, jungled",
            "swamp, mixed or open", "urban"
        ]
        self.terrain = wx.Choice(main_panel, -1, choices=roughness)
        self.terrain.SetSelection(0)
        terrain_sizer.Add(self.terrain, 1, wx.EXPAND | wx.ALL, 3)
        data_sizer.Add(terrain_sizer, 1, wx.EXPAND | wx.ALL, 5)
        # weather
        weather_types = [
            "dry, sunshine, extreme heat",
            "dry, sunshine, temperate",
            "dry, sunshine, extreme cold",
            "dry, overcast, extreme heat",
            "dry, overcast, temperate",
            "dry, overcast, extreme cold",
            "wet, light, extreme heat",
            "wet, light, temperate",
            "wet, light, extreme cold",
            "wet, heavy, extreme heat",
            "wet, heavy, temperate",
            "wet, heavy, extreme cold",
        ]
        weather_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel, "Weather:")
        self.weather = wx.Choice(main_panel, -1, choices=weather_types)
        self.weather.SetSelection(0)
        weather_sizer.Add(self.weather, 1, wx.EXPAND | wx.ALL, 3)
        data_sizer.Add(weather_sizer, 1, wx.EXPAND | wx.ALL, 5)

        # 2nd row
        datar2_sizer = wx.BoxSizer(wx.HORIZONTAL)
        main_sizer.Add(datar2_sizer, 0, wx.EXPAND | wx.ALL)
        # season
        season_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel, "Season:")
        season_choices = [
            "winter, jungle", "winter, desert", "winter, temperate",
            "spring, jungle", "spring, desert", "spring, temperate",
            "summer, jungle", "summer, desert", "summer, temperate",
            "fall, jungle", "fall, desert", "fall, temperate"
        ]
        seasons_choices = ["spring", "summer", "fall", "winter"]
        seasonloc_choices = ["temperate", "jungle", "desert"]
        self.season = wx.Choice(main_panel, -1, choices=seasons_choices)
        self.seasonloc = wx.Choice(main_panel, -1, choices=seasonloc_choices)
        self.season.SetSelection(0)
        self.seasonloc.SetSelection(0)
        season_sizer.Add(self.season, 1, wx.EXPAND | wx.ALL, 3)
        season_sizer.Add(self.seasonloc, 1, wx.EXPAND | wx.ALL, 3)
        datar2_sizer.Add(season_sizer, 1, wx.EXPAND | wx.ALL, 5)
        # roads
        road_density_choices = [
            "dense network", "medium network", "sparse network"
        ]
        road_quality_choices = ["good roads", "mediocre roads", "poor roads"]
        roads_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel, "Roads:")
        self.road_density = wx.Choice(main_panel,
                                      -1,
                                      choices=road_density_choices)
        self.road_density.SetSelection(0)
        self.road_quality = wx.Choice(main_panel,
                                      -1,
                                      choices=road_quality_choices)
        self.road_quality.SetSelection(0)
        roads_sizer.Add(self.road_density, 1, wx.EXPAND | wx.ALL, 3)
        roads_sizer.Add(self.road_quality, 1, wx.EXPAND | wx.ALL, 3)
        datar2_sizer.Add(roads_sizer, 1, wx.EXPAND | wx.ALL, 5)
        # posture
        def_pos_choices = ["hasty", "prepared", "fortified", "delay", "attack"]
        posture_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel,
                                          "Defender posture:")
        self.posture = wx.Choice(main_panel, -1, choices=def_pos_choices)
        self.posture.SetSelection(0)
        posture_sizer.Add(self.posture, 1, wx.EXPAND | wx.ALL, 3)
        datar2_sizer.Add(posture_sizer, 1, wx.EXPAND | wx.ALL, 5)

        # date and name
        mdata_sizer = wx.BoxSizer(wx.HORIZONTAL)
        main_sizer.Add(mdata_sizer, 0, wx.EXPAND | wx.ALL, 0)
        datesizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel,
                                      "Date and location:")
        self.date = DatePickerCtrl(main_panel, -1, style=wx.adv.DP_DROPDOWN)
        self.date.SetValue(wx.DateTime(1, 10, 1983))  # default is 1 Nov 1983
        #self.time = TimePickerCtrl(main_panel,-1)
        self.time = TimeCtrl(main_panel, -1, value='00:00', format='24HHMM')
        self.location = wx.TextCtrl(main_panel, -1, "")
        datesizer.Add(self.date, 0, wx.EXPAND | wx.ALL, 3)
        datesizer.Add(self.time, 0, wx.EXPAND | wx.ALL, 3)
        datesizer.Add(self.location, 1, wx.EXPAND | wx.ALL, 3)
        mdata_sizer.Add(datesizer, 1, wx.EXPAND | wx.ALL, 3)
        # river
        river_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel, "River:")
        river_choices = [
            "no river",
            "fordable, 20m",
            "fordable, 50m",
            "fordable, 100m",
            "fordable, 500m",
            "unfordable, 20m",
            "unfordable, 50m",
            "unfordable, 100m",
            "unfordable, 500m",
        ]
        self.river = wx.Choice(main_panel, -1, choices=river_choices)
        self.river.SetSelection(0)
        river_sizer.Add(self.river, 1, wx.EXPAND | wx.ALL, 3)
        mdata_sizer.Add(river_sizer, 1, wx.EXPAND | wx.ALL, 3)

        # frontage
        frontage_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel,
                                           "Frontage:")
        self.frontage = wx.Slider(main_panel,
                                  -1,
                                  100,
                                  0,
                                  100,
                                  style=wx.SL_HORIZONTAL | wx.SL_LABELS)
        frontage_sizer.Add(self.frontage, 1, wx.EXPAND | wx.ALL, 3)
        mdata_sizer.Add(frontage_sizer, 1, wx.EXPAND | wx.ALL, 3)

        # buttons
        button_panel = wx.Panel(self, style=wx.BORDER_THEME)
        frame_sizer.Add(button_panel, 0, wx.ALL | wx.EXPAND)
        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_panel.SetSizer(button_sizer)
        #main_sizer.Add(button_sizer,0,wx.EXPAND|wx.ALL,)
        self.simulate_btn = wx.Button(button_panel, -1, "Simulate")
        self.simulate_btn.Bind(wx.EVT_BUTTON, self.OnSimulate)
        self.save_btn = wx.Button(button_panel, -1, "Save State")
        self.save_btn.Bind(wx.EVT_BUTTON, self.OnSave)
        self.load_btn = wx.Button(button_panel, -1, "Load State")
        self.load_btn.Bind(wx.EVT_BUTTON, self.OnLoad)
        button_sizer.Add(self.simulate_btn, 1, wx.EXPAND | wx.ALL, 3)
        button_sizer.Add(self.save_btn, 1, wx.EXPAND | wx.ALL, 3)
        button_sizer.Add(self.load_btn, 1, wx.EXPAND | wx.ALL, 3)
class GamemasterWindow(wx.Panel):
    def __init__(self, parent):
        #wx.Frame.__init__(self,None,title="QJM Game Master")
        wx.Panel.__init__(self, parent)
        self.Bind(wx.EVT_CLOSE, self.OnClose)

        self.SetMinSize((850, 400))
        self.SetSize((800, 600))

        frame_sizer = wx.BoxSizer(wx.VERTICAL)
        self.SetSizer(frame_sizer)
        # create a panel
        main_panel = wx.ScrolledWindow(self)
        frame_sizer.Add(main_panel, 1, wx.ALL | wx.EXPAND)
        main_panel.SetScrollRate(0, 5)
        #main_panel = wx.Panel(self)
        main_sizer = wx.BoxSizer(wx.VERTICAL)
        side_sizer = wx.BoxSizer(wx.HORIZONTAL)
        main_sizer.Add(side_sizer, 1, wx.EXPAND | wx.ALL)
        main_panel.SetSizer(main_sizer)

        ### create a menu
        #menubar = wx.MenuBar()
        #filemenu = wx.Menu()
        #editmenu = wx.Menu()
        #reloadmenu = filemenu.Append(wx.ID_ANY,"&Load state")
        #filemenu.AppendSeparator()
        #quitmenu = filemenu.Append(wx.ID_EXIT, "&Quit", "Quit application")
        #dbmenu = editmenu.Append(wx.ID_ANY,"&Database Editor")
        #menubar.Append(filemenu,"&File")
        #menubar.Append(editmenu,"&Edit")
        #self.SetMenuBar(menubar)

        ## menu binds
        #self.Bind(wx.EVT_MENU,self.OnLoad,reloadmenu)
        #self.Bind(wx.EVT_MENU,self.OnClose,quitmenu)
        #self.Bind(wx.EVT_MENU,self.OnDbEdit,dbmenu)

        sides = ["", "NATO", "Warsaw Pact"]
        # attacker info
        attacker_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel,
                                           "Attacker:")
        side_sizer.Add(attacker_sizer, 1, wx.ALL | wx.EXPAND, 5)
        # attacker side selecton
        self.attacker_side = wx.Choice(main_panel, -1, choices=sides)
        self.attacker_side.Bind(wx.EVT_CHOICE, self.OnAttackerSide)
        attacker_sizer.Add(self.attacker_side, 0, wx.EXPAND, 3)
        # attacker listctrl
        self.attacker_list = CheckListCtrl(main_panel)
        attacker_sizer.Add(self.attacker_list, 1, wx.EXPAND, 3)
        self.attacker_list.InsertColumn(0, "Formation", width=180)
        self.attacker_list.InsertColumn(1, "Strength")
        self.attacker_list.Bind(EVT_CHECKLISTCTRL, self.OnAttackerCheck)
        # TLI output
        self.oli_atk = 0  # tracker
        self.attacker_oli = wx.StaticText(
            main_panel,
            -1,
            "Total attacker OLI: {:>9,.0f}".format(0),
        )
        attacker_sizer.Add(self.attacker_oli, 0,
                           wx.CENTRE | wx.EXPAND | wx.ALL, 3)

        # defender info
        defender_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel,
                                           "Defender:")
        side_sizer.Add(defender_sizer, 1, wx.ALL | wx.EXPAND, 5)
        # defender side selecton
        self.defender_side = wx.Choice(main_panel, -1, choices=sides)
        self.defender_side.Bind(wx.EVT_CHOICE, self.OnDefenderSide)
        defender_sizer.Add(self.defender_side, 0, wx.EXPAND, 3)
        # defender listctrl
        self.defender_list = CheckListCtrl(main_panel)
        defender_sizer.Add(self.defender_list, 1, wx.EXPAND, 3)
        self.defender_list.InsertColumn(0, "Formation", width=180)
        self.defender_list.InsertColumn(1, "Strength")
        self.defender_list.Bind(EVT_CHECKLISTCTRL, self.OnDefenderCheck)
        # TLI output
        self.oli_def = 0  # tracker
        self.defender_oli = wx.StaticText(
            main_panel,
            -1,
            "Total defender OLI: {:>9,.0f}".format(0),
        )
        defender_sizer.Add(self.defender_oli, 0,
                           wx.CENTRE | wx.EXPAND | wx.ALL, 3)

        # bind double click for SITREP
        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.ShowSITREP,
                  self.attacker_list)
        self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.ShowSITREP,
                  self.defender_list)

        # battle data #########################
        data_sizer = wx.BoxSizer(wx.HORIZONTAL)
        main_sizer.Add(data_sizer, 0, wx.EXPAND | wx.ALL)
        # duration
        duration_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel,
                                           "Duration (hrs):")
        self.duration = wx.SpinCtrl(main_panel, -1, min=4, max=48, initial=4)
        duration_sizer.Add(self.duration, 1, wx.EXPAND | wx.ALL, 3)
        data_sizer.Add(duration_sizer, 0, wx.EXPAND | wx.ALL, 5)
        # terrain
        terrain_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel, "Terrain:")
        roughness = [
            "rugged, heavily wooded", "rugged, mixed", "rugged, bare",
            "rolling, heavily wooded", "rolling, mixed", "rolling, bare",
            "flat, heavily wooded", "flat, mixed", "flat, bare, hard",
            "flat, desert", "desert, sandy dunes", "swamp, jungled",
            "swamp, mixed or open", "urban"
        ]
        self.terrain = wx.Choice(main_panel, -1, choices=roughness)
        self.terrain.SetSelection(0)
        terrain_sizer.Add(self.terrain, 1, wx.EXPAND | wx.ALL, 3)
        data_sizer.Add(terrain_sizer, 1, wx.EXPAND | wx.ALL, 5)
        # weather
        weather_types = [
            "dry, sunshine, extreme heat",
            "dry, sunshine, temperate",
            "dry, sunshine, extreme cold",
            "dry, overcast, extreme heat",
            "dry, overcast, temperate",
            "dry, overcast, extreme cold",
            "wet, light, extreme heat",
            "wet, light, temperate",
            "wet, light, extreme cold",
            "wet, heavy, extreme heat",
            "wet, heavy, temperate",
            "wet, heavy, extreme cold",
        ]
        weather_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel, "Weather:")
        self.weather = wx.Choice(main_panel, -1, choices=weather_types)
        self.weather.SetSelection(0)
        weather_sizer.Add(self.weather, 1, wx.EXPAND | wx.ALL, 3)
        data_sizer.Add(weather_sizer, 1, wx.EXPAND | wx.ALL, 5)

        # 2nd row
        datar2_sizer = wx.BoxSizer(wx.HORIZONTAL)
        main_sizer.Add(datar2_sizer, 0, wx.EXPAND | wx.ALL)
        # season
        season_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel, "Season:")
        season_choices = [
            "winter, jungle", "winter, desert", "winter, temperate",
            "spring, jungle", "spring, desert", "spring, temperate",
            "summer, jungle", "summer, desert", "summer, temperate",
            "fall, jungle", "fall, desert", "fall, temperate"
        ]
        seasons_choices = ["spring", "summer", "fall", "winter"]
        seasonloc_choices = ["temperate", "jungle", "desert"]
        self.season = wx.Choice(main_panel, -1, choices=seasons_choices)
        self.seasonloc = wx.Choice(main_panel, -1, choices=seasonloc_choices)
        self.season.SetSelection(0)
        self.seasonloc.SetSelection(0)
        season_sizer.Add(self.season, 1, wx.EXPAND | wx.ALL, 3)
        season_sizer.Add(self.seasonloc, 1, wx.EXPAND | wx.ALL, 3)
        datar2_sizer.Add(season_sizer, 1, wx.EXPAND | wx.ALL, 5)
        # roads
        road_density_choices = [
            "dense network", "medium network", "sparse network"
        ]
        road_quality_choices = ["good roads", "mediocre roads", "poor roads"]
        roads_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel, "Roads:")
        self.road_density = wx.Choice(main_panel,
                                      -1,
                                      choices=road_density_choices)
        self.road_density.SetSelection(0)
        self.road_quality = wx.Choice(main_panel,
                                      -1,
                                      choices=road_quality_choices)
        self.road_quality.SetSelection(0)
        roads_sizer.Add(self.road_density, 1, wx.EXPAND | wx.ALL, 3)
        roads_sizer.Add(self.road_quality, 1, wx.EXPAND | wx.ALL, 3)
        datar2_sizer.Add(roads_sizer, 1, wx.EXPAND | wx.ALL, 5)
        # posture
        def_pos_choices = ["hasty", "prepared", "fortified", "delay", "attack"]
        posture_sizer = wx.StaticBoxSizer(wx.VERTICAL, main_panel,
                                          "Defender posture:")
        self.posture = wx.Choice(main_panel, -1, choices=def_pos_choices)
        self.posture.SetSelection(0)
        posture_sizer.Add(self.posture, 1, wx.EXPAND | wx.ALL, 3)
        datar2_sizer.Add(posture_sizer, 1, wx.EXPAND | wx.ALL, 5)

        # date and name
        mdata_sizer = wx.BoxSizer(wx.HORIZONTAL)
        main_sizer.Add(mdata_sizer, 0, wx.EXPAND | wx.ALL, 0)
        datesizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel,
                                      "Date and location:")
        self.date = DatePickerCtrl(main_panel, -1, style=wx.adv.DP_DROPDOWN)
        self.date.SetValue(wx.DateTime(1, 10, 1983))  # default is 1 Nov 1983
        #self.time = TimePickerCtrl(main_panel,-1)
        self.time = TimeCtrl(main_panel, -1, value='00:00', format='24HHMM')
        self.location = wx.TextCtrl(main_panel, -1, "")
        datesizer.Add(self.date, 0, wx.EXPAND | wx.ALL, 3)
        datesizer.Add(self.time, 0, wx.EXPAND | wx.ALL, 3)
        datesizer.Add(self.location, 1, wx.EXPAND | wx.ALL, 3)
        mdata_sizer.Add(datesizer, 1, wx.EXPAND | wx.ALL, 3)
        # river
        river_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel, "River:")
        river_choices = [
            "no river",
            "fordable, 20m",
            "fordable, 50m",
            "fordable, 100m",
            "fordable, 500m",
            "unfordable, 20m",
            "unfordable, 50m",
            "unfordable, 100m",
            "unfordable, 500m",
        ]
        self.river = wx.Choice(main_panel, -1, choices=river_choices)
        self.river.SetSelection(0)
        river_sizer.Add(self.river, 1, wx.EXPAND | wx.ALL, 3)
        mdata_sizer.Add(river_sizer, 1, wx.EXPAND | wx.ALL, 3)

        # frontage
        frontage_sizer = wx.StaticBoxSizer(wx.HORIZONTAL, main_panel,
                                           "Frontage:")
        self.frontage = wx.Slider(main_panel,
                                  -1,
                                  100,
                                  0,
                                  100,
                                  style=wx.SL_HORIZONTAL | wx.SL_LABELS)
        frontage_sizer.Add(self.frontage, 1, wx.EXPAND | wx.ALL, 3)
        mdata_sizer.Add(frontage_sizer, 1, wx.EXPAND | wx.ALL, 3)

        # buttons
        button_panel = wx.Panel(self, style=wx.BORDER_THEME)
        frame_sizer.Add(button_panel, 0, wx.ALL | wx.EXPAND)
        button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        button_panel.SetSizer(button_sizer)
        #main_sizer.Add(button_sizer,0,wx.EXPAND|wx.ALL,)
        self.simulate_btn = wx.Button(button_panel, -1, "Simulate")
        self.simulate_btn.Bind(wx.EVT_BUTTON, self.OnSimulate)
        self.save_btn = wx.Button(button_panel, -1, "Save State")
        self.save_btn.Bind(wx.EVT_BUTTON, self.OnSave)
        self.load_btn = wx.Button(button_panel, -1, "Load State")
        self.load_btn.Bind(wx.EVT_BUTTON, self.OnLoad)
        button_sizer.Add(self.simulate_btn, 1, wx.EXPAND | wx.ALL, 3)
        button_sizer.Add(self.save_btn, 1, wx.EXPAND | wx.ALL, 3)
        button_sizer.Add(self.load_btn, 1, wx.EXPAND | wx.ALL, 3)

    def OnAttackerCheck(self, event):
        idx = event.idx
        name = self.attacker_list.GetItemText(idx, col=0)
        form = self.GetTopLevelParent().gdb.gm_forms_db.formation_by_name(name)
        flag = event.flg
        if flag:  # if checked, add the OLI value
            self.oli_atk += form.OLI
        else:  # if unchecked, remove it
            self.oli_atk += -form.OLI
        # update the OLI display
        self.attacker_oli.SetLabel("Total attacker OLI: {:>9,.0f}".format(
            self.oli_atk))

    def OnDefenderCheck(self, event):
        idx = event.idx
        name = self.defender_list.GetItemText(idx, col=0)
        form = self.GetTopLevelParent().gdb.gm_forms_db.formation_by_name(name)
        flag = event.flg
        if flag:  # if checked, add the OLI value
            self.oli_def += form.OLI
        else:  # if unchecked, remove it
            self.oli_def += -form.OLI
        # update the OLI display
        self.defender_oli.SetLabel("Total defender OLI: {:>9,.0f}".format(
            self.oli_def))

    def OnAttackerSide(self, event):
        # set both OLI values to zero
        self.attacker_oli.SetLabel("Total attacker OLI: {:>9,.0f}".format(0))
        self.defender_oli.SetLabel("Total defender OLI: {:>9,.0f}".format(0))
        self.attacker_list.DeleteAllItems()  # clear items
        side = self.attacker_side.GetString(self.attacker_side.GetSelection())
        if side == "":
            return
        faction_search = side_dict[side]
        formations = self.GetTopLevelParent().gdb.gm_forms_db.forms
        for form in formations:
            if form.faction in faction_search:
                entry = [form.name, "{:,.0f}".format(form.OLI)]
                self.attacker_list.Append(entry)

    def OnDefenderSide(self, event):
        self.defender_list.DeleteAllItems()  # clear items
        side = self.defender_side.GetString(self.defender_side.GetSelection())
        if side == "":
            return
        faction_search = side_dict[side]
        formations = self.GetTopLevelParent().gdb.gm_forms_db.forms
        for form in formations:
            if form.faction in faction_search:
                entry = [form.name, "{:,.0f}".format(form.OLI)]
                self.defender_list.Append(entry)

    def OnSimulate(self, event):
        # Multiply force strength by operational variables - overall forms a big ugly equation
        # force strength is shown by:
        # S = [(ws+Wmg+Whw)*rn]+(wgi*rn)+[(Wg+Wgy)*(rwg*hwg*zwg*wyg)]+(Wi*rwi*hwi)+ ...
        #        ...(Wy*rwy*hwy*zyw*wyy) + Wgi + Wgy
        #   note Wgi is included up to enemy armour OLI, then only half excess is added
        #   same applies for Wfgy for air defense weapons, up to hostile Close Air Support (Wey)
        # Air firepower (Wy) over sum of all ground firepower is not fully effective
        # Wy > Ws + Wmy + Whw + Wgi + Wg + Wgy + Wi, only half of excess Wy is applied
        #       maximum Wy is 3x ground weapons firepower
        #
        # operational factors are given by:
        # [Ma-(1-rm*hm)(Ma-1)]*le*t*o*b*us*ru*hu*zu*v
        #       where v = 1-(N*uv/ru*(Se/Sf)**.5 * vy*vr)/Sf
        # Following are degredation factors
        # le: leadership - typically 1
        # t: training/experience - typically 1
        # o: morale - typically 1
        # b: logistical capability - typically 1

        # Get OLI values from checked attackers
        attackers = list()
        attackers_forms = list()
        for idx in range(self.attacker_list.GetItemCount()):
            if self.attacker_list.IsChecked(idx):
                attackers.append(self.attacker_list.GetItemText(idx))
        for form in attackers:
            attackers_forms.append(
                self.GetTopLevelParent().gdb.gm_forms_db.formation_by_name(
                    form))
        attacker_oli = self.GetTopLevelParent().gdb.gm_forms_db.oli_by_names(
            attackers)
        N_attacker = self.GetTopLevelParent().gdb.gm_forms_db.pers_by_names(
            attackers)
        J_attacker = self.GetTopLevelParent(
        ).gdb.gm_forms_db.vehicles_by_names(
            attackers,
            self.GetTopLevelParent().gdb.equip_db)

        # Get OLI values from checked defenders
        defenders = list()
        defenders_forms = list()
        for idx in range(self.defender_list.GetItemCount()):
            if self.defender_list.IsChecked(idx):
                defenders.append(self.defender_list.GetItemText(idx))
        defender_oli = self.GetTopLevelParent().gdb.gm_forms_db.oli_by_names(
            defenders)
        for form in defenders:
            defenders_forms.append(
                self.GetTopLevelParent().gdb.gm_forms_db.formation_by_name(
                    form))

        N_defender = self.GetTopLevelParent().gdb.gm_forms_db.pers_by_names(
            defenders)
        J_defender = self.GetTopLevelParent(
        ).gdb.gm_forms_db.vehicles_by_names(
            defenders,
            self.GetTopLevelParent().gdb.equip_db)

        # get environment data from the forms
        terrain = self.terrain.GetString(self.terrain.GetSelection())
        weather = self.weather.GetString(self.weather.GetSelection())
        season_sel = self.season.GetString(self.season.GetSelection())
        season_locale = self.seasonloc.GetString(self.seasonloc.GetSelection())
        river = self.river.GetString(self.river.GetSelection())
        time_day = self.time.GetValue()
        print(time_day)
        # determine if it is day or night
        if time_day > "06:00" and time_day < "20:00":
            daytime = True
        else:
            daytime = False

        # get the frontage of the attack (% of defenders)
        frontage = self.frontage.GetValue() / 100

        seasonstr = season_sel + ', ' + season_locale
        #print(seasonstr)

        # get the posture from the form
        def_posture = self.posture.GetString(self.posture.GetSelection())

        # Terrain effectiveness values (r) and weather effectiveness (h)
        # infantry & antitank
        rn = mc.terrain(terrain, 'inf')
        # artillery & air defence
        rwg = mc.terrain(terrain, 'arty')
        hwg = mc.weather(weather, 'arty')
        zwg = mc.season(seasonstr, 'arty')
        # tanks
        rwi = mc.terrain(terrain, 'tank')
        hwi = mc.weather(weather, 'tank')
        # aircraft
        rwy = mc.terrain(terrain, 'air')
        hwy = mc.weather(weather, 'air')
        zwy = mc.season(seasonstr, 'air')

        # these constants are for air superiority
        wyg = 1
        wyy = 1

        print(attacker_oli.air, attacker_oli.ad)
        print(defender_oli.air, defender_oli.ad)

        # attacker data:
        Wain = attacker_oli.inf
        Waat = attacker_oli.at
        Watn = attacker_oli.afv
        Waar = attacker_oli.arty
        Waad = attacker_oli.ad
        Waai = attacker_oli.air

        # defender data
        Wdin = defender_oli.inf
        Wdat = defender_oli.at
        Wdtn = defender_oli.afv
        Wdar = defender_oli.arty
        Wdad = defender_oli.ad
        Wdai = defender_oli.air

        # deal with overmatches in at and ad OLIs
        Waat = overmatch(Waat, Wdtn)
        Wdat = overmatch(Wdat, Watn)
        Waad = overmatch(Waad, Wdai, cap=3)
        Wdad = overmatch(Wdad, Waai, cap=3)

        # using my "simplified" formula
        S_attacker = ((Wain + Waat) * rn +
                      (Waar + Waad * wyg) * rwg * hwg * zwg +
                      Watn * rwi * hwi + Waai * rwy * hwy * zwy * wyy)
        S_defender = (
            (Wdin + Wdat) * rn + (Wdar + Wdad * wyg) * rwg * hwg * zwg +
            Wdtn * rwi * hwi + Wdai * rwy * hwy * zwy * wyy) * frontage

        # get the combat power
        Faj = 1  # judgement degrading factor for attacker
        Fdj = 1  # judgement degrading factor for defender
        uas = mc.stren_posture_factor('attack')  # posture for attacker
        uds = mc.stren_posture_factor(def_posture)  # posture for defender
        rau = 1  # terrain for attacker - attacker is always 1
        rdu = mc.terrain(
            terrain, 'defpos')  # terrain for defender - uses terrain defpos
        hau = mc.weather(weather, 'attack')  # weather for attacker
        hdu = 1  # weather for defender - defender is always 1
        zau = mc.season(seasonstr, 'attack')  # season for attacker
        zdu = 1  # season for defender - defender is always 1

        # mobility factors
        road_quality = self.road_quality.GetString(
            self.road_quality.GetSelection())
        road_density = self.road_density.GetString(
            self.road_density.GetSelection())
        rma = mc.terrain(terrain, 'mobility')
        hma = mc.weather(weather, 'mobility')
        mya = 1  # don't know what this factor is
        myd = 1  # don't know what this factor is either

        # vulnerability factors
        uav = mc.vuln_posture_factor('attack')
        udv = mc.vuln_posture_factor(def_posture)
        vay = 1  # air superiority vulnerability
        vdy = 1  # air superiority vulnerability
        var = 1  # shoreline vulnerability
        vdr = 1  # shoreline vulnerability

        # mobility
        MFactor = 12  # 20 for WWII
        M_attacker = ((
            (N_attacker + MFactor * J_attacker + Waar) * mya / N_attacker) /
                      ((N_defender + MFactor * J_defender + Wdar) * myd /
                       N_defender))**0.5
        M_defender = 1  # always 1

        ma_operational = M_attacker - (1 - rma * hma) * (M_attacker - 1)
        md_operational = M_defender

        # vulnerability
        Vuln_attacker = N_attacker * uav / rau * (S_defender /
                                                  S_attacker)**0.5 * vay * var
        print("Vulnerability calcs:", N_attacker, uav, rau, S_defender,
              S_attacker, vay, var)
        Vuln_defender = N_defender * udv / rdu * (S_attacker /
                                                  S_defender)**0.5 * vdy * vdr
        va_operational = (1 - Vuln_attacker / S_attacker)
        vd_operational = (1 - Vuln_defender / S_defender)

        if va_operational > 0.8:
            va_operational = 0.8
        elif va_operational > 0.3:
            va_operational = 0.3 + 0.1 * (va_operational - 0.3)
        else:
            va_operational = 0.3
        if vd_operational > 0.8:
            vd_operational = 0.8
        elif vd_operational > 0.3:
            vd_operational = 0.3 + 0.1 * (vd_operational - 0.3)
        else:
            vd_operational = 0.3

        # note that the CEV is already contained in the OLI output
        Op_attacker = Faj * uas * rau * hau * zau
        Op_defender = Fdj * uds * rdu * hdu * zdu

        P_attacker = S_attacker * ma_operational * Op_attacker * va_operational
        P_defender = S_defender * md_operational * Op_defender * vd_operational
        P_ratio = P_attacker / P_defender

        dateval = self.date.GetValue().FormatISODate()
        #timeval = self.time.GetValue().FormatISOTime()
        timeval = self.time.GetWxDateTime().FormatISOTime()
        location = self.location.GetValue()

        print("*** START REPORT ***\n")

        print("{} engages {}\n".format(attackers, defenders))

        print(
            "Base OLI data: (W) || Attacker: {:9,.0f} | Defender: {:9,.0f} | Ratio {:.1f}"
            .format(attacker_oli.total, defender_oli.total,
                    attacker_oli.total / defender_oli.total))

        print(
            "Strength data (S): || Attacker: {:9,.0f} | Defender: {:9,.0f} | Ratio {:.1f}"
            .format(S_attacker, S_defender, S_attacker / S_defender))

        print(
            "Combat Power (P):  || Attacker: {:9,.0f} | Defender: {:9,.0f} | Ratio {:.1f}"
            .format(P_attacker, P_defender, P_attacker / P_defender))

        print(
            "\n Key factors: |  Attacker | Defender\n",
            "Strength     | {:9,.0f} | {:9,.0f}\n".format(
                S_attacker, S_defender),
            "Mobility     | {:9,.2f} | {:9,.2f}\n".format(
                M_attacker, M_defender),
            "Vulnerability| {:9,.0f} | {:9,.0f}\n".format(
                Vuln_attacker, Vuln_defender),
            "Op. Vuln     | {:9,.3f} | {:9,.3f}\n".format(
                va_operational, vd_operational),
        )

        # advance rate - probably need to run for each individual formation?
        for name in attackers:
            index = self.GetTopLevelParent().gdb.gm_forms_db.names.index(name)
            unittype = self.GetTopLevelParent(
            ).gdb.gm_forms_db.forms[index].type
            adv_base = mc.advance_rate_base(P_ratio, unittype, def_posture)
            adv_roads = mc.advance_rate_road(road_quality, road_density)
            adv_terr = mc.advance_rate_terr(terrain, unittype)
            adv_river = mc.river_obstacle_factor(river)
            adv_rate = adv_base * adv_roads * adv_terr * adv_river
            atk_losses = self.GetTopLevelParent(
            ).gdb.gm_forms_db.forms[index].casualties(
                P_ratio,
                'attack',
                day=daytime,
                duration=self.duration.GetValue(),
                pers=N_attacker)
            print("{} advance rate: {:.1f} km/day".format(
                self.GetTopLevelParent().gdb.gm_forms_db.forms[index].name,
                adv_rate))
            print("---")
            print(self.GetTopLevelParent().gdb.gm_forms_db.forms[index].SITREP(
                atk_losses,
                activity='Attacking',
                datestr="{} {}".format(dateval, timeval),
                location=location,
                writefolder=gmdir + "\\reports"))

        for name in defenders:
            index = self.GetTopLevelParent().gdb.gm_forms_db.names.index(name)
            def_losses = self.GetTopLevelParent(
            ).gdb.gm_forms_db.forms[index].casualties(
                P_ratio,
                def_posture,
                day=daytime,
                duration=self.duration.GetValue(),
                exposure=frontage,
                pers=N_defender)
            print("---")
            print(self.GetTopLevelParent().gdb.gm_forms_db.forms[index].SITREP(
                def_losses,
                activity=def_posture + ' defense',
                datestr="{} {}".format(dateval, timeval),
                location=location,
                writefolder=gmdir + "\\reports"))

        # finish the report
        print("*** END REPORT ***")

    def ShowSITREP(self, event):
        # get the list that was clicked
        formlist = event.GetEventObject()
        # get the item from the list
        item = formlist.GetItemText(event.GetIndex(), col=0)
        # print a sitrep for the item
        form = self.GetTopLevelParent().gdb.gm_forms_db.formation_by_name(item)
        infoframe = formation_info_form(
            self,
            form.SITREP(activity='None') +
            "\nNo TLI data for:\n{}".format(form.NoTLIData), item)
        infoframe.Show()

    def OnDbEdit(self, event):
        eqp = equip_gui.equipment_gui_frame()
        eqp.Show()

    def OnSave(self, event):
        dlg = wx.DirDialog(self,
                           message="Master folder for formations to save",
                           defaultPath=gmdir)
        result = dlg.ShowModal()
        path = dlg.GetPath()
        dlg.Destroy()
        if result == wx.ID_OK:
            for form in self.GetTopLevelParent().gdb.gm_forms_db.forms:
                form.output(path)

    def OnLoad(self, event):
        dlg = wx.DirDialog(self,
                           message="Master folder for formations to load",
                           defaultPath=gmdir)
        result = dlg.ShowModal()
        path = dlg.GetPath()
        dlg.Destroy()
        if result == wx.ID_OK:
            self.GetTopLevelParent().gdb.load_gm_formations(path)

    def OnClose(self, event):
        dlg = wx.MessageDialog(self, "Are you sure you want to close?",
                               "Confirm exit",
                               wx.OK | wx.CANCEL | wx.ICON_QUESTION)
        result = dlg.ShowModal()
        dlg.Destroy()
        if result == wx.ID_OK:
            self.Destroy()
Exemple #10
0
    def __init__(self, parent, title, sdb):

        wx.Frame.__init__(self, parent, title=title, size=(200, 100))
        self.timeControl = TimeCtrl(self,
                                    -1,
                                    value='00:00:00',
                                    pos=wx.DefaultPosition,
                                    size=wx.DefaultSize,
                                    style=wx.TE_PROCESS_TAB,
                                    validator=wx.DefaultValidator,
                                    name="time",
                                    format='HHMMSS',
                                    fmt24hr=True,
                                    displaySeconds=False,
                                    spinButton=None,
                                    min=None,
                                    max=None,
                                    limited=None,
                                    oob_color="Yellow")

        self.sizer = wx.GridSizer(rows=4, cols=1, hgap=0, vgap=0)

        self.timeControlSizer = wx.GridSizer(rows=1, cols=1, hgap=0, vgap=0)
        self.timeControlSizer.Add(self.timeControl, 0, wx.EXPAND)
        self.sizer.Add(self.timeControlSizer, 0, wx.ALIGN_CENTER)

        # Button to set alarm
        self.setButton = wx.Button(self, -1, "Set Alarm")
        self.setButton.Bind(wx.EVT_BUTTON, self.OnAlarm)

        # Button to reset alarm
        self.resetButton = wx.ToggleButton(self, wx.ID_ANY, "OFF")
        self.resetButton.SetBackgroundColour('RED')
        self.resetButton.SetValue(False)
        self.resetButton.Bind(wx.EVT_TOGGLEBUTTON, self.OnReset)

        self.alarmControlSizer = wx.GridSizer(rows=1, cols=2, hgap=0, vgap=0)
        self.alarmControlSizer.Add(self.setButton, 0, wx.EXPAND)
        self.alarmControlSizer.Add(self.resetButton, 0, wx.EXPAND)
        self.sizer.Add(self.alarmControlSizer, 0, wx.EXPAND)

        # Now Playing
        self.nowPlaying = wx.TextCtrl(self, wx.ID_ANY, NOW_PLAYING)
        self.nowPlaying.SetEditable(False)
        self.sizer.Add(self.nowPlaying, 0, wx.EXPAND)
        self.SetNowPlaying(sdbPlayer.CurrentSong.ArtistName,
                           sdbPlayer.CurrentSong.Title)

        # Player Controls
        self.controlsSizer = wx.GridSizer(rows=1, cols=4, hgap=0, vgap=0)

        self.playButton = wx.Button(self, wx.ID_ANY, "> ||")
        self.playButton.Bind(wx.EVT_BUTTON, self.OnPressPlay)

        self.stopButton = wx.Button(self, wx.ID_ANY, "x")
        self.stopButton.Bind(wx.EVT_BUTTON, self.OnPressStop)

        self.nextButton = wx.Button(self, wx.ID_ANY, ">>")
        self.nextButton.Bind(wx.EVT_BUTTON, self.OnPressNext)

        self.prevButton = wx.Button(self, wx.ID_ANY, "<<")
        self.prevButton.Bind(wx.EVT_BUTTON, self.OnPressPrev)

        self.controlsSizer.Add(self.playButton, 0, wx.EXPAND)
        self.controlsSizer.Add(self.stopButton, 0, wx.EXPAND)
        self.controlsSizer.Add(self.prevButton, 0, wx.EXPAND)
        self.controlsSizer.Add(self.nextButton, 0, wx.EXPAND)

        self.sizer.Add(self.controlsSizer, 0, wx.EXPAND)

        self.SetBackgroundColour('WHITE')
        self.CreateStatusBar()

        # File Menu Set Up
        filemenu = wx.Menu()

        menuAbout = filemenu.Append(
            wx.ID_ABOUT, "&About",
            "An alarm clock that ties into Media Monkey and triggers\
             a play on the now playing playlist.")
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)

        menuExit = filemenu.Append(wx.ID_EXIT, "&Exit",
                                   "Terminate the Program")
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

        # Create the Menu Bar.
        menuBar = wx.MenuBar()
        menuBar.Append(filemenu, "&File")
        self.SetMenuBar(menuBar)

        #Layout sizers
        self.SetSizer(self.sizer)
        self.SetAutoLayout(1)
        self.sizer.Fit(self)

        # Set the window to be visible.
        self.Show(True)
Exemple #11
0
class MainWindow(wx.Frame):
    def __init__(self, parent, title, sdb):

        wx.Frame.__init__(self, parent, title=title, size=(200, 100))
        self.timeControl = TimeCtrl(self,
                                    -1,
                                    value='00:00:00',
                                    pos=wx.DefaultPosition,
                                    size=wx.DefaultSize,
                                    style=wx.TE_PROCESS_TAB,
                                    validator=wx.DefaultValidator,
                                    name="time",
                                    format='HHMMSS',
                                    fmt24hr=True,
                                    displaySeconds=False,
                                    spinButton=None,
                                    min=None,
                                    max=None,
                                    limited=None,
                                    oob_color="Yellow")

        self.sizer = wx.GridSizer(rows=4, cols=1, hgap=0, vgap=0)

        self.timeControlSizer = wx.GridSizer(rows=1, cols=1, hgap=0, vgap=0)
        self.timeControlSizer.Add(self.timeControl, 0, wx.EXPAND)
        self.sizer.Add(self.timeControlSizer, 0, wx.ALIGN_CENTER)

        # Button to set alarm
        self.setButton = wx.Button(self, -1, "Set Alarm")
        self.setButton.Bind(wx.EVT_BUTTON, self.OnAlarm)

        # Button to reset alarm
        self.resetButton = wx.ToggleButton(self, wx.ID_ANY, "OFF")
        self.resetButton.SetBackgroundColour('RED')
        self.resetButton.SetValue(False)
        self.resetButton.Bind(wx.EVT_TOGGLEBUTTON, self.OnReset)

        self.alarmControlSizer = wx.GridSizer(rows=1, cols=2, hgap=0, vgap=0)
        self.alarmControlSizer.Add(self.setButton, 0, wx.EXPAND)
        self.alarmControlSizer.Add(self.resetButton, 0, wx.EXPAND)
        self.sizer.Add(self.alarmControlSizer, 0, wx.EXPAND)

        # Now Playing
        self.nowPlaying = wx.TextCtrl(self, wx.ID_ANY, NOW_PLAYING)
        self.nowPlaying.SetEditable(False)
        self.sizer.Add(self.nowPlaying, 0, wx.EXPAND)
        self.SetNowPlaying(sdbPlayer.CurrentSong.ArtistName,
                           sdbPlayer.CurrentSong.Title)

        # Player Controls
        self.controlsSizer = wx.GridSizer(rows=1, cols=4, hgap=0, vgap=0)

        self.playButton = wx.Button(self, wx.ID_ANY, "> ||")
        self.playButton.Bind(wx.EVT_BUTTON, self.OnPressPlay)

        self.stopButton = wx.Button(self, wx.ID_ANY, "x")
        self.stopButton.Bind(wx.EVT_BUTTON, self.OnPressStop)

        self.nextButton = wx.Button(self, wx.ID_ANY, ">>")
        self.nextButton.Bind(wx.EVT_BUTTON, self.OnPressNext)

        self.prevButton = wx.Button(self, wx.ID_ANY, "<<")
        self.prevButton.Bind(wx.EVT_BUTTON, self.OnPressPrev)

        self.controlsSizer.Add(self.playButton, 0, wx.EXPAND)
        self.controlsSizer.Add(self.stopButton, 0, wx.EXPAND)
        self.controlsSizer.Add(self.prevButton, 0, wx.EXPAND)
        self.controlsSizer.Add(self.nextButton, 0, wx.EXPAND)

        self.sizer.Add(self.controlsSizer, 0, wx.EXPAND)

        self.SetBackgroundColour('WHITE')
        self.CreateStatusBar()

        # File Menu Set Up
        filemenu = wx.Menu()

        menuAbout = filemenu.Append(
            wx.ID_ABOUT, "&About",
            "An alarm clock that ties into Media Monkey and triggers\
             a play on the now playing playlist.")
        self.Bind(wx.EVT_MENU, self.OnAbout, menuAbout)

        menuExit = filemenu.Append(wx.ID_EXIT, "&Exit",
                                   "Terminate the Program")
        self.Bind(wx.EVT_MENU, self.OnExit, menuExit)

        # Create the Menu Bar.
        menuBar = wx.MenuBar()
        menuBar.Append(filemenu, "&File")
        self.SetMenuBar(menuBar)

        #Layout sizers
        self.SetSizer(self.sizer)
        self.SetAutoLayout(1)
        self.sizer.Fit(self)

        # Set the window to be visible.
        self.Show(True)

    def OnAbout(self, e):
        # A message dialog with OK button.
        dlg = wx.MessageDialog(
            self, "An alarm clock that ties into Media Monkey and triggers\
                 a play on the now playing playlist. \n\n Created by Natasha Dalal (2014).",
            "About", wx.OK)
        dlg.ShowModal()
        dlg.Destroy()  # Destroy the window when it is finished.
        print('resetting')

    def OnExit(self, e):
        self.Close(True)

    def OnReset(self, e):
        self.ToggleReset()

    def ToggleReset(self):
        self.SetAlarmArmed(self.resetButton.GetValue())

    def SetAlarmArmed(self, arm):
        self.resetButton.SetValue(arm)
        if not arm:
            self.resetButton.SetBackgroundColour('RED')
            self.resetButton.SetLabel("OFF")
            try:
                self.timer.Stop()
                print "Disarming Alarm"
            except:
                print "No timer currently set"
        else:
            print "Arming Alarm"
            self.resetButton.SetBackgroundColour('GREEN')
            self.resetButton.SetLabel("ON")

    def OnAlarm(self, e):
        try:
            self.timer.Stop()
        except:
            print "No timer currently set"

        # Get the current set alarm time:
        atTime = self.timeControl.GetValue(as_wxDateTime=True)

        # Set the date to the right date.
        atTime.SetDay(wx.DateTime.Today().GetDay())
        atTime.SetMonth(wx.DateTime.Today().GetMonth())
        atTime.SetYear(wx.DateTime.Today().GetYear())

        # If the time specified has already passed, set it for
        # the provided time on the next day.
        now = wx.DateTime.Now()
        if atTime.IsEarlierThan(now):
            # Number of Days in the current month
            dim = wx.DateTime.GetNumberOfDaysInMonth(atTime.GetMonth())
            if atTime.GetDay() == dim:
                atTime.SetDay(1)
                atTime.SetMonth(atTime.GetMonth() + 1)
            else:
                atTime.SetDay(atTime.GetDay() + 1)

        # At this point, atTime should be the right time and date.

        # The sleep time in seconds
        sleepTime = atTime.GetTicks() - now.GetTicks()
        self.timer = wx.Timer(self, -1)
        self.Bind(wx.EVT_TIMER, self.DoPlay)

        self.timer.Start(sleepTime * 1000, wx.TIMER_ONE_SHOT)
        self.SetAlarmArmed(True)

    def DoPlay(self, e):
        print("Starting to Play")
        sdbPlayer.Play()
        self.ToggleReset()

    def SetNowPlaying(self, artist, title):
        self.nowPlaying.SetValue(NOW_PLAYING + artist + " - " + title)

    # Player Control Handlers
    def OnPressPlay(self, e):
        if sdbPlayer.isPlaying:
            sdbPlayer.Pause()
        else:
            sdbPlayer.Play()

    def OnPressStop(self, e):
        sdbPlayer.Stop()

    def OnPressNext(self, e):
        sdbPlayer.Next()

    def OnPressPrev(self, e):
        sdbPlayer.Previous()