class DialogSats(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent=parent, title='GPS Satellite Levels')
        self.parent = parent

        self.satLevel = SatLevel(self)

        self.textSats = wx.StaticText(self)
        self.__set_text(0, 0)

        self.Bind(wx.EVT_CLOSE, self.__on_close)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.satLevel, 1, flag=wx.ALL | wx.EXPAND, border=5)
        sizer.Add(self.textSats, 0, flag=wx.ALL | wx.EXPAND, border=5)

        self.SetSizerAndFit(sizer)

    def __set_text(self, used, seen):
        self.textSats.SetLabel('Satellites: {} used, {} seen'.format(used,
                                                                     seen))

    def __on_close(self, _event):
        self.Unbind(wx.EVT_CLOSE)
        self.parent.dlgSats = None
        self.Close()

    def set_sats(self, sats):
        self.satLevel.set_sats(sats)
        used = sum(1 for sat in sats.values() if sat[1])
        self.__set_text(used, len(sats))
    def __init__(self, parent, device):
        self.device = device
        self.threadLocation = None
        self.raw = ''

        wx.Dialog.__init__(self, parent=parent, title='GPS Test')

        textLat = wx.StaticText(self, label='Longitude')
        self.textLat = wx.TextCtrl(self, style=wx.TE_READONLY)
        textLon = wx.StaticText(self, label='Latitude')
        self.textLon = wx.TextCtrl(self, style=wx.TE_READONLY)
        textAlt = wx.StaticText(self, label='Altitude')
        self.textAlt = wx.TextCtrl(self, style=wx.TE_READONLY)
        textSats = wx.StaticText(self, label='Satellites')
        self.textSats = wx.TextCtrl(self, style=wx.TE_READONLY)
        textRaw = wx.StaticText(self, label='Raw output')
        self.textRaw = wx.TextCtrl(self,
                                   style=wx.TE_MULTILINE | wx.TE_READONLY)

        textLevel = wx.StaticText(self, label='Level')
        self.satLevel = SatLevel(self)

        self.buttonStart = wx.Button(self, label='Start')
        self.Bind(wx.EVT_BUTTON, self.__on_start, self.buttonStart)
        self.buttonStop = wx.Button(self, label='Stop')
        self.Bind(wx.EVT_BUTTON, self.__on_stop, self.buttonStop)
        self.buttonStop.Disable()

        buttonOk = wx.Button(self, wx.ID_OK)
        self.Bind(wx.EVT_BUTTON, self.__on_ok, buttonOk)

        grid = wx.GridBagSizer(10, 10)

        grid.Add(textLat, pos=(0, 0), flag=wx.ALL, border=5)
        grid.Add(self.textLat, pos=(0, 1), span=(1, 2), flag=wx.ALL, border=5)
        grid.Add(textLon, pos=(1, 0), flag=wx.ALL, border=5)
        grid.Add(self.textLon, pos=(1, 1), span=(1, 2), flag=wx.ALL, border=5)
        grid.Add(textAlt, pos=(2, 0), flag=wx.ALL, border=5)
        grid.Add(self.textAlt, pos=(2, 1), span=(1, 2), flag=wx.ALL, border=5)
        grid.Add(textSats, pos=(3, 0), flag=wx.ALL, border=5)
        grid.Add(self.textSats, pos=(3, 1), span=(1, 2), flag=wx.ALL, border=5)
        grid.Add(textLevel, pos=(0, 3), flag=wx.ALL, border=5)
        grid.Add(self.satLevel, pos=(1, 3), span=(3, 2), flag=wx.ALL, border=5)
        grid.Add(textRaw, pos=(4, 0), flag=wx.ALL, border=5)
        grid.Add(self.textRaw, pos=(5, 0), span=(5, 5),
                 flag=wx.ALL | wx.EXPAND, border=5)
        grid.Add(self.buttonStart, pos=(10, 2), flag=wx.ALL, border=5)
        grid.Add(self.buttonStop, pos=(10, 3), flag=wx.ALL | wx.ALIGN_RIGHT,
                 border=5)
        grid.Add(buttonOk, pos=(11, 4), flag=wx.ALL | wx.ALIGN_RIGHT,
                 border=5)

        self.SetSizerAndFit(grid)

        self.queue = Queue.Queue()
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.__on_timer, self.timer)
        self.timer.Start(self.POLL)
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent=parent, title='GPS Satellite Levels')
        self.parent = parent

        self.satLevel = SatLevel(self)

        self.textSats = wx.StaticText(self)
        self.__set_text(0, 0)

        self.Bind(wx.EVT_CLOSE, self.__on_close)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.satLevel, 1, flag=wx.ALL | wx.EXPAND, border=5)
        sizer.Add(self.textSats, 0, flag=wx.ALL | wx.EXPAND, border=5)

        self.SetSizerAndFit(sizer)
class DialogGPSTest(wx.Dialog):
    POLL = 500

    def __init__(self, parent, device):
        self.device = device
        self.threadLocation = None
        self.raw = ''

        wx.Dialog.__init__(self, parent=parent, title='GPS Test')

        textLat = wx.StaticText(self, label='Longitude')
        self.textLat = wx.TextCtrl(self, style=wx.TE_READONLY)
        textLon = wx.StaticText(self, label='Latitude')
        self.textLon = wx.TextCtrl(self, style=wx.TE_READONLY)
        textAlt = wx.StaticText(self, label='Altitude')
        self.textAlt = wx.TextCtrl(self, style=wx.TE_READONLY)
        textSats = wx.StaticText(self, label='Satellites')
        self.textSats = wx.TextCtrl(self, style=wx.TE_READONLY)
        textRaw = wx.StaticText(self, label='Raw output')
        self.textRaw = wx.TextCtrl(self,
                                   style=wx.TE_MULTILINE | wx.TE_READONLY)

        textLevel = wx.StaticText(self, label='Level')
        self.satLevel = SatLevel(self)

        self.buttonStart = wx.Button(self, label='Start')
        self.Bind(wx.EVT_BUTTON, self.__on_start, self.buttonStart)
        self.buttonStop = wx.Button(self, label='Stop')
        self.Bind(wx.EVT_BUTTON, self.__on_stop, self.buttonStop)
        self.buttonStop.Disable()

        buttonOk = wx.Button(self, wx.ID_OK)
        self.Bind(wx.EVT_BUTTON, self.__on_ok, buttonOk)

        grid = wx.GridBagSizer(10, 10)

        grid.Add(textLat, pos=(0, 0), flag=wx.ALL, border=5)
        grid.Add(self.textLat, pos=(0, 1), span=(1, 2), flag=wx.ALL, border=5)
        grid.Add(textLon, pos=(1, 0), flag=wx.ALL, border=5)
        grid.Add(self.textLon, pos=(1, 1), span=(1, 2), flag=wx.ALL, border=5)
        grid.Add(textAlt, pos=(2, 0), flag=wx.ALL, border=5)
        grid.Add(self.textAlt, pos=(2, 1), span=(1, 2), flag=wx.ALL, border=5)
        grid.Add(textSats, pos=(3, 0), flag=wx.ALL, border=5)
        grid.Add(self.textSats, pos=(3, 1), span=(1, 2), flag=wx.ALL, border=5)
        grid.Add(textLevel, pos=(0, 3), flag=wx.ALL, border=5)
        grid.Add(self.satLevel, pos=(1, 3), span=(3, 2), flag=wx.ALL, border=5)
        grid.Add(textRaw, pos=(4, 0), flag=wx.ALL, border=5)
        grid.Add(self.textRaw, pos=(5, 0), span=(5, 5),
                 flag=wx.ALL | wx.EXPAND, border=5)
        grid.Add(self.buttonStart, pos=(10, 2), flag=wx.ALL, border=5)
        grid.Add(self.buttonStop, pos=(10, 3), flag=wx.ALL | wx.ALIGN_RIGHT,
                 border=5)
        grid.Add(buttonOk, pos=(11, 4), flag=wx.ALL | wx.ALIGN_RIGHT,
                 border=5)

        self.SetSizerAndFit(grid)

        self.queue = Queue.Queue()
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.__on_timer, self.timer)
        self.timer.Start(self.POLL)

    def __on_start(self, _event):
        if not self.threadLocation:
            self.buttonStart.Disable()
            self.buttonStop.Enable()
            self.textRaw.SetValue('')
            self.__add_raw('Starting...')
            self.threadLocation = ThreadLocation(self.queue, self.device,
                                                 raw=True)

    def __on_stop(self, _event):
        if self.threadLocation and self.threadLocation.isAlive():
            self.__add_raw('Stopping...')
            self.threadLocation.stop()
            self.threadLocation.join()
        self.threadLocation = None
        self.satLevel.clear_sats()
        self.textLat.SetValue('')
        self.textLon.SetValue('')
        self.textAlt.SetValue('')
        self.textSats.SetValue('')
        self.buttonStart.Enable()
        self.buttonStop.Disable()

    def __on_ok(self, _event):
        self.__on_stop(None)
        self.EndModal(wx.ID_OK)

    def __on_timer(self, _event):
        self.timer.Stop()
        while not self.queue.empty():
            event = self.queue.get()
            status = event.data.get_status()
            loc = event.data.get_arg2()

            if status == Event.LOC:
                if loc[0] is not None:
                    text = '{:.5f}'.format(loc[0])
                else:
                    text = ''
                self.textLon.SetValue(text)
                if loc[1] is not None:
                    text = '{:.5f}'.format(loc[1])
                else:
                    text = ''
                self.textLat.SetValue(text)
                if loc[2] is not None:
                    text = '{:.1f}'.format(loc[2])
                else:
                    text = ''
                self.textAlt.SetValue(text)
            elif status == Event.LOC_SAT:
                self.satLevel.set_sats(loc)
                used = sum(1 for sat in loc.values() if sat[1])
                self.textSats.SetLabel('{}/{}'.format(used, len(loc)))
            elif status == Event.LOC_ERR:
                self.__on_stop(None)
                self.__add_raw('{}'.format(loc))
            elif status == Event.LOC_RAW:
                self.__add_raw(loc)
        self.timer.Start(self.POLL)

    def __add_raw(self, text):
        text = text.replace('\n', '')
        text = text.replace('\r', '')
        terminal = self.textRaw.GetValue().split('\n')
        terminal.append(text)
        while len(terminal) > 100:
            terminal.pop(0)
        self.textRaw.SetValue('\n'.join(terminal))
        self.textRaw.ScrollPages(self.textRaw.GetNumberOfLines())