Imports System.Runtime.InteropServices

Imports Stax

Public Class MediaInfo
    Implements IDisposable

    Private Handle As IntPtr

    <DllImport("MediaInfo.dll")> _
    Public Shared Function MediaInfo_New() As IntPtr
    End Function

    <DllImport("MediaInfo.dll")> _
    Public Shared Sub MediaInfo_Delete(ByVal Handle As IntPtr)
    End Sub

    <DllImport("MediaInfo.dll", CharSet:=CharSet.Unicode)> _
    Public Shared Function MediaInfo_Open(ByVal Handle As IntPtr, ByVal FileName As String) As Integer
    End Function

    <DllImport("MediaInfo.dll")> _
    Public Shared Function MediaInfo_Close(ByVal Handle As IntPtr) As Integer
    End Function

    <DllImport("MediaInfo.dll", CharSet:=CharSet.Unicode)> _
    Public Shared Function MediaInfo_Inform(ByVal Handle As IntPtr, <MarshalAs(UnmanagedType.U4)> ByVal Reserved As UInteger) As String
    End Function

    <DllImport("MediaInfo.dll", CharSet:=CharSet.Unicode)> _
    Public Shared Function MediaInfo_GetI(ByVal Handle As IntPtr, <MarshalAs(UnmanagedType.U4)> ByVal StreamKind As MediaInfoStreamKind, ByVal StreamNumber As UInteger, ByVal Parameter As UInteger, <MarshalAs(UnmanagedType.U4)> ByVal KindOfInfo As MediaInfoInfoKind) As String
    End Function

    <DllImport("MediaInfo.dll", CharSet:=CharSet.Unicode)> _
    Public Shared Function MediaInfo_Get(ByVal Handle As IntPtr, <MarshalAs(UnmanagedType.U4)> ByVal StreamKind As MediaInfoStreamKind, ByVal StreamNumber As UInteger, ByVal Parameter As String, <MarshalAs(UnmanagedType.U4)> ByVal KindOfInfo As MediaInfoInfoKind, <MarshalAs(UnmanagedType.U4)> ByVal KindOfSearch As MediaInfoInfoKind) As String
    End Function

    <DllImport("MediaInfo.dll", CharSet:=CharSet.Unicode)> _
    Public Shared Function MediaInfo_Option(ByVal Handle As IntPtr, ByVal OptionString As String, ByVal Value As String) As String
    End Function

    <DllImport("MediaInfo.dll")> _
    Public Shared Function MediaInfo_State_Get(ByVal Handle As IntPtr) As Integer
    End Function

    <DllImport("MediaInfo.dll")> _
    Public Shared Function MediaInfo_Count_Get(ByVal Handle As IntPtr, <MarshalAs(UnmanagedType.U4)> ByVal StreamKind As MediaInfoStreamKind, ByVal StreamNumber As Integer) As Integer
    End Function

    Public Sub New(ByVal path As String)
        Handle = MediaInfo_New()
        MediaInfo_Open(Handle, path)
    End Sub

    Private disposedValue As Boolean

    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not disposedValue Then
            If disposing Then
                MediaInfo_Close(Handle)
                MediaInfo_Delete(Handle)
            End If
        End If

        disposedValue = True
    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

    Public AudioTracksValue As List(Of MediaInfoAudioTrack)

    Public ReadOnly Property AudioTracks() As List(Of MediaInfoAudioTrack)
        Get
            If AudioTracksValue Is Nothing Then
                AudioTracksValue = New List(Of MediaInfoAudioTrack)
                Dim count As Integer = MediaInfo_Count_Get(Handle, MediaInfoStreamKind.Audio, -1)

                If count > 0 Then
                    For i As Integer = 0 To count - 1
                        Dim at As New MediaInfoAudioTrack
                        Dim codec As String = MediaInfo_Get(Handle, MediaInfoStreamKind.Audio, Convert.ToUInt32(i), "Codec/String", MediaInfoInfoKind.Text, MediaInfoInfoKind.Name)

                        Select Case codec
                            Case "MPEG1/2 L3"
                                at.AudioType = MediaInfoAudioType.MP3
                            Case "AC3"
                                at.AudioType = MediaInfoAudioType.AC3
                            Case "PCM"
                                at.AudioType = MediaInfoAudioType.WAV
                            Case Else
                                at.AudioType = MediaInfoAudioType.NotImplemented
                        End Select

                        at.LanguageTwoLetter = MediaInfo_Get(Handle, MediaInfoStreamKind.Audio, Convert.ToUInt32(i), "Language", MediaInfoInfoKind.Text, MediaInfoInfoKind.Name)
                        at.Info = MediaInfo_Get(Handle, MediaInfoStreamKind.Audio, Convert.ToUInt32(i), "Language/Info", MediaInfoInfoKind.Text, MediaInfoInfoKind.Name)

                        AudioTracksValue.Add(at)
                    Next
                End If
            End If

            Return AudioTracksValue
        End Get
    End Property

    Public SubtitlesValue As List(Of MediaInfoSubtitle)

    Public ReadOnly Property Subtitles() As List(Of MediaInfoSubtitle)
        Get
            If SubtitlesValue Is Nothing Then
                SubtitlesValue = New List(Of MediaInfoSubtitle)
                Dim count As Integer = MediaInfo_Count_Get(Handle, MediaInfoStreamKind.Text, -1)

                If count > 0 Then
                    For i As Integer = 0 To count - 1
                        Dim s As New MediaInfoSubtitle
                        s.LanguageTwoLetter = MediaInfo_Get(Handle, MediaInfoStreamKind.Text, Convert.ToUInt32(i), "Language", MediaInfoInfoKind.Text, MediaInfoInfoKind.Name)
                        SubtitlesValue.Add(s)
                    Next
                End If
            End If

            Return SubtitlesValue
        End Get
    End Property
End Class

Public Class MediaInfoAudioTrack
    Private AudioTypeValue As MediaInfoAudioType

    Public Property AudioType() As MediaInfoAudioType
        Get
            Return AudioTypeValue
        End Get
        Set(ByVal Value As MediaInfoAudioType)
            AudioTypeValue = Value
        End Set
    End Property

    Private LanguageTwoLetterValue As String

    Public Property LanguageTwoLetter() As String
        Get
            Return LanguageTwoLetterValue
        End Get
        Set(ByVal Value As String)
            LanguageTwoLetterValue = Value
        End Set
    End Property

    Private InfoValue As String

    Public Property Info() As String
        Get
            If InfoValue Is Nothing Then
                InfoValue = ""
            End If

            Return InfoValue
        End Get
        Set(ByVal Value As String)
            InfoValue = Value
        End Set
    End Property

    Public ReadOnly Property Extension() As String
        Get
            Return "." + AudioType.ToString.ToLower
        End Get
    End Property
End Class

Public Class MediaInfoSubtitle
    Private LanguageTwoLetterValue As String

    Public Property LanguageTwoLetter() As String
        Get
            Return LanguageTwoLetterValue
        End Get
        Set(ByVal Value As String)
            LanguageTwoLetterValue = Value
        End Set
    End Property
End Class

Public Enum MediaInfoStreamKind
    General
    Video
    Audio
    Text
    Chapters
    Image
End Enum

Public Enum MediaInfoInfoKind
    Name
    Text
    Measure
    Options
    NameText
    MeasureText
    Info
    HowTo
End Enum

Public Enum MediaInfoAudioType
    NotImplemented
    MP3
    AC3
    WAV
End Enum