' Copyright (C) 2023  Andy https://github.com/AAndyProgram
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY
Imports System.ComponentModel
Imports PersonalUtilities.Forms
Imports PersonalUtilities.Forms.Controls
Imports PersonalUtilities.Forms.Controls.Base
Imports PersonalUtilities.Functions.XML
Imports PersonalUtilities.Functions.XML.Base
Imports PersonalUtilities.Tools
Imports SCrawler.API.YouTube.Base
Imports SCrawler.API.YouTube.Objects
Imports SCrawler.DownloadObjects.STDownloader
Imports UMTypes = SCrawler.Plugin.UserMediaTypes
Imports ADB = PersonalUtilities.Forms.Controls.Base.ActionButton.DefaultButtons
Namespace API.YouTube.Controls
    Friend Class VideoOptionsForm : Implements IDesignXMLContainer
#Region "Declarations"
        Private MyView As FormView
        Private ReadOnly MyFieldsChecker As FieldsChecker
        Friend Property DesignXML As EContainer Implements IDesignXMLContainer.DesignXML
        Private Property DesignXMLNodes As String() Implements IDesignXMLContainer.DesignXMLNodes
        Private Property DesignXMLNodeName As String Implements IDesignXMLContainer.DesignXMLNodeName
        Private Const ControlsRow As Integer = 7
        Private ReadOnly Property CNT_PROCESSOR As TableControlsProcessor
        Friend Property MyContainer As YouTubeMediaContainerBase
        Private Initialization As Boolean = True
        Private ReadOnly InheritsFromContainer As Boolean
        Private ReadOnly M3U8Files As List(Of SFile)
        Friend Property UseCookies As Boolean = False
        Private ReadOnly Property M3U8FilesFull As List(Of SFile)
            Get
                Return ListAddList(Nothing, M3U8Files, LAP.NotContainsOnly).ListAddValue(CMB_PLS.Text, LAP.NotContainsOnly)
            End Get
        End Property
        Private Class FpsFieldChecker : Inherits FieldsCheckerProviderBase
            Private ReadOnly MyProvider As ANumbers = YouTubeSettings.FpsFormatProvider.MyProviderDefault
            Public Overrides Property ErrorMessage As String
                Get
                    Return IIf(HasError, YouTubeSettings.FpsFormatProvider.ErrorMessageDefault, String.Empty)
                End Get
                Set : End Set
            End Property
            Public Overrides Function Convert(ByVal Value As Object, ByVal DestinationType As Type, ByVal Provider As IFormatProvider,
                                              Optional ByVal NothingArg As Object = Nothing, Optional ByVal e As ErrorsDescriber = Nothing) As Object
                If ACheck(Of Double)(Value, AModes.Var, MyProvider) Then
                    Return Value
                Else
                    HasError = True
                    TypeError = True
                    Return Nothing
                End If
            End Function
        End Class
#End Region
#Region "Initializers"
        Friend Sub New(ByVal Container As YouTubeMediaContainerBase, Optional ByVal InheritsFromContainer As Boolean = False)
            InitializeComponent()
            M3U8Files = New List(Of SFile)
            MyContainer = Container
            CNT_PROCESSOR = New TableControlsProcessor(TP_CONTROLS)
            Me.InheritsFromContainer = InheritsFromContainer
            MyFieldsChecker = New FieldsChecker
            UseCookies = MyYouTubeSettings.DefaultUseCookies
        End Sub
#End Region
#Region "Form handlers"
        Private Sub VideoOptionsForm_Load(sender As Object, e As EventArgs) Handles Me.Load
            If Not DesignXML Is Nothing Then
                MyView = New FormView(Me) With {.LocationOnly = True}
                MyView.Import()
                MyView.SetFormSize()
            End If

            MyYouTubeSettings.DownloadLocations.PopulateComboBox(TXT_FILE)
            MyYouTubeSettings.PlaylistsLocations.PopulateComboBox(CMB_PLS,, True)
            CMB_PLS.Text = MyYouTubeSettings.LatestPlaylistFile.Value

            If Not MyContainer Is Nothing Then
                With MyContainer
                    Dim i%
                    Dim arr$() = Nothing
                    Dim arrComparer As New FComparer(Of String)(Function(x, y) x.ToLower = y.ToLower)
                    Dim setDef As Action(Of ComboBox, String) =
                        Sub(ByVal cmb As ComboBox, ByVal compValue As String)
                            i = -1
                            If Not compValue.IsEmptyString Then i = arr.ListIndexOf(compValue, arrComparer, EDP.ReturnValue)
                            If i >= 0 Then cmb.SelectedIndex = i Else cmb.SelectedIndex = 0
                        End Sub
                    Dim __audioOnly As Boolean = False
                    Dim __optionValue$

                    If .HasElements Then
                        Text = "Playlist"
                        If Not .PlaylistTitle.IsEmptyString Or Not .Title.IsEmptyString Then Text &= $" - { .PlaylistTitle.IfNullOrEmpty(.Title)}"
                        TP_MAIN.Controls.Remove(TP_HEADER_BASE)
                        TP_MAIN.RowStyles(0).Height = 0
                        Dim def% = If(InheritsFromContainer, .ArrayMaxResolution, MyYouTubeSettings.DefaultVideoDefinition.Value)
                        If InheritsFromContainer Then
                            __audioOnly = def = -2
                            If def <= 0 Then def = MyYouTubeSettings.DefaultVideoDefinition
                        Else
                            If Not def.ValueBetween(-1, 10000) Then def = 1080
                        End If
                        NUM_RES.Value = def
                        With TXT_FILE
                            .CaptionMode = ICaptionControl.Modes.CheckBox
                            .CaptionWidth = 18
                            .CaptionToolTipText = "If this checkbox is selected, this path is absolute and artist folder will not be created in it"
                            .CaptionToolTipEnabled = True
                        End With
                    Else
                        TP_OPTIONS.Controls.Remove(NUM_RES)
                        TP_OPTIONS.ColumnStyles(3).Width = 0
                        Dim img As Image = Nothing
                        Dim imgUrl$ = .ThumbnailUrlMedia
                        If Not imgUrl.IsEmptyString Then
                            img = ImageRenderer.GetImage(SFile.GetBytesFromNet(imgUrl, EDP.ReturnValue), EDP.ReturnValue)
                            If Not img Is Nothing Then ICON_VIDEO.Image = img : ICON_VIDEO.InitialImage = img
                        End If
                        LBL_TITLE.Text = $"{If(MyYouTubeSettings.FileAddDateToFileName_VideoForm.Value, $"[{ .DateAdded:yyyy-MM-dd}] ", String.Empty)}{ .Title}"
                        LBL_TIME.Text = AConvert(Of String)(.Duration, TimeToStringProvider, String.Empty)
                        TP_HEADER_INFO_2.ColumnStyles(1).Width = MeasureTextDefault(LBL_TIME.Text, LBL_TIME.Font).Width + PaddingE.GetOf({LBL_TIME}).Horizontal
                        TP_HEADER_INFO_2.Refresh()
                        LBL_URL.Text = .URL
                    End If

                    If .IsMusic Or __audioOnly Or (InheritsFromContainer And .IsAudioSelected) Then
                        OPT_AUDIO.Checked = True
                    Else
                        OPT_VIDEO.Checked = True
                    End If
                    CMB_FORMAT.Enabled = OPT_VIDEO.Checked

                    arr = AvailableVideoFormats
                    CMB_FORMAT.Items.AddRange(arr)
                    If InheritsFromContainer Then
                        __optionValue = .OutputVideoExtension.IfNullOrEmpty(MyYouTubeSettings.DefaultVideoFormat.Value)
                    Else
                        __optionValue = MyYouTubeSettings.DefaultVideoFormat.Value
                    End If
                    setDef(CMB_FORMAT, __optionValue)

                    arr = AvailableAudioFormats
                    CMB_AUDIO_CODEC.Items.AddRange(arr)
                    If InheritsFromContainer Then
                        __optionValue = .OutputAudioCodec.IfNullOrEmpty(IIf(.IsMusic, MyYouTubeSettings.DefaultAudioCodecMusic.Value, MyYouTubeSettings.DefaultAudioCodec.Value))
                    Else
                        __optionValue = IIf(.IsMusic, MyYouTubeSettings.DefaultAudioCodecMusic.Value, MyYouTubeSettings.DefaultAudioCodec.Value)
                    End If
                    setDef(CMB_AUDIO_CODEC, __optionValue)

                    arr = AvailableSubtitlesFormats
                    CMB_SUBS_FORMAT.Items.AddRange(arr)
                    If InheritsFromContainer Then
                        __optionValue = .OutputSubtitlesFormat.IfNullOrEmpty(IIf(.IsMusic, "LRC", MyYouTubeSettings.DefaultSubtitlesFormat.Value))
                    Else
                        __optionValue = IIf(.IsMusic, "LRC", MyYouTubeSettings.DefaultSubtitlesFormat.Value)
                    End If
                    setDef(CMB_SUBS_FORMAT, __optionValue)

                    If InheritsFromContainer Then
                        If .OutputVideoFPS > 0 Then TXT_FPS.Text = .OutputVideoFPS
                        If .OutputAudioBitrate > 0 Then TXT_AUDIO_BITRATE.Text = .OutputAudioBitrate
                    Else
                        If MyYouTubeSettings.DefaultVideoFPS > 0 Then TXT_FPS.Text = MyYouTubeSettings.DefaultVideoFPS
                        If MyYouTubeSettings.DefaultAudioBitrate > 0 Then TXT_AUDIO_BITRATE.Text = MyYouTubeSettings.DefaultAudioBitrate.Value
                    End If
                    With MyFieldsChecker
                        .AddControl(Of Double)(TXT_FPS, TXT_FPS.CaptionText, True, New FpsFieldChecker)
                        .AddControl(Of Integer)(TXT_AUDIO_BITRATE, TXT_AUDIO_BITRATE.CaptionText, True)
                        .EndLoaderOperations()
                    End With
                    TP_SUBS.Enabled = .Subtitles.Count > 0
                    TXT_SUBS_ADDIT.Enabled = .Subtitles.Count > 0
                    RefillTextBoxes()
                    TXT_SUBS_ADDIT.Checked = .PostProcessing_OutputSubtitlesFormats.Count > 0
                    TXT_EXTRA_AUDIO_FORMATS.Checked = .PostProcessing_OutputAudioFormats.Count > 0
                    TXT_FILE.Text = .File
                    RefillList()
                    If OPT_VIDEO.Checked Then
                        ChangeFileExtension(CMB_FORMAT.Text)
                    Else
                        If .HasElements Then NUM_RES.Enabled = False
                        ChangeFileExtension(CMB_AUDIO_CODEC.Text)
                    End If
                End With
            End If
            Initialization = False
        End Sub
        Private Sub VideoOptionsForm_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
            MyView.DisposeIfReady()
            MyFieldsChecker.DisposeIfReady()
            M3U8Files.Clear()
        End Sub
#End Region
#Region "Refill"
        Private Sub RefillList()
            Dim i%
            Dim h% = -1
            Dim rh% = IIf(MyContainer.HasElements, 60, 25)
            Dim s As New Size(Width, h)
            Dim CalculateSize As Action(Of Integer) =
                Sub(ByVal InitHeight As Integer)
                    With TP_MAIN.RowStyles(ControlsRow) : .SizeType = SizeType.Absolute : .Height = InitHeight : End With
                    s.Height = InitHeight
                    For ii% = 0 To TP_MAIN.RowStyles.Count - 1
                        If Not ii = ControlsRow And TP_MAIN.RowStyles(ii).SizeType = SizeType.Absolute Then s.Height += TP_MAIN.RowStyles(ii).Height
                    Next
                    s.Height += PaddingE.GetOf({TP_MAIN}).Vertical(TP_MAIN.RowStyles.Count - 3 - IIf(MyContainer.HasElements, 1, 0))
                End Sub
            Dim __contentType As UMTypes = IIf(OPT_VIDEO.Checked, UMTypes.Video, UMTypes.Audio)
            With TP_CONTROLS
                If .Controls.Count > 0 Then
                    For Each cnt As Control In .Controls : cnt.Dispose() : Next
                    .Controls.Clear()
                End If
                .RowStyles.Clear()
                .RowCount = 0
            End With
            With MyContainer
                Dim audio As MediaObject = Nothing
                If __contentType = UMTypes.Video Then audio = .SelectedAudio
                Dim data As IEnumerable(Of Control)

                If .HasElements Then
                    data = .Elements.Select(Function(ee) New MediaItem(ee, True) With {.Dock = DockStyle.Fill, .Checked = ee.Checked, .UseCookies = UseCookies})
                Else
                    data = (From m As MediaObject In .Self.MediaObjects
                            Where m.Type = __contentType
                            Select New VideoOption(m, audio) With {.Dock = DockStyle.Fill, .Checked = m.Index = MyContainer.SelectedVideoIndex})
                End If

                If data.ListExists Then
                    With TP_CONTROLS
                        With .RowStyles
                            .Clear()
                            For i = 0 To data.Count - 1 : .Add(New RowStyle(SizeType.Absolute, rh)) : Next
                            .Add(New RowStyle(SizeType.AutoSize))
                        End With
                        .RowCount = .RowStyles.Count
                        For i = 0 To data.Count - 1 : .Controls.Add(data(i), 0, i) : Next
                        .Controls.Cast(Of Control).ToList.ForEach(Sub(ByVal d As Control)
                                                                      DirectCast(d, ISupportInitialize).EndInit()
                                                                      If MyContainer.HasElements Then
                                                                          With DirectCast(d, MediaItem)
                                                                              AddHandler .CheckedChanged, AddressOf MediaItem_CheckedChanged
                                                                              AddHandler .BeforeOpenEditor, AddressOf MediaItem_BeforeOpenEditor
                                                                              AddHandler .BeforeOpenEditorFull, AddressOf MediaItem_BeforeOpenEditorFull
                                                                              AddHandler .Click, AddressOf CNT_PROCESSOR.MediaItem_Click
                                                                              AddHandler .KeyDown, AddressOf CNT_PROCESSOR.MediaItem_KeyDown
                                                                          End With
                                                                      End If
                                                                  End Sub)
                        If MyContainer.HasElements Then
                            If .Controls.Count > 0 Then
                                Dim cIndx% = 0
                                Dim c As Color
                                For Each cnt As MediaItem In .Controls
                                    cIndx += 1
                                    If (cIndx Mod 2) = 0 Then c = SystemColors.ControlLight Else c = SystemColors.Window
                                    cnt.BackColor = c
                                Next
                            End If
                        Else
                            If Not data.ListExists(Function(d As VideoOption) d.Checked) Then
                                If MyYouTubeSettings.DefaultVideoDefinition > 0 Then
                                    For Each cnt As VideoOption In .Controls
                                        If cnt.MyMedia.Height <= MyYouTubeSettings.DefaultVideoDefinition Then cnt.Checked = True : Exit For
                                    Next
                                Else
                                    DirectCast(.Controls(0), VideoOption).Checked = True
                                End If
                            End If
                        End If
                    End With

                    h = data.Count * rh + PaddingE.GetOf({TP_CONTROLS}).Vertical(1.5)
                    CalculateSize(h)
                    Dim hh% = Screen.PrimaryScreen.WorkingArea.Height - 20
                    If s.Height > hh Then
                        h = 5 * rh + PaddingE.GetOf({TP_CONTROLS}).Vertical(1.5)
                        CalculateSize(h)
                        With TP_CONTROLS
                            .AutoSizeMode = AutoSizeMode.GrowAndShrink
                            .AutoScroll = True
                            Dim p As Padding = .Padding
                            p.Right += 3
                            .Padding = p
                            .VerticalScroll.Visible = True
                            .VerticalScroll.Enabled = True
                            .HorizontalScroll.Visible = False
                            .HorizontalScroll.Enabled = False
                        End With
                    End If

                    With TP_CONTROLS
                        .PerformLayout()
                        .Select()
                        If .Controls.Count > 0 Then .Controls(0).Focus()
                    End With
                End If
            End With

            If s.Height = -1 Then s.Height = rh
            MaximumSize = Nothing
            MinimumSize = Nothing
            Size = s
            MinimumSize = Size
            MaximumSize = Size
        End Sub
#End Region
#Region "Media items' handlers"
        Private Sub MediaItem_CheckedChanged(ByVal Sender As MediaItem, ByVal Container As IYouTubeMediaContainer)
            ControlInvokeFast(TP_CONTROLS, Sub() Container.Checked = Sender.Checked, EDP.None)
        End Sub
        Private Sub MediaItem_BeforeOpenEditor(ByVal Sender As MediaItem, ByVal Container As IYouTubeMediaContainer)
            MediaItem_BeforeOpenEditorImpl(Sender, Container, False)
        End Sub
        Private Sub MediaItem_BeforeOpenEditorFull(ByVal Sender As MediaItem, ByVal Container As IYouTubeMediaContainer)
            MediaItem_BeforeOpenEditorImpl(Sender, Container, True)
        End Sub
        Private Sub MediaItem_BeforeOpenEditorImpl(ByVal Sender As MediaItem, ByVal Container As IYouTubeMediaContainer, ByVal Full As Boolean)
            If MyContainer.HasElements Then
                ControlInvokeFast(TP_CONTROLS, Sub()
                                                   With DirectCast(Container, YouTubeMediaContainerBase)
                                                       .File = $"{TXT_FILE.Text.CSFilePS}{ .File.File}"
                                                       .M3U8_PlaylistFiles = M3U8FilesFull
                                                       If Full Then
                                                           .OutputVideoExtension = CMB_FORMAT.Text.StringToLower
                                                           .OutputVideoFPS = AConvert(Of Double)(TXT_FPS.Text, YouTubeSettings.FpsFormatProvider.MyProviderDefault, -1)
                                                           .OutputAudioBitrate = AConvert(Of Integer)(TXT_AUDIO_BITRATE.Text, -1)
                                                           .OutputAudioCodec = CMB_AUDIO_CODEC.Text.StringToLower
                                                           .OutputSubtitlesFormat = CMB_SUBS_FORMAT.Text.StringToLower
                                                           .IsAudioSelected = OPT_AUDIO.Checked
                                                       End If
                                                   End With
                                               End Sub, EDP.None)
            End If
        End Sub
#End Region
#Region "OK, Cancel"
        Private Sub BTT_DOWN_Click(sender As Object, e As EventArgs) Handles BTT_DOWN.Click
            Try
                If Not MyFieldsChecker.AllParamsOK Then Exit Sub
                Dim f As SFile
                If MyContainer.HasElements Then
                    f = TXT_FILE.Text.CSFileP
                Else
                    f = TXT_FILE.Text
                End If
                f = CleanFileName(f)
                If f.IsEmptyString Then Throw New ArgumentNullException("File", "The output file cannot be null")
                With MyContainer
                    .OutputVideoExtension = CMB_FORMAT.Text.StringToLower
                    .OutputVideoFPS = AConvert(Of Double)(TXT_FPS.Text, YouTubeSettings.FpsFormatProvider.MyProviderDefault, -1)
                    .OutputAudioBitrate = AConvert(Of Integer)(TXT_AUDIO_BITRATE.Text, -1)
                    .OutputAudioCodec = CMB_AUDIO_CODEC.Text.StringToLower
                    .OutputSubtitlesFormat = CMB_SUBS_FORMAT.Text.StringToLower
                    .M3U8_PlaylistFiles = M3U8FilesFull

                    If Not .HasElements Then
                        Dim cntIndex% = -1
                        With TP_CONTROLS.Controls
                            If .Count > 0 Then
                                For Each cnt As VideoOption In .Self
                                    If cnt.Checked Then cntIndex = cnt.MyMedia.Index : Exit For
                                Next
                            End If
                        End With
                        If cntIndex = -1 Then Throw New ArgumentOutOfRangeException("Download option", "What to download is not selected")
                        If OPT_VIDEO.Checked Then
                            .SelectedVideoIndex = cntIndex
                        Else
                            .SelectedVideoIndex = -1
                            .SelectedAudioIndex = cntIndex
                            .MediaType = UMTypes.Audio
                        End If
                        .FileSetManually = True
                        .File = f
                        .UpdateInfoFields()
                        '#If DEBUG Then
                        'Debug.WriteLine(.Command(False))
                        '#End If
                    Else
                        If OPT_AUDIO.Checked Then
                            .SetMaxResolution(-2)
                            .MediaType = UMTypes.Audio
                        Else
                            .SetMaxResolution(NUM_RES.Value)
                        End If
                        .AbsolutePath = TXT_FILE.Checked
                        .File = f
                    End If
                End With

                If MyYouTubeSettings.OutputPathAutoChange Then MyYouTubeSettings.OutputPath.Value = f
                If MyDownloaderSettings.OutputPathAutoAddPaths Then MyYouTubeSettings.DownloadLocations.Add(f, False)
                If Not CMB_PLS.Text.IsEmptyString Then MyYouTubeSettings.PlaylistsLocations.Add(CMB_PLS.Text, False, True)
                MyYouTubeSettings.LatestPlaylistFile.Value = CMB_PLS.Text

                DialogResult = DialogResult.OK
                Close()
            Catch ex As Exception
                ErrorsDescriber.Execute(EDP.SendToLog + EDP.ShowMainMsg, ex, $"Download {IIf(MyContainer.HasElements, "playlist", "video")}")
            End Try
        End Sub
        Private Sub BTT_CANCEL_Click(sender As Object, e As EventArgs) Handles BTT_CANCEL.Click
            DialogResult = DialogResult.Cancel
            Close()
        End Sub
#End Region
#Region "Controls' handlers"
#Region "Header"
        Private Sub LBL_URL_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs) Handles LBL_URL.LinkClicked
            If Not LBL_URL.Text.IsEmptyString Then
                Try : Process.Start(LBL_URL.Text) : Catch : End Try
            End If
        End Sub
#End Region
#Region "Settings"
        Private Sub OPT_VIDEO_AUDIO_CheckedChanged(sender As Object, e As EventArgs) Handles OPT_VIDEO.CheckedChanged, OPT_AUDIO.CheckedChanged
            If Not Initialization Then
                CMB_FORMAT.Enabled = OPT_VIDEO.Checked
                Dim upFormat As Action(Of String) = Sub(ByVal format As String)
                                                        If Not format.IsEmptyString Then
                                                            format = format.ToLower
                                                            Dim fIndex% = CMB_AUDIO_CODEC.Items.Cast(Of String).ListIndexOf(Function(f) f.ToLower = format)
                                                            If fIndex >= 0 Then CMB_AUDIO_CODEC.SelectedIndex = fIndex
                                                        End If
                                                    End Sub
                If OPT_VIDEO.Checked Then
                    upFormat(MyYouTubeSettings.DefaultAudioCodec)
                Else
                    upFormat(MyYouTubeSettings.DefaultAudioCodecMusic)
                End If

                If MyContainer.HasElements Then
                    NUM_RES.Enabled = OPT_VIDEO.Checked
                Else
                    RefillList()
                    If OPT_VIDEO.Checked Then
                        ChangeFileExtension(CMB_FORMAT.Text)
                    Else
                        ChangeFileExtension(CMB_AUDIO_CODEC.Text)
                    End If
                End If
            End If
        End Sub
        Private Sub CMB_FORMAT_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CMB_FORMAT.SelectedIndexChanged
            If Not Initialization AndAlso OPT_VIDEO.Checked Then ChangeFileExtension(CMB_FORMAT.Text)
        End Sub
        Private Sub CMB_AUDIO_CODEC_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CMB_AUDIO_CODEC.SelectedIndexChanged
            If Not Initialization AndAlso OPT_AUDIO.Checked Then ChangeFileExtension(CMB_AUDIO_CODEC.Text)
        End Sub
        Private Sub ChangeFileExtension(ByVal NewExt As String)
            If Not MyContainer.HasElements Then
                Dim f As SFile = TXT_FILE.Text
                f.Extension = NewExt.StringToLower
                TXT_FILE.Text = f
            End If
        End Sub
        Private Sub BTT_TRIM_Click(sender As Object, e As EventArgs) Handles BTT_TRIM.Click
            Using f As New VideoOptionsTrimForm(MyContainer) : f.ShowDialog() : End Using
        End Sub
        Private Sub TXT_SUBS_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_SUBS.ActionOnButtonClick
            Select Case Sender.DefaultButton
                Case ADB.Open
                    If MyContainer.Subtitles.Count > 0 Then
                        Using f As New SimpleListForm(Of String)(MyContainer.Subtitles.Select(Function(s) s.Name)) With {
                            .DesignXML = DesignXML,
                            .DesignXMLNodeName = SimpleArraysFormNode,
                            .Mode = SimpleListFormModes.CheckedItems,
                            .FormText = "Subtitles"
                        }
                            With MyContainer
                                If .SubtitlesSelectedIndexes.Count > 0 Then f.DataSelectedIndexes.AddRange(.SubtitlesSelectedIndexes)
                                If f.ShowDialog() = DialogResult.OK Then
                                    .SubtitlesSelectedIndexes.Clear()
                                    If f.DataResultIndexes.Count > 0 Then .SubtitlesSelectedIndexes.AddRange(f.DataResultIndexes)
                                    RefillTextBoxes()
                                End If
                            End With
                        End Using
                    End If
                Case ADB.Refresh
                    MyContainer.SubtitlesSelectedIndexesReset()
                    RefillTextBoxes()
                Case ADB.Clear
                    MyContainer.SubtitlesSelectedIndexes.Clear()
                    RefillTextBoxes()
            End Select
        End Sub
        Private Sub CONTROLS_ADDIT_ActionOnButtonClick(ByVal Sender As ActionButton, ByVal e As ActionButtonEventArgs) Handles TXT_SUBS_ADDIT.ActionOnButtonClick,
                                                                                                                               TXT_EXTRA_AUDIO_FORMATS.ActionOnButtonClick
            Dim isSubs As Boolean = CStr(DirectCast(e.AssociatedControl, TextBoxExtended).Tag) = "s"
            Select Case Sender.DefaultButton
                Case ADB.Open
                    Using f As New SimpleListForm(Of String)(If(isSubs, AvailableSubtitlesFormats, AvailableAudioFormats)) With {
                        .DesignXML = DesignXML,
                        .DesignXMLNodeName = SimpleArraysFormNode,
                        .Mode = SimpleListFormModes.CheckedItems,
                        .FormText = DirectCast(e.AssociatedControl, TextBoxExtended).CaptionText
                    }
                        With MyContainer
                            With If(isSubs, .PostProcessing_OutputSubtitlesFormats, .PostProcessing_OutputAudioFormats)
                                If .Self.Count > 0 Then f.DataSelected.AddRange(.Self)
                                If f.ShowDialog() = DialogResult.OK Then
                                    .Self.Clear()
                                    If f.DataResultIndexes.Count > 0 Then .Self.AddRange(f.DataResult)
                                    DirectCast(e.AssociatedControl, TextBoxExtended).Text = .ListToString
                                    RefillTextBoxes()
                                End If
                            End With
                        End With
                    End Using
                Case ADB.Refresh
                    If isSubs Then
                        MyContainer.PostProcessing_OutputSubtitlesFormats_Reset()
                    Else
                        MyContainer.PostProcessing_OutputAudioFormats_Reset()
                    End If
                    RefillTextBoxes()
                Case ADB.Clear
                    If isSubs Then
                        MyContainer.PostProcessing_OutputSubtitlesFormats.Clear()
                    Else
                        MyContainer.PostProcessing_OutputAudioFormats.Clear()
                    End If
                    RefillTextBoxes()
            End Select
        End Sub
#End Region
#Region "Footer"
        Private Sub CMB_PLS_ActionOnButtonClick(ByVal Sender As Object, ByVal e As ActionButtonEventArgs) Handles CMB_PLS.ActionOnButtonClick
            Select Case e.DefaultButton
                Case ADB.List
                    Dim result As Boolean = False
                    Dim selectedFiles As IEnumerable(Of SFile) = MyYouTubeSettings.PlaylistsLocations.ChooseNewPlaylistArray(CMB_PLS, result)
                    If result And selectedFiles.ListExists Then M3U8Files.ListAddList(selectedFiles, LAP.NotContainsOnly, LAP.ClearBeforeAdd)
                Case ADB.Save
                    With MyYouTubeSettings.PlaylistsLocations
                        If Not CMB_PLS.Text.IsEmptyString AndAlso .IndexOf(CMB_PLS.Text,, True) = -1 Then
                            .Add(CMB_PLS.Text, True, True)
                            .PopulateComboBox(CMB_PLS, CMB_PLS.Text, True)
                        End If
                    End With
                Case ADB.Clear : M3U8Files.Clear()
            End Select
        End Sub
        Private Sub BTT_PLS_BROWSE_MouseDown(sender As Object, e As MouseEventArgs) Handles BTT_PLS_BROWSE.MouseDown
            Try
                Dim f As SFile = Nothing
                If Not CMB_PLS.Text.IsEmptyString Then
                    f = CMB_PLS.Text
                ElseIf Not TXT_FILE.Text.IsEmptyString Then
                    f = TXT_FILE.Text
                End If
                f = SFile.SelectFiles(f, False, "Select a playlist...", "Playlists|*.m3u;*.m3u8|All files|*.*", EDP.ReturnValue).FirstOrDefault
                If Not f.IsEmptyString Then
                    If e.Button = MouseButtons.Right Then
                        MyYouTubeSettings.PlaylistsLocations.Add(f.ToString, True, True)
                        MyYouTubeSettings.PlaylistsLocations.PopulateComboBox(CMB_PLS, f, True)
                    End If
                    CMB_PLS.Text = f
                End If
            Catch ex As Exception
                ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.YouTube.Controls.VideoOptionsForm.SelectPlaylist]")
            End Try
        End Sub
        Private _FilePathBeforeItemChange As SFile = Nothing
        Private Sub TXT_FILE_ActionSelectedItemBeforeChanged(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles TXT_FILE.ActionSelectedItemBeforeChanged
            If Not TXT_FILE.Text.IsEmptyString Then _FilePathBeforeItemChange = TXT_FILE.Text Else _FilePathBeforeItemChange = Nothing
        End Sub
        Private Sub TXT_FILE_ActionSelectedItemChanged(ByVal Sender As Object, ByVal e As EventArgs, ByVal Item As ListViewItem) Handles TXT_FILE.ActionSelectedItemChanged
            Try
                If Not MyContainer.HasElements Then
                    Dim currentPath As SFile = _FilePathBeforeItemChange
                    Dim newPath As SFile = TXT_FILE.Text.CSFileP
                    If Not currentPath.File.IsEmptyString Then
                        newPath.Name = currentPath.Name
                        newPath.Extension = currentPath.Extension
                        TXT_FILE.Text = newPath
                    End If
                End If
            Catch ex As Exception
                ErrorsDescriber.Execute(EDP.SendToLog, ex, "[API.YouTube.Controls.VideoOptionsForm.ChangeDestinationPath]")
            Finally
                _FilePathBeforeItemChange = Nothing
            End Try
        End Sub
        Private Sub TXT_FILE_ActionOnButtonClick(ByVal Sender As Object, ByVal e As ActionButtonEventArgs) Handles TXT_FILE.ActionOnButtonClick
            If e.DefaultButton = ADB.Save And Not TXT_FILE.Text.IsEmptyString Then
                With MyYouTubeSettings.PlaylistsLocations
                    .Add(TXT_FILE.Text, True)
                    .PopulateComboBox(TXT_FILE, TXT_FILE.Text)
                End With
            End If
        End Sub
        Private Sub BTT_BROWSE_MouseDown(sender As Object, e As MouseEventArgs) Handles BTT_BROWSE.MouseDown
            Dim f As SFile
#Disable Warning BC40000
            If MyContainer.HasElements Then
                f = TXT_FILE.Text.CSFileP
                f = SFile.SelectPath(f, "Select the destination of the video files", EDP.ReturnValue)
            Else
                f = TXT_FILE.Text
                Dim ext$ = f.Extension
                Dim sPattern$ = "All Files|*.*|" &
                                $"Video|{AvailableVideoFormats.Select(Function(vf) $"*.{vf.ToLower}").ListToString(";")}" &
                                $"|Audio|{AvailableAudioFormats.Select(Function(af) $"*.{af.ToLower}").ListToString(";")}"
                f = SFile.SaveAs(f, "Select the destination of the video file",, ext, sPattern, EDP.ReturnValue)
                If Not f.IsEmptyString Then f.Extension = ext
            End If
#Enable Warning
            f = CleanFileName(f)
            If Not f.IsEmptyString Then
                If e.Button = MouseButtons.Right Then
                    MyYouTubeSettings.DownloadLocations.Add(f, MyDownloaderSettings.OutputPathAskForName)
                    MyYouTubeSettings.DownloadLocations.PopulateComboBox(TXT_FILE, f)
                End If
                TXT_FILE.Text = f
            End If
        End Sub
#End Region
#End Region
#Region "Functions"
        Private Sub RefillTextBoxes()
            With MyContainer
                If .SubtitlesSelectedIndexes.Count > 0 Then
                    TXT_SUBS.Text = ListAddList(Nothing, .Subtitles.Select(Function(s, i) If(.SubtitlesSelectedIndexes.Contains(i), s.ID, String.Empty)),
                                                LAP.NotContainsOnly, EDP.ReturnValue).ListToString(",")
                Else
                    TXT_SUBS.Clear()
                End If
                If .PostProcessing_OutputSubtitlesFormats.Count > 0 Then
                    TXT_SUBS_ADDIT.Text = .PostProcessing_OutputSubtitlesFormats.ListToString
                Else
                    TXT_SUBS_ADDIT.Clear()
                End If
                If .PostProcessing_OutputAudioFormats.Count > 0 Then
                    TXT_EXTRA_AUDIO_FORMATS.Text = .PostProcessing_OutputAudioFormats.ListToString
                Else
                    TXT_EXTRA_AUDIO_FORMATS.Clear()
                End If
            End With
        End Sub
#End Region
    End Class
End Namespace