Imports System
Imports System.Globalization
Imports System.Text
#If VBC_VER >= 11 Then
Imports Tellert.Til
#Else
Imports view_tms.Tellert.Til
#End If

Module view_tms

    Function Main(ByVal args As String()) As Integer

        ' Ignore current culture settings for compatibility with the "C" version of VIEW_TMS.EXE
        System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US")

        If args.Length < 1 Then
            Console.WriteLine("VIEW_TMS V1.3.3 - Copyright (c) 2014-2018 Rudy Tellert Elektronik")
            Console.WriteLine("SYNTAX: VIEW_TMS filename.tms")
            Return 87
        End If

        Using til As New Til()
            If til.Load(args(0)) Then
                Dim g As UInteger = 0
                For Each group As Til.Group In til.Groups
                    Console.WriteLine(Console.Out.NewLine & "Group " & (g + 1) & "/" & til.Groups.Length & ":")
                    Console.WriteLine("  SampleCount = " & group.SampleCount)
                    Console.WriteLine("  SampleRate = " & group.SampleRate & " s")
                    If group.Time.DeviceSetup.IsAvailable Then
                        Console.WriteLine("  HWSetup = " & group.Time.DeviceSetup.ToString())
                    End If
                    If group.Time.Start.IsAvailable Then
                        Console.WriteLine("  Start = " & group.Time.Start.ToString())
                    End If
                    If group.Time.DeviceReadOut.IsAvailable Then
                        Console.WriteLine("  HWReadOut = " & group.Time.DeviceReadOut.ToString())
                    End If
                    If group.Time.Sections.Length <> 0 Then
                        For n As UInteger = 0 To group.Time.Sections.Length - 1
                            Dim lastSampleIndex As ULong = If(n + 1 <> group.Time.Sections.Length, group.Time.Sections(n + 1).SampleOffset, group.SampleCount)
                            If lastSampleIndex <> 0 Then
                                lastSampleIndex -= 1
                            End If
                            Console.Write("  Sample range of section" & (n + 1) & " = [" & group.Time.Sections(n).SampleOffset & ";" & lastSampleIndex & "]")
                            Console.WriteLine(If(group.Time.Sections(n).Start.IsAvailable, " at " & group.Time.Sections(n).Start.ToString(), ""))
                        Next
                    End If
                    Dim values As Double()() = New Double(group.Signals.Length - 1)() {}
#If DEBUG Then
                    Dim valuesFromRaw As Double()() = New Double(group.Signals.Length - 1)() {}
#End If
                    Dim s As UInteger = 0
                    For Each signal As Til.Signal In group.Signals
                        Console.WriteLine(Console.Out.NewLine & "  Signal " & (s + 1) & "/" & group.Signals.Length & If(s = 0, " (= Reference Signal):", ":"))
                        Console.WriteLine("    Name = " & signal.Name)
                        Console.WriteLine("    Unit = " & signal.Unit)
                        Console.WriteLine("    DataType = " & GetDataTypeString(signal.Raw.DataType, group.SampleCount))
                        Console.WriteLine("    Factor = " & signal.Raw.Factor)
                        Console.WriteLine("    Offset = " & signal.Raw.Offset)
                        If signal.Raw.Storage.FileName.Length <> 0 Then
                            Console.WriteLine("    FileName = " & signal.Raw.Storage.FileName)
                            Console.WriteLine("    FileOffset = " & signal.Raw.Storage.Offset)
                            Console.WriteLine("    FileDataSize = " & signal.Raw.Storage.DataSize)
                            Console.WriteLine("    FileGap = " & signal.Raw.Storage.Gap)
                        End If
                        Console.WriteLine("    FlagQuantized = " & If(signal.Attributes.Quantized, 1, 0))
                        Console.WriteLine("    ViewMin = " & signal.ViewDefaults.Min)
                        Console.WriteLine("    ViewMax = " & signal.ViewDefaults.Max)

                        signal.Iterator.CopyTo(values(s))
#If DEBUG Then
                        signal.Raw.ConvertTo(valuesFromRaw(s))
#End If
                        s += 1
                    Next

                    Console.WriteLine(Console.Out.NewLine & "  Sample values:")
                    If group.SampleCount <> 0 Then
                        For k As ULong = 0 To group.SampleCount - 1
                            If group.Signals.Length <> 0 Then
                                For s = 0 To group.Signals.Length - 1
#If DEBUG Then
                                    If values(s)(k) <> valuesFromRaw(s)(k) Then
                                        Throw New Til.Exception("Unexpected sample value mismatch!")
                                    End If
#End If
                                    If s = 0 Then
                                        Console.Write("    ")
                                    End If
                                    Console.Write(values(s)(k))
                                    Console.Write(If(s + 1 = group.Signals.Length, Console.Out.NewLine, vbTab))
                                Next
                            End If
                        Next
                    End If
                    g += 1
                Next
            End If
        End Using

        Return 0

    End Function

    Private Function GetDataTypeString(ByVal dataType As Til.DataType, ByVal sampleCount As UInt64) As String
        Select Case dataType
            Case Til.DataType.SampleNumber
                Return "sample number [0;" & (sampleCount - 1) & "]; size: 0 bytes"
            Case Til.DataType.LeUInt8
                Return "unsigned char (Intel); size: 1 byte"
            Case Til.DataType.LeInt8
                Return "signed char (Intel); size: 1 byte"
            Case Til.DataType.LeUInt16
                Return "unsigned short (Intel); size: 2 bytes"
            Case Til.DataType.LeInt16
                Return "signed short (Intel); size: 2 bytes"
            Case Til.DataType.LeUInt32
                Return "unsigned long (Intel); size: 4 bytes"
            Case Til.DataType.LeInt32
                Return "signed long (Intel); size: 4 bytes"
            Case Til.DataType.LeUInt64
                Return "unsigned __int64 (Intel); size: 8 bytes"
            Case Til.DataType.LeInt64
                Return "signed __int64 (Intel); size: 8 bytes"
            Case Til.DataType.LeFloat32
                Return "float (Intel); size: 4 bytes"
            Case Til.DataType.LeFloat64
                Return "double (Intel); size: 8 bytes"
            Case Til.DataType.RsvdLeFloat80
                Return "long double (Intel); size: 10 bytes"
        End Select

        Return "unknown"
    End Function

End Module
