Imports System.Globalization
Imports GPSConnector.Common

Public Class GH3000
    Inherits TeltonikaDevice
    Public Overrides ReadOnly Property CodeId As Integer
        Get
            Return 7
        End Get
    End Property

    Public Overrides Function ParseData(teltonikaDeviceData As TeltonikaDeviceData) As GPSProcessorResult
        Dim result As New GPSProcessorResult
        Dim HexData(teltonikaDeviceData.Data.Length - 4) As String
        Dim j As Integer = 0
        Dim i As Integer
        Dim recCount As Integer = 0
        Dim gpsData As GPSDeviceData
        Dim prioritystrTimestamp As String
        Dim lgTimeStamp As Long
        Dim priority As Integer
        Dim strTimestamp As String
        Dim binstrTimestamp As String
        Dim nextii As Integer
        Dim longititude, latitude, altitude, course, satellites As String
        Dim speed, locationAreaCode, cellId, signalQuality, operatorCode As String
        Dim ioElements As Dictionary(Of Integer, String)
        Dim hasLatitudeLongitude As Boolean
        Dim hasAltitude As Boolean
        Dim hasAngle As Boolean
        Dim hasSpeed As Boolean
        Dim hasSatellites As Boolean
        Dim hasLocationAreaCellID As Boolean
        Dim hasSignalQuality As Boolean
        Dim hasOperatorCode As Boolean
        Dim globalMask As String
        Dim hasGPSElement As Boolean
        Dim hasIOElement1B As Boolean
        Dim hasIOElement2B As Boolean
        Dim hasIOElement4B As Boolean
        Dim gpsMask As String


        For i = 2 To teltonikaDeviceData.Data.Length - 2
            If Hex(teltonikaDeviceData.Data(i)).Length = 1 Then
                HexData(j) = "0" & Hex(teltonikaDeviceData.Data(i))
            Else
                HexData(j) = Hex(teltonikaDeviceData.Data(i))
            End If
            j = j + 1
        Next i


        i = 0

        Do
            recCount = recCount + 1
            gpsData = New GPSDeviceData()
            prioritystrTimestamp = String.Empty
            longititude = String.Empty
            latitude = String.Empty
            altitude = String.Empty
            course = String.Empty
            ioElements = New Dictionary(Of Integer, String)()
            hasLatitudeLongitude = False
            hasAltitude = False
            hasAngle = False
            hasSpeed = False
            hasSatellites = False
            hasLocationAreaCellID = False
            hasSignalQuality = False
            hasOperatorCode = False
            globalMask = String.Empty
            hasGPSElement = False
            hasIOElement1B = False
            hasIOElement2B = False
            hasIOElement4B = False
            gpsMask = String.Empty



            For k As Integer = 0 To 3 'FIRST 4bytes
                prioritystrTimestamp = prioritystrTimestamp & HexData(i + k)
            Next

            binstrTimestamp = Convert.ToString(Convert.ToInt32(prioritystrTimestamp, 16), 2).PadLeft(32, "0")

            strTimestamp = binstrTimestamp.Substring(2)
            priority = Convert.ToInt32(binstrTimestamp.Substring(0, 2), 2)

            lgTimeStamp = Convert.ToInt64(strTimestamp, 2)
            Dim dt As DateTime = ConvertFromUnixTimestamp(lgTimeStamp, New DateTime(2007, 1, 1))

            gpsData.Imei = teltonikaDeviceData.IMEI
            gpsData.GPSTime = dt.ToString("ddMMyyHHmmss")
            gpsData.LoggingTime = gpsData.GPSTime

            globalMask = Convert.ToString(Convert.ToInt32(HexData(i + 4), 16), 2).PadLeft(8, "0")
            hasGPSElement = globalMask(7) = "1"
            hasIOElement1B = globalMask(6) = "1"
            hasIOElement2B = globalMask(5) = "1"
            hasIOElement4B = globalMask(4) = "1"



            nextii = 5

            If hasGPSElement Then

                gpsMask = Convert.ToString(Convert.ToInt32(HexData(i + 5), 16), 2).PadLeft(8, "0")
                hasLatitudeLongitude = gpsMask(7) = "1"
                hasAltitude = gpsMask(6) = "1"
                hasAngle = gpsMask(5) = "1"
                hasSpeed = gpsMask(4) = "1"
                hasSatellites = gpsMask(3) = "1"
                hasLocationAreaCellID = gpsMask(2) = "1"
                hasSignalQuality = gpsMask(1) = "1"
                hasOperatorCode = gpsMask(0) = "1"

                nextii = 6

                If hasLatitudeLongitude Then
                    latitude = HexData(i + 6) & HexData(i + 7) & HexData(i + 8) & HexData(i + 9)
                    longititude = HexData(i + 10) & HexData(i + 11) & HexData(i + 12) & HexData(i + 13)
                    nextii = 14
                End If

                If hasAltitude Then
                    altitude = HexData(i + nextii) & HexData(i + nextii + 1)
                    nextii += 2
                End If

                If hasAngle Then
                    course = HexData(i + nextii)
                    nextii += 1
                End If

                If hasSpeed Then
                    speed = HexData(i + nextii)
                    nextii += 1
                End If

                If hasSatellites Then
                    satellites = HexData(i + nextii)
                    nextii += 1
                End If

                If hasLocationAreaCellID Then
                    locationAreaCode = HexData(i + nextii) & HexData(i + nextii + 1)
                    cellId = HexData(i + nextii + 2) + HexData(i + nextii + 3)
                    nextii += 4
                End If

                If hasSignalQuality Then
                    signalQuality = HexData(nextii + i)
                    nextii += 1
                End If
                If hasOperatorCode Then
                    operatorCode = HexData(nextii + i) & HexData(nextii + i + 1) & HexData(nextii + i + 2) & HexData(nextii + i + 3)
                    nextii += 4
                End If
            End If

            If hasIOElement1B Then
                Dim IOElement1BQuantity As Integer = Convert.ToInt32(HexData(i + nextii), 16)
                nextii += 1
                For ib As Integer = 0 To IOElement1BQuantity - 1
                    ioElements.Add(Convert.ToInt32(HexData(nextii + i), 16), Convert.ToInt32(HexData(nextii + 1 + i), 16))
                    nextii += 2
                Next
            End If

            If hasIOElement2B Then
                Dim IOElement2BQuantity As Integer = Convert.ToInt32(HexData(nextii + i), 16)
                nextii += 1
                For ib As Integer = 0 To IOElement2BQuantity - 1
                    ioElements.Add(Convert.ToInt32(HexData(nextii + i), 16), Convert.ToInt32(HexData(nextii + i + 1) & HexData(nextii + i + 2), 16))
                    nextii += 3
                Next
            End If


            If hasIOElement4B Then
                Dim IOElement4BQuantity As Integer = Convert.ToInt32(HexData(nextii + i), 16)
                nextii += 1
                For ib As Integer = 0 To IOElement4BQuantity - 1
                    ioElements.Add(Convert.ToInt32(HexData(nextii + i), 16), Convert.ToInt32(HexData(nextii + 1 + i) & HexData(nextii + 2 + i) & HexData(nextii + 3 + i) & HexData(nextii + 4 + i), 16))
                    nextii += 5
                Next
            End If

            If hasGPSElement Then

                If hasLatitudeLongitude Then
                    gpsData.Longtitude = ConvertHexToInteger(longititude).ToString().Replace(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator, String.Empty).Replace(CultureInfo.InvariantCulture.NumberFormat.NumberGroupSeparator, String.Empty)
                    gpsData.Latitude = ConvertHexToInteger(latitude).ToString().Replace(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator, String.Empty).Replace(CultureInfo.InvariantCulture.NumberFormat.NumberGroupSeparator, String.Empty)
                End If

                If hasAltitude Then gpsData.Height = Convert.ToInt32(altitude, 16)
                If hasAngle Then gpsData.Course = Math.Floor(Convert.ToInt32(course, 16) * 360 / 250)
                If hasSatellites Then gpsData.SatellitesViewed = Convert.ToInt32(satellites, 16)
                If hasSpeed Then gpsData.Speed = Convert.ToInt32(speed, 16)

                If ioElements.ContainsKey(20) Then
                    gpsData.HDOP = Convert.ToInt32(ioElements(20), 16) / 10
                Else
                    gpsData.HDOP = -1
                End If
                If ioElements.ContainsKey(21) Then
                    gpsData.VDOP = Convert.ToInt32(ioElements(21), 16) / 10
                Else
                    gpsData.VDOP = -1
                End If

                If ioElements.ContainsKey(1) Then
                    gpsData.AnlgIN = Convert.ToInt32(ioElements(1), 16)
                Else
                    gpsData.AnlgIN = 0
                End If

                If ((gpsData.SatellitesViewed >= 4) And (gpsData.Speed < 240)) Then
                    gpsData.FixType = 3
                Else
                    gpsData.FixType = 0
                End If

                gpsData.Mileage = -1
                gpsData.MCC = -1
                gpsData.DigIN = 0
                gpsData.DigOUT = 0
                gpsData.AnlgOUT = 0
                gpsData.PomAnlgIN = -1
                gpsData.PomAnlgIN = -1
                gpsData.MotionSensor = -1
                gpsData.GPSAccuracy = -1
                gpsData.MessageCode = 20          ' Na tvrdo, Track point=20,98 / Periodic point=20,99 / Alarm point=30,66
                gpsData.LoggingCause = 98

                result.GPSDeviceDataList.Add(gpsData)
            End If
            i = i + nextii
        Loop Until recCount = teltonikaDeviceData.NumberOfRecord

        result.Success = True
        result.BackMessages.Add(New Byte() {0, 0, 0, teltonikaDeviceData.NumberOfRecord})
        Return result
    End Function
    End Class

