

Public Class mainFrm
    Dim WithEvents serial As New System.IO.Ports.SerialPort
    Dim dataGps As String
    Dim NMEA_part() As String
    Dim NMEA_line() As String
    Dim hours_new As String
    Dim minutes_new As String
    Dim seconds_new As String
    Dim days_new As String
    Dim months_new As String
    Dim years_new As String
    Dim timeGps As String
    Dim dateGps As String
    Dim GpsSatNumber As String
    Dim GpsConState As Boolean
    Dim index As Integer
    Dim syncTimeRequest As String = False
    Dim last_hour As Byte
    Dim count_hours As Byte





    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        If My.Settings.minimize_at_startup Then
            btnMinimize.PerformClick()
        End If
        tmrDataUpdate.Interval = My.Settings.read_gps_time * 1000
        tmrSyncTimeout.Interval = My.Settings.timeout_gps * 60000
        last_hour = DateTime.Now.Hour
        lblGpsPortView.Text = My.Settings.com_port
        view_system_date_time()
        tmrSystemTimeUpdate.Start()
        reset_all_view()
        view_last_result("Program start")
        If (My.Settings.active_com_only_sync = False) Or My.Settings.sync_at_startup Then
            open_gps_com()
        End If
        If My.Settings.sync_at_startup Then
            sync_date_time_cmd()
        End If
    End Sub

    Public Sub view_last_result(ByRef text As String)
        Try
            text = DateTime.Now & " " & text
            txtLastResult.Text = text
            ntfIcnGPSTsync.Text = "GPS TSync - " & text
        Catch ' se il messaggio di notifica è troppo lungo (errore) non lo scrive
            'vale solo per eventuali modifiche, attualmente tutti i messaggi hanno meno di 64 caratteri
        End Try
    End Sub





    Private Sub Form1_Close(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
        close_gps_com()
    End Sub

    Private Sub tmrDataUpdate_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrDataUpdate.Tick
        tmrDataUpdate.Stop()
        Try
            dataGps = serial.ReadExisting()
            If (dataGps <> "") Then
                NMEA_line = dataGps.Split("$") 'Divide tutti i singoli pacchetti NMEA ricevuti nell'intervallo
                For Me.index = 1 To NMEA_line.Length - 2 'Scorre tutti i pacchetti ricevuti tranne il primo (#0) e l'ultimo (#n-1) in quanto
                    'potrebbero essere non completi
                    If NMEA_line(index).Contains("GPGGA") Then
                        NMEA_part = NMEA_line(index).Split(",") 'separo le singole componenti del pacchetto nmea
                        If (NMEA_part.Length = 15) Then 'se la lunghezza del pacchetto nmea è giusta esegue la decodifica
                            If (Val(NMEA_part(6)) > 0) Then
                                GpsConState = True
                            Else
                                GpsConState = False
                            End If
                            timeGps = NMEA_part(1)
                            GpsSatNumber = NMEA_part(7)
                        End If
                    ElseIf NMEA_line(index).Contains("GPRMC") Then
                        NMEA_part = NMEA_line(index).Split(",") 'separo le singole componenti del pacchetto nmea
                        If (NMEA_part.Length = 13) Then 'se la lunghezza del pacchetto nmea è giusta esegue la decodifica
                            timeGps = NMEA_part(1)
                            dateGps = NMEA_part(9)
                        End If
                    End If
                Next
            End If
            If serial.IsOpen Then
                serial.DiscardInBuffer()
            End If

            dataGps = String.Empty
            hours_new = Mid(timeGps, 1, 2) 'inizia dal carattere 1 a prendere 2 caratteri dalla part edl protocollo nema
            minutes_new = Mid(timeGps, 3, 2)
            seconds_new = Mid(timeGps, 5, 2)
            days_new = Mid(dateGps, 1, 2)
            months_new = Mid(dateGps, 3, 2)
            years_new = Mid(dateGps, 5, 2)
            Dim newDateTimeLocal As Date = UTC_To_Local_time(days_new, months_new, years_new, hours_new, minutes_new, seconds_new)
            view_date_time(newDateTimeLocal)
            NumSatView.Text = GpsSatNumber

            If GpsConState Then
                ConGpsStateView.Text = "FIX OK"
                If syncTimeRequest And (DateTime.Now.Minute > 0) And (DateTime.Now.Minute < 59) Then
                    change_system_datetime(newDateTimeLocal)
                    gps_state_reset()
                    view_last_result("Time sync OK!")
                End If
            Else
                ConGpsStateView.Text = "WAITING FIX"

            End If
        Catch
            gps_state_reset()
            view_last_result("Error change time!")
        Finally
            If serial.IsOpen Then
                tmrDataUpdate.Start()
            End If

        End Try
    End Sub

    Private Function UTC_To_Local_time(ByRef day_set As String, ByRef month_set As String, ByRef year_set As String, ByRef hours_set As String, ByRef minutes_set As String, ByRef seconds_set As String)
        'Preleva i singoli componenti, li combina in data e ora e li converte in locale. Successivamente rilascia un tipo date
        Dim dateToSet As Date
        dateToSet = DateTime.SpecifyKind(CDate(day_set & "/" & month_set & "/" & year_set & " " & hours_set & ":" & minutes_set & ":" & seconds_set), DateTimeKind.Utc)
        dateToSet = DateTime.SpecifyKind(dateToSet.ToLocalTime, DateTimeKind.Local)
        Return dateToSet
    End Function

    Private Sub change_system_datetime(ByRef new_datetime As Date)
        'Imposto data
        Today = new_datetime
        'Imposto orario
        'includo parte correzione orario
        If My.Settings.timeCorrectionPos Then
            TimeOfDay = new_datetime.AddMilliseconds(My.Settings.timeCorrection)
        Else
            TimeOfDay = new_datetime.AddMilliseconds(My.Settings.timeCorrection * (-1))
        End If

    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles btnSyncNow.Click
        sync_date_time_cmd()
    End Sub

    Private Sub sync_date_time_cmd()
        If (serial.IsOpen = False) Then
            open_gps_com()
        End If
        syncTimeRequest = True
        tmrSyncTimeout.Stop()
        tmrSyncTimeout.Start()
    End Sub

    Private Sub open_gps_com()
        Try
            If serial.IsOpen Then
                serial.Close()
            End If

            With serial
                .PortName = My.Settings.com_port
                .BaudRate = My.Settings.baud_rate
                .Parity = IO.Ports.Parity.None
                .DataBits = 8
                .StopBits = IO.Ports.StopBits.One
                .ReadBufferSize = 10000
            End With

            serial.Open()
            tmrDataUpdate.Start()

        Catch
            ConGpsStateView.Text = "COM ERROR"
        End Try

    End Sub

    Private Sub close_gps_com()
        Try
            reset_all_view()
            If serial.IsOpen Then
                tmrDataUpdate.Stop()
                serial.DiscardInBuffer()
                serial.Close()
            End If

        Catch
        End Try

    End Sub

    Private Sub view_date_time(ByVal dateTimeView As Date)
        Dim hours_view, minutes_view, day_view, months_view As String
        hours_view = ""
        If (dateTimeView.Hour < 10) Then
            hours_view = "0"
        End If
        hours_view = hours_view & dateTimeView.Hour
        minutes_view = ""
        If (dateTimeView.Minute < 10) Then
            minutes_view = "0"
        End If
        minutes_view = minutes_view & dateTimeView.Minute
        day_view = ""
        If (dateTimeView.Day < 10) Then
            day_view = "0"
        End If
        day_view = day_view & dateTimeView.Day
        months_view = ""
        If (dateTimeView.Month < 10) Then
            months_view = "0"
        End If
        months_view = months_view & dateTimeView.Month
        lblTimeGPSView.Text = hours_view & ":" & minutes_view
        lblDateGPSView.Text = day_view & "/" & months_view & "/" & dateTimeView.Year
    End Sub

    Private Sub reset_all_view()
        lblDateGPSView.Text = "--/--/----"
        lblTimeGPSView.Text = "--:--"
        ConGpsStateView.Text = "IDLE"
        NumSatView.Text = "--"
    End Sub

    Private Sub btnSettings_Click(sender As System.Object, e As System.EventArgs) Handles btnSettings.Click
        frmSettings.Show()
    End Sub

    Private Sub view_system_date_time()
        Dim hours_view, minutes_view, day_view, months_view As String
        hours_view = ""
        If (DateTime.Now.Hour < 10) Then
            hours_view = "0"
        End If
        hours_view = hours_view & DateTime.Now.Hour
        minutes_view = ""
        If (DateTime.Now.Minute < 10) Then
            minutes_view = "0"
        End If
        minutes_view = minutes_view & DateTime.Now.Minute
        day_view = ""
        If (DateTime.Now.Day < 10) Then
            day_view = "0"
        End If
        day_view = day_view & DateTime.Now.Day
        months_view = ""
        If (DateTime.Now.Month < 10) Then
            months_view = "0"
        End If
        months_view = months_view & DateTime.Now.Month
        lblTimeSystemView.Text = hours_view & ":" & minutes_view
        lblDateSystemView.Text = day_view & "/" & months_view & "/" & DateTime.Now.Year
    End Sub

    Private Sub tmrSystemTimeUpdate_Tick(sender As System.Object, e As System.EventArgs) Handles tmrSystemTimeUpdate.Tick
        tmrSystemTimeUpdate.Stop()
        'Esegue solo se è passata l'ora!!!!
        If (DateTime.Now.Hour <> last_hour) Then
            last_hour = DateTime.Now.Hour
            'Modalità aggiornamento ora ogni n ore
            If (My.Settings.mode_auto_sync = 1) Then
                count_hours = count_hours + 1
                If (count_hours >= My.Settings.every_hour_set) Then
                    count_hours = 0
                    sync_date_time_cmd()
                End If
            ElseIf (My.Settings.mode_auto_sync = 2) Then
                If (DateTime.Now.Hour = My.Settings.spec_time_h_set) Then
                    sync_date_time_cmd()
                End If
            End If

        End If

        view_system_date_time()
        tmrSystemTimeUpdate.Start()
    End Sub

    Public Sub gps_state_reset()
        tmrSyncTimeout.Stop()
        If My.Settings.active_com_only_sync Then
            close_gps_com()
        End If
        syncTimeRequest = False
    End Sub

    Private Sub tmrSyncTimeout_Tick(sender As System.Object, e As System.EventArgs) Handles tmrSyncTimeout.Tick
        gps_state_reset()
        view_last_result("Error! Timeout GPS.")
    End Sub

    Private Sub ntfIcnGPSTsync_MouseClick(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles ntfIcnGPSTsync.MouseClick
        Me.ShowInTaskbar = True
        Me.Visible = True
        ntfIcnGPSTsync.Visible = False
    End Sub

    Private Sub btnMinimize_Click(sender As System.Object, e As System.EventArgs) Handles btnMinimize.Click
        'Minimizza la finestra
        Me.ShowInTaskbar = False
        Me.Visible = False
        ntfIcnGPSTsync.Visible = True
    End Sub

    Private Sub lblLinkAbout_LinkClicked(sender As System.Object, e As System.Windows.Forms.LinkLabelLinkClickedEventArgs) Handles lblLinkAbout.LinkClicked
        AboutBox1.Show()
    End Sub
End Class
