'''metronome2
Now try to get a visual component flashing with each beat
'''
import wx

mspm = 60*1000 # milliseconds per minute
    
class MFrame(wx.Frame):
    def __init__(self,):
        wx.Frame.__init__(self,None)
        #define the components
        self.go = wx.Button(self,wx.ID_ANY,"Start")
        self.stop = wx.Button(self,wx.ID_ANY,"Stop")
        self.bpm = wx.SpinCtrl(self,wx.ID_ANY,value="120",min=1,max=240)
        self.dingcheck = wx.CheckBox(self,wx.ID_ANY)
        self.downbeat = wx.SpinCtrl(self,wx.ID_ANY,value="4",min = 2, max=12)
        self.flashcheck = wx.CheckBox(self,wx.ID_ANY,"Flash")
        self.flash = wx.Panel(self,wx.ID_ANY,size=(150,150))

        self.dingcheck.SetValue(False)
        self.downbeat.Enable(False)
        self.flashing = True
        self.flashcheck.SetValue(True)
        self.SetFlash()
        
        #do the layout
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(wx.StaticText(self,wx.ID_ANY,"Set the beats per minute"))
        sizer.Add(self.bpm)
        sizer.Add(self.go)
        sizer.Add(self.stop)
        s2 = wx.BoxSizer(wx.HORIZONTAL)
        s2.Add(self.dingcheck,0,wx.ALIGN_CENTRE_VERTICAL)
        s2.Add(wx.StaticText(self,wx.ID_ANY,"Beats per measure"),0,wx.ALIGN_CENTRE_VERTICAL)
        s2.Add(self.downbeat)
        sizer.Add(s2)
        sizer.Add(self.flashcheck,0,wx.ALIGN_CENTRE)
        sizer.Add(self.flash,1,wx.ALL|wx.EXPAND|wx.ALIGN_CENTRE,10)
        self.SetSizerAndFit(sizer)
        self.Layout()
        
        #Bind events
        self.Bind(wx.EVT_BUTTON,self.Start,self.go)
        self.Bind(wx.EVT_BUTTON,self.Stop,self.stop)
        self.Bind(wx.EVT_TIMER,self.Tick)
        self.Bind(wx.EVT_CHECKBOX,self.SetDownBeat,self.dingcheck)

    def SetFlash(self):
        if self.flashcheck.IsChecked():
            if self.flashing:
                self.flash.SetBackgroundColour('White')
            else:
                self.flash.SetBackgroundColour('Black')
            self.flash.Refresh()
        self.flashing = not self.flashing
        
    def SetDownBeat(self,evt):
        if self.dingcheck.IsChecked():
            self.downbeat.Enable(True)
        else:
            self.downbeat.Enable(False)
            
    def Start(self,evt):
        self.timer=wx.Timer(self)
        self.count = 0
        self.timer.Start(mspm/float(self.bpm.GetValue()))
        self.go.Enable(False)
        self.stop.Enable(True)

    def Stop(self,evt):
        self.timer.Stop()
        del self.timer
        self.go.Enable(True)
        self.stop.Enable(False)

    def Tick(self,evt):
        if bool(self.count):
            sound = wx.Sound('tick2.wav')
        else:
            if self.dingcheck.IsChecked():
                sound = wx.Sound('ding.wav')
            else:
                sound = wx.Sound('tick2.wav')
        sound.Play(wx.SOUND_ASYNC)
        self.SetFlash()
        self.count = (self.count + 1) % int(self.downbeat.GetValue())
        wx.YieldIfNeeded()
        
class TestApp(wx.App):
    def OnInit(self):
        mainframe = MFrame()
        self.SetTopWindow(mainframe)
        mainframe.Show()
        return 1


app = TestApp(0)
app.MainLoop()
