
'This is a control inheriting from the ListView control.
'It has an additional property LVType that allows me to select the type (texture, shader etc)
'and it automatically sets some properties (columns etc)
Public Class clsListView
    Inherits ListView

    Public Enum LVTypeEnum As Integer
        TextureFolders = 0
        TextureFiles = 1
        ShaderFiles = 2
        ModelFolders = 3
        ModelFiles = 4
        SoundFolders = 5
        SoundFiles = 6
        MiscFolders = 7
        MiscFiles = 8
    End Enum

    Public Sub New()
        Me.HideSelection = False
        Me.View = Windows.Forms.View.Details
        Me.LVType = LVTypeEnum.TextureFolders

        _Items = New LVItemCollection(Me)
        _Iml = New ImageList With {.ColorDepth = ColorDepth.Depth32Bit, .ImageSize = New Size(16, 16)}
        Me.SmallImageList = Me.Iml
    End Sub

    Private _Iml As ImageList
    Public Property Iml() As ImageList
        Get
            Return _Iml
        End Get
        Set(ByVal value As ImageList)
            _Iml = value
        End Set
    End Property

    Private _Items As LVItemCollection
    Public Overloads ReadOnly Property Items() As LVItemCollection
        Get
            Return _Items
        End Get
    End Property

    Public ReadOnly Property SelectedTextureFolder() As clsTextureFolder
        Get
            If Me.LVType = LVTypeEnum.TextureFolders AndAlso Me.SelectedItems.Count > 0 Then
                Return TryCast(Me.SelectedItems(0), clsTextureFolder)
            Else
                Return Nothing
            End If
        End Get
    End Property
    Public ReadOnly Property SelectedTexture() As clsTexture
        Get
            If Me.LVType = LVTypeEnum.TextureFiles AndAlso Me.SelectedItems.Count > 0 Then
                Return TryCast(Me.SelectedItems(0), clsTexture)
            Else
                Return Nothing
            End If
        End Get
    End Property
    Public ReadOnly Property SelectedShader() As clsShader
        Get
            If Me.LVType = LVTypeEnum.ShaderFiles AndAlso Me.SelectedItems.Count > 0 Then
                Return TryCast(Me.SelectedItems(0), clsShader)
            Else
                Return Nothing
            End If
        End Get
    End Property
    Public ReadOnly Property SelectedModelFolder() As clsModelFolder
        Get
            If Me.LVType = LVTypeEnum.ModelFolders AndAlso Me.SelectedItems.Count > 0 Then
                Return TryCast(Me.SelectedItems(0), clsModelFolder)
            Else
                Return Nothing
            End If
        End Get
    End Property
    Public ReadOnly Property SelectedModel() As clsModel
        Get
            If Me.LVType = LVTypeEnum.ModelFiles AndAlso Me.SelectedItems.Count > 0 Then
                Return TryCast(Me.SelectedItems(0), clsModel)
            Else
                Return Nothing
            End If
        End Get
    End Property
    Public ReadOnly Property SelectedSoundFolder() As clsSoundFolder
        Get
            If Me.LVType = LVTypeEnum.SoundFolders AndAlso Me.SelectedItems.Count > 0 Then
                Return TryCast(Me.SelectedItems(0), clsSoundFolder)
            Else
                Return Nothing
            End If
        End Get
    End Property
    Public ReadOnly Property SelectedSound() As clsSound
        Get
            If Me.LVType = LVTypeEnum.SoundFiles AndAlso Me.SelectedItems.Count > 0 Then
                Return TryCast(Me.SelectedItems(0), clsSound)
            Else
                Return Nothing
            End If
        End Get
    End Property
    Public ReadOnly Property SelectedMiscFolder() As clsMiscFolder
        Get
            If Me.LVType = LVTypeEnum.MiscFolders AndAlso Me.SelectedItems.Count > 0 Then
                Return TryCast(Me.SelectedItems(0), clsMiscFolder)
            Else
                Return Nothing
            End If
        End Get
    End Property
    Public ReadOnly Property SelectedMisc() As clsMisc
        Get
            If Me.LVType = LVTypeEnum.MiscFiles AndAlso Me.SelectedItems.Count > 0 Then
                Return TryCast(Me.SelectedItems(0), clsMisc)
            Else
                Return Nothing
            End If
        End Get
    End Property
    Public Property SelectedItem() As ListViewItem
        Get
            If Me.SelectedItems.Count > 0 Then
                Return Me.SelectedItems(0)
            Else
                Return Nothing
            End If
        End Get
        Set(ByVal value As ListViewItem)
            For Each o As ListViewItem In Me.Items
                If o Is value Then
                    o.Selected = True
                Else
                    o.Selected = False
                End If
            Next
        End Set
    End Property


    Private _LVType As LVTypeEnum
    Public Property LVType() As LVTypeEnum
        Get
            Return _LVType
        End Get
        Set(ByVal value As LVTypeEnum)
            _LVType = value

            'Set columns + some properties
            Me.Columns.Clear()
            Select Case value
                Case LVTypeEnum.TextureFolders
                    Me.MultiSelect = False
                    Me.Columns.Add("colTextureDirName", "Directory Name", Me.Width)
                Case LVTypeEnum.TextureFiles
                    Me.MultiSelect = True
                    Me.Columns.Add("colTextureFileName", "File Name", CInt(Me.Width * (3 / 4)) - 2)
                    Me.Columns.Add("colTextureStandard", "Standard", CInt(Me.Width * (1 / 4)) - 2)
                Case LVTypeEnum.ShaderFiles
                    Me.MultiSelect = True
                    Me.Columns.Add("colShaderFileName", "File Name", CInt(Me.Width * (3 / 4)))
                    Me.Columns.Add("colShaderStandard", "Standard", CInt(Me.Width * (1 / 4)))
                Case LVTypeEnum.ModelFolders
                    Me.MultiSelect = False
                    Me.Columns.Add("colModelDirName", "Directory Path", Me.Width)
                Case LVTypeEnum.ModelFiles
                    Me.MultiSelect = True
                    Me.Columns.Add("colModelFileName", "File Name", CInt(Me.Width * (3 / 4)))
                    Me.Columns.Add("colModelStandard", "Standard", CInt(Me.Width * (1 / 4)))
                Case LVTypeEnum.SoundFolders
                    Me.MultiSelect = False
                    Me.Columns.Add("colSoundDirName", "Directory Path", Me.Width)
                Case LVTypeEnum.SoundFiles
                    Me.MultiSelect = True
                    Me.Columns.Add("colSoundFileName", "File Name", CInt(Me.Width * (3 / 4)))
                    Me.Columns.Add("colSoundStandard", "Standard", CInt(Me.Width * (1 / 4)))
                Case LVTypeEnum.MiscFolders
                    Me.MultiSelect = False
                    Me.Columns.Add("colMiscDirName", "Directory Path", Me.Width)
                Case LVTypeEnum.MiscFiles
                    Me.MultiSelect = True
                    Me.Columns.Add("colMiscFileName", "File Name", CInt(Me.Width * (3 / 4)))
                    Me.Columns.Add("colMiscStandard", "Standard", CInt(Me.Width * (1 / 4)))
            End Select
        End Set
    End Property
End Class

Public Class LVItemCollection
    Inherits ListView.ListViewItemCollection

    Private _owner As clsListView = Nothing

    Public Sub New(ByVal owner As clsListView)
        MyBase.New(owner)
        _owner = owner
    End Sub


    Public Overrides Function Add(ByVal value As System.Windows.Forms.ListViewItem) As System.Windows.Forms.ListViewItem
        Select Case _owner.LVType
            Case clsListView.LVTypeEnum.TextureFiles
                Dim file As clsTexture = TryCast(value, clsTexture)
                If file IsNot Nothing Then
                    If Not _owner.Iml.Images.ContainsKey(file.IconPtr.ToString) Then _owner.Iml.Images.Add(file.IconPtr.ToString, file.Icon)
                    file.ImageKey = file.IconPtr.ToString

                    Dim str As String
                    If file.IsStandard Then
                        str = "Yes"
                    Else
                        str = "No"
                    End If

                    file.SubItems.Add(str)
                    MyBase.Add(file)
                End If
            Case clsListView.LVTypeEnum.TextureFolders
                Dim dir As clsTextureFolder = TryCast(value, clsTextureFolder)
                If dir IsNot Nothing Then
                    If Not _owner.Iml.Images.ContainsKey(dir.IconPtr.ToString) Then _owner.Iml.Images.Add(dir.IconPtr.ToString, dir.Icon)
                    dir.ImageKey = dir.IconPtr.ToString
                    MyBase.Add(dir)
                End If
            Case clsListView.LVTypeEnum.ShaderFiles
                Dim file As clsShader = TryCast(value, clsShader)
                If file IsNot Nothing Then
                    If Not _owner.Iml.Images.ContainsKey(file.IconPtr.ToString) Then _owner.Iml.Images.Add(file.IconPtr.ToString, file.Icon)
                    file.ImageKey = file.IconPtr.ToString

                    Dim str As String
                    If file.IsStandard Then
                        str = "Yes"
                    Else
                        str = "No"
                    End If

                    file.SubItems.Add(str)
                    MyBase.Add(file)
                End If
            Case clsListView.LVTypeEnum.ModelFiles
                Dim file As clsModel = TryCast(value, clsModel)
                If file IsNot Nothing Then
                    If Not _owner.Iml.Images.ContainsKey(file.IconPtr.ToString) Then _owner.Iml.Images.Add(file.IconPtr.ToString, file.Icon)
                    file.ImageKey = file.IconPtr.ToString

                    Dim str As String
                    If file.IsStandard Then
                        str = "Yes"
                    Else
                        str = "No"
                    End If

                    file.SubItems.Add(str)
                    MyBase.Add(file)
                End If
            Case clsListView.LVTypeEnum.ModelFolders
                Dim dir As clsModelFolder = TryCast(value, clsModelFolder)
                If dir IsNot Nothing Then
                    If Not _owner.Iml.Images.ContainsKey(dir.IconPtr.ToString) Then _owner.Iml.Images.Add(dir.IconPtr.ToString, dir.Icon)
                    dir.ImageKey = dir.IconPtr.ToString
                    MyBase.Add(dir)
                End If
            Case clsListView.LVTypeEnum.SoundFiles
                Dim file As clsSound = TryCast(value, clsSound)
                If file IsNot Nothing Then
                    If Not _owner.Iml.Images.ContainsKey(file.IconPtr.ToString) Then _owner.Iml.Images.Add(file.IconPtr.ToString, file.Icon)
                    file.ImageKey = file.IconPtr.ToString

                    Dim str As String
                    If file.IsStandard Then
                        str = "Yes"
                    Else
                        str = "No"
                    End If

                    file.SubItems.Add(str)
                    MyBase.Add(file)
                End If
            Case clsListView.LVTypeEnum.SoundFolders
                Dim dir As clsSoundFolder = TryCast(value, clsSoundFolder)
                If dir IsNot Nothing Then
                    If Not _owner.Iml.Images.ContainsKey(dir.IconPtr.ToString) Then _owner.Iml.Images.Add(dir.IconPtr.ToString, dir.Icon)
                    dir.ImageKey = dir.IconPtr.ToString
                    MyBase.Add(dir)
                End If
            Case clsListView.LVTypeEnum.MiscFiles
                Dim file As clsMisc = TryCast(value, clsMisc)
                If file IsNot Nothing Then
                    If Not _owner.Iml.Images.ContainsKey(file.IconPtr.ToString) Then _owner.Iml.Images.Add(file.IconPtr.ToString, file.Icon)
                    file.ImageKey = file.IconPtr.ToString

                    Dim str As String
                    If file.IsStandard Then
                        str = "Yes"
                    Else
                        str = "No"
                    End If

                    file.SubItems.Add(str)
                    MyBase.Add(file)
                End If
            Case clsListView.LVTypeEnum.MiscFolders
                Dim dir As clsMiscFolder = TryCast(value, clsMiscFolder)
                If dir IsNot Nothing Then
                    If Not _owner.Iml.Images.ContainsKey(dir.IconPtr.ToString) Then _owner.Iml.Images.Add(dir.IconPtr.ToString, dir.Icon)
                    dir.ImageKey = dir.IconPtr.ToString
                    MyBase.Add(dir)
                End If
        End Select
    End Function
End Class