Attribute VB_Name = "modDVDMenu"
' -------------------------------------------------------------------------------
'
'   AVStoDVD - by MrC
'   File: modDVDMenu.bas
'   Purpose: DVD Menu functions
'
' -------------------------------------------------------------------------------


Option Explicit
Option Compare Binary
Option Base 0

Private VertRes As Integer
Private VideoStandardStr As String
Private FPS As Single
            

Public Function Generate_DVD_Menu(Optional DVDName As String, Optional OutputPath As String, Optional RunMode As Boolean) As Byte

    ' Returns 0 if everything is OK
    ' Returns 1 if aborted by user
    ' Returns 2 if any error is occurred
    
    ' RunMode = true  -> Menu generation during encoding
    ' RunMode = false -> Menu generation during editing/designing
    
    Dim TempPathName As String
    Dim OutputPathname As String
    Dim ThumbImagePathName As String
    Dim jj As Integer
    Dim kk As Integer
    Dim StrASS As String
    Dim StrAVS As String
    Dim MenuFramesNum As Long
    Dim MInfo As New clsMediaInfo
    Dim AudioInfo As New clsTitleAudioInfo
    Dim FlagSkip As Boolean
    Dim sCL As String
    Dim MaxNumSteps As Long
    
    On Error GoTo Err_Handling
    
    ' Initialize variables
    VideoStandardStr = "pal_video"
    FPS = 25
    If VideoStandard = NTSC Then
        VideoStandardStr = "ntsc_video"
        FPS = 2997 / 100
    End If
    If DVDMenu.AR = Standard Then
        VertRes = 540
    Else
        VertRes = 406
    End If
    MaxNumSteps = DVDMenu.TitlesFormat * NumTitles + 1
    If RunMode = True And modFS.EsisteFile(DVDMenu.BackgroundAudioPath) = True Then
        MaxNumSteps = MaxNumSteps + 1
    End If
    If OutputPath = "" Then OutputPath = Preferences.AssetsPath
    If Right(OutputPath, 1) <> "\" Then
        OutputPathname = OutputPath & "\"
    Else
        OutputPathname = OutputPath
    End If
    If DVDName <> "" Then OutputPathname = OutputPathname & DVDName & "_"
    TempPathName = Preferences.TempPath & "\"
    If DVDName <> "" Then TempPathName = TempPathName & DVDName & "_"
    
    ' Clean garbage
    If Dir(TempPathName & "Thumb*.bmp") <> "" Then
        Kill TempPathName & "Thumb*.bmp"
    End If
    If Dir(TempPathName & "Menu*.*") <> "" Then
        Kill TempPathName & "Menu*.*"
    End If
    
    Screen.MousePointer = vbHourglass
    Load frmMessage
    With frmMessage
        .Initialize "AVStoDVD - Building DVD Menu", "", , , , 0, MaxNumSteps
        .Show 0, Screen.ActiveForm
        If DVDMenu.TitlesFormat = Thumbs And DVDMenu.ThumbImageSource = SourceTitle Then
            ' Generate Thumbnails
            For jj = 1 To NumTitles
                If .FormIsClosedByUser = True Then
                    Exit For
                Else
                    .Update "Generating DVD Menu Thumbnails:" & vbCrLf & vbCrLf & "Title " & jj & "/" & NumTitles & "...", CLng(jj)
                    modDVDMenu.Generate_DVD_Thumbnail jj, TempPathName & "Thumb_" & jj, RunMode
                End If
            Next jj
        End If
        If .FormIsClosedByUser = False Then
            If RunMode = True Then
                ' Generate Audio
                If modFS.EsisteFile(DVDMenu.BackgroundAudioPath) = True Then
                    .Update "Generating DVD Menu Audio...", .ProgressBar.value + 1
                    If MInfo.ReadMediaInfo(DVDMenu.BackgroundAudioPath, , False, False, True, False) = True Then
                        FlagSkip = False
                        If modFS.EsisteFile(OutputPathname & "Menu.ac3") = True Then
                            FlagSkip = CBool(frmQuestion.Display(frmMain, "DVD Menu Audio " & Msgs.FileExistsOverwrite & vbCrLf & vbCrLf & "'" & OutputPathname & "Menu.ac3'" & vbCrLf & vbCrLf & "Default 'Yes'", , 60) - 6) 'vbYes=6 vbNo=7
                        End If
                        If FlagSkip = False Then
                            AudioInfo.Initialize MInfo, 0
                            If AudioInfo.DVDCompliant = AC3_Compl Then
                                sCL = "-i """ & DVDMenu.BackgroundAudioPath & """"
                                If DVDMenu.Style = MotionMenu Then
                                    sCL = sCL & " -t " & DVDMenu.MotionMenuDuration
                                End If
                                sCL = sCL & " -c:a copy -vn -sn """ & OutputPathname & "Menu.ToFix.ac3"""
                                modShellEx.Execute App.Path & "\FFmpeg\ffmpeg.exe", sCL, SW_MINIMIZED, True
                                modShellEx.Execute App.Path & "\ac3fix\ac3fix.exe", """" & OutputPathname & "Menu.ToFix.ac3""" & " """ & OutputPathname & "Menu.ac3""", SW_MINIMIZED, True
                                modFS.DeleteIfExist OutputPathname & "Menu.ToFix.ac3"
                            Else
                                If Preferences.DSFiltersRuntime = True Then
                                    modExtSW.AudioMixerChange Val(AudioInfo.Channels), 2
                                End If
                                sCL = "-i """ & DVDMenu.BackgroundAudioPath & """" & _
                                      IIf(Preferences.MultiThread = True, " -threads " & SysInfo.ProcessorNumber, "") & _
                                      " -y -vn -c:a ac3 " & _
                                      " -ac 2 -ar 48000 -ab " & Preferences.AudioBitRate & "k"
                                If DVDMenu.Style = MotionMenu Then
                                    sCL = sCL & " -t " & modStr.VisualTime(DVDMenu.MotionMenuDuration, True)
                                End If
                                sCL = sCL & " """ & OutputPathname & "Menu.ac3"""
                                modShellEx.Execute App.Path & "\FFmpeg\ffmpeg.exe", sCL, SW_MINIMIZED, True
                                If Preferences.DSFiltersRuntime = True Then
                                    modExtSW.AudioMixerRestore
                                End If
                            End If
                        End If
                    End If
                End If
            End If
            ' Generate Background
            .Update "Generating DVD Menu Background...", .ProgressBar.Max
            ' Generate DVD Title Label (VobSub with ASS format)
            StrASS = "[Script Info]" & vbCrLf & _
                     "; This is a Advanced Sub Station Alpha v4+ script" & vbCrLf & _
                     "Title: TitleText ASS file" & vbCrLf & _
                     "Original Script: " & frmMain.StatusBar.Panels("Release").Text & vbCrLf & _
                     "ScriptType: v4.00+" & vbCrLf & _
                     "WrapStyle: 0" & vbCrLf & _
                     "PlayResX: 720" & vbCrLf & _
                     "PlayResY: " & VertRes & vbCrLf & _
                     "ScaledBorderAndShadow: yes" & vbCrLf & _
                     "Video Aspect Ratio: 0" & vbCrLf & _
                     "Video Zoom: 6" & vbCrLf & _
                     "Video Position: 0" & vbCrLf & vbCrLf & _
                     "[V4+ Styles]" & vbCrLf & _
                     "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding" & vbCrLf & _
                     "Style: Default," & DVDMenu.TitleFont.Name & "," & Round(1.66 * DVDMenu.TitleFont.Height - 1, 0) & "," & DVDMenu.TitleFont.Color & ",255,0,&HA0000000&," & -CInt(DVDMenu.TitleFont.Bold) & "," & -CInt(DVDMenu.TitleFont.Italic) & "," & -CInt(DVDMenu.TitleFont.Underline) & ",0,100,100,0,0,1," & -CInt(DVDMenu.TitleFont.Outline) & "," & -CInt(DVDMenu.TitleFont.Shadow) * 2 & "," & IIf(DVDMenu.TitleAlignment = vbLeftJustify, 7, IIf(DVDMenu.TitleAlignment = vbRightJustify, 9, 8)) & "," & DVDMenu.TitleLeft & "," & 720 - DVDMenu.TitleLeft - DVDMenu.TitleWidth & "," & DVDMenu.TitleTop & ",0" & vbCrLf & vbCrLf & _
                     "[Events]" & vbCrLf & _
                     "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" & vbCrLf
            If DVDMenu.Style = MotionMenu And RunMode = True Then
                StrASS = StrASS & _
                         "Dialogue: 0,0:00:00.00,0:" & Replace(Format(Val(DVDMenu.MotionMenuDuration) / 3600 / 24, "nn:ss"), ".", ":") & ".01"
            Else
                StrASS = StrASS & _
                         "Dialogue: 0,0:00:00.00,0:00:00.01"
            End If
            StrASS = StrASS & ",Default,,0000,0000,0000,," & Replace(Replace(DVDMenu.TitleText, Chr(13), "\"), Chr(10), "N")
            modStr.STRtoANSIFile StrASS, TempPathName & "TitleText.ass"
            ' Generate Thumbs Labels (VobSub with ASS format)
            For jj = 1 To NumTitles
                StrASS = "[Script Info]" & vbCrLf & _
                         "; This is a Advanced Sub Station Alpha v4+ script" & vbCrLf & _
                         "Title: Thumb" & jj & "LabelText ASS file" & vbCrLf & _
                         "Original Script: " & frmMain.StatusBar.Panels("Release").Text & vbCrLf & _
                         "ScriptType: v4.00+" & vbCrLf & _
                         "WrapStyle: 0" & vbCrLf & _
                         "PlayResX: 720" & vbCrLf & _
                         "PlayResY: " & VertRes & vbCrLf & _
                         "ScaledBorderAndShadow: yes" & vbCrLf & _
                         "Video Aspect Ratio: 0" & vbCrLf & _
                         "Video Zoom: 6" & vbCrLf & _
                         "Video Position: 0" & vbCrLf & vbCrLf & _
                         "[V4+ Styles]" & vbCrLf & _
                         "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding" & vbCrLf & _
                         "Style: Default," & DVDMenu.ThumbLabelFont(jj).Name & "," & Round(1.66 * DVDMenu.ThumbLabelFont(jj).Height - 1, 0) & "," & DVDMenu.ThumbLabelFont(jj).Color & ",255,&H4A000000&,0," & -CInt(DVDMenu.ThumbLabelFont(jj).Bold) & "," & -CInt(DVDMenu.ThumbLabelFont(jj).Italic) & "," & -CInt(DVDMenu.ThumbLabelFont(jj).Underline) & ",0,100,100,0,0,1," & -CInt(DVDMenu.ThumbLabelFont(jj).Outline) & "," & -CInt(DVDMenu.ThumbLabelFont(jj).Shadow) & "," & IIf(DVDMenu.ThumbLabelAlignment(jj) = vbLeftJustify, 7, IIf(DVDMenu.ThumbLabelAlignment(jj) = vbRightJustify, 9, 8)) & "," & DVDMenu.ThumbLabelLeft(jj) & "," & 720 - DVDMenu.ThumbLabelLeft(jj) - DVDMenu.ThumbLabelWidth(jj) & "," & DVDMenu.ThumbLabelTop(jj) & ",0" & vbCrLf & vbCrLf & _
                         "[Events]" & vbCrLf & _
                         "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" & vbCrLf
                If DVDMenu.Style = MotionMenu And RunMode = True Then
                    StrASS = StrASS & _
                             "Dialogue: 0,0:00:00.00,0:" & Replace(Format(Val(DVDMenu.MotionMenuDuration) / 3600 / 24, "nn:ss"), ".", ":") & ".01"
                Else
                    StrASS = StrASS & _
                             "Dialogue: 0,0:00:00.00,0:00:00.01"
    
                End If
                StrASS = StrASS & ",Default,,0000,0000,0000,," & Replace(Replace(DVDMenu.ThumbLabelText(jj), Chr(13), "\"), Chr(10), "N")
                modStr.STRtoANSIFile StrASS, TempPathName & "ThumbLabelText" & jj & ".ass"
            Next jj
            ' Generate AVS Scripts for all Menu Pages
            StrAVS = ""
            For jj = 1 To DVDMenu.NumMenuPages
                StrAVS = "LoadCPlugin(""" & App.Path & "\Lib\ffms2.dll""" & ")" & vbCrLf & _
                         "LoadPlugin(""" & App.Path & "\Lib\GetSystemEnv.dll""" & ")" & vbCrLf & _
                         "Import(""" & App.Path & "\Lib\A2DSource.avsi""" & ")" & vbCrLf & _
                         "Import(""" & App.Path & "\Lib\DropShadow.avsi"")" & vbCrLf & _
                         "LoadPlugin(""" & App.Path & "\VobSub\VSFilter.dll""" & ")" & vbCrLf & vbCrLf
                If DVDMenu.Style = MotionMenu Then
                    If RunMode = True Then
                        MenuFramesNum = CLng(FPS * DVDMenu.MotionMenuDuration) - 1
                        If DVDMenu.BackgroundVideoPath <> "" Then
                            StrAVS = StrAVS & _
                                     "Background = A2DVideoSource(""" & DVDMenu.BackgroundVideoPath & """).ChangeFPS(""" & VideoStandardStr & """).Loop().Trim(0," & MenuFramesNum & ")" & vbCrLf
                        End If
                    Else
                        If DVDMenu.BackgroundVideoPath <> "" Then
                            StrAVS = StrAVS & _
                                     "Background = A2DVideoSource(""" & DVDMenu.BackgroundVideoPath & """).Trim(1,1)" & vbCrLf
                        End If
                    End If
                End If
                If InStr(1, StrAVS, "Background =") = 0 Then
                    StrAVS = StrAVS & _
                             "Background = ImageSource(""" & DVDMenu.BackgroundPicturePath & """,fps=" & Replace(CStr(FPS), ",", ".") & ",start=0,end=" & MenuFramesNum & ")" & vbCrLf
                End If
                StrAVS = StrAVS & _
                         "Background = Background.Lanczos4Resize(720," & VertRes & ").ConvertToYV12" & vbCrLf
                If DVDMenu.PlayAllButton = True Then
                    StrAVS = StrAVS & _
                             "PlayAll = ImageSource(""" & DVDMenu.PlayAllButtonPicturePath & """,fps=" & Replace(CStr(FPS), ",", ".") & ",start=0,end=" & MenuFramesNum & ").Lanczos4Resize(" & DVDMenu.PlayAllButtonWidth & "," & DVDMenu.PlayAllButtonHeight & ")" & vbCrLf
                    ' Append Play All button and add shadow
                    Select Case DVDMenu.PlayAllShadow
                    Case None
                        StrAVS = StrAVS & _
                                 "Background = Background.Overlay(PlayAll," & DVDMenu.PlayAllButtonLeft & "," & DVDMenu.PlayAllButtonTop & ")" & vbCrLf
                    Case Simple
                        StrAVS = StrAVS & _
                                 "Background = Background.Overlay(Blankclip(PlayAll,color=$000000)," & DVDMenu.PlayAllButtonLeft + 5 & "," & DVDMenu.PlayAllButtonTop + 3 & ")" & vbCrLf & _
                                 "Background = Background.Overlay(PlayAll," & DVDMenu.PlayAllButtonLeft & "," & DVDMenu.PlayAllButtonTop & ")" & vbCrLf
                    Case Progressive
                        StrAVS = StrAVS & _
                                 "Background = DropShadow(Background,PlayAll," & DVDMenu.PlayAllButtonLeft & "," & DVDMenu.PlayAllButtonTop & ")" & vbCrLf
                    End Select
                End If
                StrAVS = StrAVS & _
                         "Background = Background.TextSub(""" & TempPathName & "TitleText.ass""" & ")" & vbCrLf
                For kk = (jj - 1) * DVDMenu.MaxTitlesPage + 1 To jj * DVDMenu.MaxTitlesPage
                    If DVDMenu.NumMenuPages > 1 Then
                        ' Append Right Arrows button and add shadow
                        If jj < DVDMenu.NumMenuPages Then
                            StrAVS = StrAVS & _
                                     "ArrowR = ImageSource(""" & DVDMenu.ArrowRButtonPicturePath & """,pixel_type=""rgb32"",fps=" & Replace(CStr(FPS), ",", ".") & ",start=0,end=" & MenuFramesNum & ").Lanczos4Resize(" & DVDMenu.ArrowRButtonWidth & "," & DVDMenu.ArrowRButtonHeight & ")" & vbCrLf
                            Select Case DVDMenu.ArrowsShadow
                            Case None
                                StrAVS = StrAVS & _
                                         "Background = Background.Overlay(ArrowR, " & DVDMenu.ArrowRButtonLeft & "," & DVDMenu.ArrowRButtonTop & ",ShowAlpha(ArrowR,""rgb""))" & vbCrLf
                            Case Simple
                                StrAVS = StrAVS & _
                                         "Background = Background.Overlay(Blankclip(ArrowR,color=$000000)," & DVDMenu.ArrowRButtonLeft + 5 & "," & DVDMenu.ArrowRButtonTop + 3 & ")" & vbCrLf & _
                                         "Background = Background.Overlay(ArrowR, " & DVDMenu.ArrowRButtonLeft & "," & DVDMenu.ArrowRButtonTop & ",ShowAlpha(ArrowR,""rgb""))" & vbCrLf
                            Case Progressive
                                StrAVS = StrAVS & _
                                         "Background = DropShadow(Background,ArrowR," & DVDMenu.ArrowRButtonLeft & "," & DVDMenu.ArrowRButtonTop & ")" & vbCrLf
                            End Select
                        End If
                        ' Append Left Arrows button and add shadow
                        If jj > 1 Then
                            StrAVS = StrAVS & _
                                     "ArrowL = ImageSource(""" & DVDMenu.ArrowLButtonPicturePath & """,pixel_type=""rgb32"",fps=" & Replace(CStr(FPS), ",", ".") & ",start=0,end=" & MenuFramesNum & ").Lanczos4Resize(" & DVDMenu.ArrowLButtonWidth & "," & DVDMenu.ArrowLButtonHeight & ")" & vbCrLf
                            Select Case DVDMenu.ArrowsShadow
                            Case None
                                StrAVS = StrAVS & _
                                         "Background = Background.Overlay(ArrowL, " & DVDMenu.ArrowLButtonLeft & "," & DVDMenu.ArrowLButtonTop & ",ShowAlpha(ArrowL,""rgb""))" & vbCrLf
                            Case Simple
                                StrAVS = StrAVS & _
                                         "Background = Background.Overlay(Blankclip(ArrowL,color=$000000)," & DVDMenu.ArrowLButtonLeft + 5 & "," & DVDMenu.ArrowLButtonTop + 3 & ")" & vbCrLf & _
                                         "Background = Background.Overlay(ArrowL, " & DVDMenu.ArrowLButtonLeft & "," & DVDMenu.ArrowLButtonTop & ",ShowAlpha(ArrowL,""rgb""))" & vbCrLf
                            Case Progressive
                                StrAVS = StrAVS & _
                                         "Background = DropShadow(Background,ArrowL," & DVDMenu.ArrowLButtonLeft & "," & DVDMenu.ArrowLButtonTop & ")" & vbCrLf
                            End Select
                        End If
                    End If
                    ' Append Titles Script to Menu AVS Script
                    If kk <= DVDMenu.NumMenuTitles Then
                        If DVDMenu.TitlesFormat = Thumbs Then
                            If DVDMenu.Style = MotionMenu And RunMode = True Then
                                StrAVS = StrAVS & "Thumb" & kk & " = Import(""" & TempPathName & "Thumb_" & kk & "_Video.avs""" & ")" & vbCrLf & _
                                                  "Thumb" & kk & " = Thumb" & kk & ".KillAudio().Loop()" & vbCrLf
                            Else
                                If DVDMenu.ThumbImageSource = ExternalFile Then
                                    ThumbImagePathName = DVDMenu.ThumbPicturePath(kk)
                                Else
                                    ThumbImagePathName = TempPathName & "Thumb_" & kk & ".bmp"
                                End If
                                StrAVS = StrAVS & "Thumb" & kk & " = ImageSource(""" & ThumbImagePathName & """,start=0,end=0).Lanczos4Resize(" & DVDMenu.ThumbWidth(kk) & "," & DVDMenu.ThumbHeight(kk) & ")" & vbCrLf
                            End If
                            ' Add shadow
                            Select Case DVDMenu.ThumbShadow
                            Case None
                                StrAVS = StrAVS & _
                                         "Background = Background.Overlay(Thumb" & kk & "," & DVDMenu.ThumbLeft(kk) & "," & DVDMenu.ThumbTop(kk) & ")" & vbCrLf
                            Case Simple
                                StrAVS = StrAVS & _
                                         "Background = Background.Overlay(Blankclip(Thumb" & kk & ",color=$000000)," & DVDMenu.ThumbLeft(kk) + 5 & "," & DVDMenu.ThumbTop(kk) + 3 & ")" & vbCrLf & _
                                         "Background = Background.Overlay(Thumb" & kk & "," & DVDMenu.ThumbLeft(kk) & "," & DVDMenu.ThumbTop(kk) & ")" & vbCrLf
                            Case Progressive
                                StrAVS = StrAVS & _
                                         "Background = DropShadow(Background,Thumb" & kk & "," & DVDMenu.ThumbLeft(kk) & "," & DVDMenu.ThumbTop(kk) & ")" & vbCrLf
                            End Select
                        End If
                        StrAVS = StrAVS & _
                                 "Background = Background.TextSub(""" & TempPathName & "ThumbLabelText" & kk & ".ass""" & ")" & vbCrLf
                    End If
                Next kk
                ' Continue Menu AVS Script
                StrAVS = StrAVS & vbCrLf & _
                         "Last = Background" & vbCrLf & _
                         "Lanczos4Resize(720," & IIf(VideoStandard = NTSC, 480, 576) & ")"
                modStr.STRtoANSIFile StrAVS, TempPathName & "MenuPage" & jj & ".avs"
                If RunMode = False Then
                    modShellEx.Execute App.Path & "\FFmpeg\ffmpeg.exe", "-i """ & TempPathName & "MenuPage" & jj & ".avs""" & " -f rawvideo" & IIf(Preferences.MultiThread = True, " -threads " & SysInfo.ProcessorNumber, "") & " -c:v bmp -r 1 -y -an """ & TempPathName & "MenuPage" & jj & ".bmp""", SW_MINIMIZED, True
                Else
                    If DVDMenu.Style = MotionMenu Then
                        FlagSkip = False
                        If modFS.EsisteFile(OutputPathname & "MenuPage" & jj & ".m2v") = True Then
                            FlagSkip = CBool(frmQuestion.Display(frmMain, "DVD Menu Video " & Msgs.FileExistsOverwrite & vbCrLf & vbCrLf & "'" & OutputPathname & "MenuPage" & jj & ".m2v'" & vbCrLf & vbCrLf & "Default 'Yes'", , 60) - 6) 'vbYes=6 vbNo=7
                        End If
                        If FlagSkip = False Then
                            sCL = "-i """ & TempPathName & "MenuPage" & jj & ".avs""" & _
                                  " -threads " & SysInfo.ProcessorNumber & _
                                  " -aspect " & IIf(DVDMenu.AR = Standard, "4:3", "16:9") & _
                                  " -c:v mpeg2video -b:v " & DVDMenu.VideoBitRate & "k -minrate " & DVDMenu.VideoBitRate & "k -maxrate " & DVDMenu.VideoBitRate & "k" & _
                                  " -bufsize 2000k -dc 10 -bf 2" & _
                                  " -y """ & OutputPathname & "MenuPage" & jj & ".m2v"""
                            modShellEx.Execute App.Path & "\FFmpeg\ffmpeg.exe", sCL, Preferences.EncodingWindowStyle, True
                        End If
                    Else
                        modShellEx.Execute App.Path & "\FFmpeg\ffmpeg.exe", "-i """ & TempPathName & "MenuPage" & jj & ".avs""" & " -f rawvideo" & IIf(Preferences.MultiThread = True, " -threads " & SysInfo.ProcessorNumber, "") & " -c:v bmp -r 1 -y -an """ & OutputPathname & "MenuPage" & jj & ".bmp""", SW_MINIMIZED, True
                    End If
                End If
            Next jj
            Generate_DVD_Menu = 0
        Else
            Generate_DVD_Menu = 1
        End If
    End With
    
    GoTo Exit_Handling
        
Err_Handling:
Generate_DVD_Menu = 2
Select Case Err.Number
Case 9999
    Resume
Case Else
    MsgBox "Error " & Err.Number & vbCrLf & vbCrLf & Err.Description, vbCritical, App.Title
End Select

Exit_Handling:
Set MInfo = Nothing
Set AudioInfo = Nothing
Unload frmMessage
Screen.MousePointer = vbDefault


End Function


Public Sub Generate_DVD_Thumbnail(NumTitle As Integer, OutputPathname As String, Optional RunMode As Boolean)

    ' OutputPathName is intended with full path and without extension

    Dim sAVS As String
    Dim PathName As String
    
    With Title(NumTitle)
        If DVDMenu.ThumbAVSSCript(NumTitle) <> "" Then
            sAVS = DVDMenu.ThumbAVSSCript(NumTitle)
        Else
            sAVS = .AVSScript
            sAVS = modStr.RemoveStr(sAVS, ".Normalize()")
            sAVS = Replace(sAVS, "#PullDown: using DGPulldown/HCenc to upsize FPS", "Video = Video.ChangeFPS(""" & VideoStandardStr & """)")
            If .AudioTracksCount = 0 Then
                sAVS = Replace(sAVS, "Return Video", "Last = Video")
                'sAVS = modStr.RemoveStr(sAVS, "Return Video")
            Else
                sAVS = Replace(sAVS, "AudioDub(Video, Audio)", "Last = Video")
                'sAVS = modStr.RemoveStr(sAVS, "AudioDub(Video, Audio)")
            End If
            DVDMenu.ThumbAVSSCript(NumTitle) = sAVS
        End If
            
        If DVDMenu.Style = MotionMenu And RunMode = False Then
            sAVS = sAVS & vbCrLf & _
                   "Trim(" & DVDMenu.ThumbFrameEnd(NumTitle) & "," & DVDMenu.ThumbFrameEnd(NumTitle) & ")" & vbCrLf & _
                   "Image = Last" & vbCrLf & _
                   "Film = ImageSource(""" & App.Path & "\Menu\Blank.bmp"",start=0,end=0)" & vbCrLf & _
                   "Film = Film.Subtitle(""" & NumTitle & """,x=-1,y=80,size=50,text_color=$000000,halo_color=$FFFFFF)" & vbCrLf & _
                   "Image = Image.Lanczos4Resize(Film.width,Film.height)" & vbCrLf & _
                   "Overlay(Image,Film,opacity=0.6,mode=""Blend"")"
        Else
            sAVS = sAVS & vbCrLf & _
                   "Trim(" & DVDMenu.ThumbFrameStart(NumTitle) & "," & DVDMenu.ThumbFrameEnd(NumTitle) & ")" & vbCrLf
        End If
        sAVS = sAVS & "Lanczos4Resize(" & DVDMenu.ThumbWidth(NumTitle) & "," & DVDMenu.ThumbHeight(NumTitle) & ")"
        If DVDMenu.Style = MotionMenu And RunMode = True Then
            PathName = OutputPathname & "_Video.avs"
            modStr.STRtoANSIFile sAVS, PathName
        Else
            PathName = OutputPathname & ".bmp"
            modStr.STRtoANSIFile sAVS, OutputPathname & "_AviSynthT.avs"
            modShellEx.Execute App.Path & "\FFmpeg\ffmpeg.exe", " -i """ & OutputPathname & "_AviSynthT.avs""" & " -f rawvideo -threads " & SysInfo.ProcessorNumber & " -c:v bmp -r 1 -y -an """ & PathName & """", SW_HIDE, True
        End If
        If modFS.EsisteFile(PathName) = False Then
            MsgBox "Warning! Cannot create DVD Thumbnail from Title " & NumTitle, vbCritical + vbOKOnly, App.Title
        End If
    End With

End Sub

Public Sub DVD_Adj_But(ByVal NumButs As Integer, Pos() As ButPos, Adj() As ButAdj, Optional HorizRes As Integer, Optional VertRes As Integer)
    
    Dim jj As Integer
    Dim kk As Integer
    Dim BC_X(1 To 99) As Single    'Buttons BaryCenter X co-ordinate
    Dim BC_Y(1 To 99) As Single    'Buttons BaryCenter Y co-ordinate
    Dim Vector As Single
    Dim Vector1 As Single
    Dim Vector2 As Single
    
    Erase Adj
    
    If HorizRes = 0 Then HorizRes = 720
    If VertRes = 0 Then VertRes = 406
    
    ' Define barycenters
    For jj = 1 To NumButs
        BC_X(jj) = Pos(jj).X + Pos(jj).w / 2
        BC_Y(jj) = Pos(jj).Y + Pos(jj).h / 2
    Next jj
    
    ' Define "Up" and "Down" highlight movements
    For jj = 1 To NumButs
        Vector1 = HorizRes ^ 2 + VertRes ^ 2
        Vector2 = Vector1
        For kk = 1 To NumButs
            If jj <> kk Then
                'If BC_Y(kk) < BC_Y(jj) Then
                If Pos(kk).Y + Pos(kk).h < BC_Y(jj) Then
                    Vector = (Abs(BC_X(jj) - BC_X(kk))) ^ 2 + (Abs(Pos(jj).Y - (Pos(kk).Y + Pos(kk).h))) ^ 2
                    If Vector < Vector1 Then
                        Adj(jj).Up = kk
                        Vector1 = Vector
                    End If
                End If
                'If BC_Y(kk) > BC_Y(jj) Then
                If Pos(kk).Y > BC_Y(jj) Then
                    Vector = (Abs(BC_X(jj) - BC_X(kk))) ^ 2 + ((Abs(Pos(jj).Y + Pos(jj).h) - Pos(kk).Y)) ^ 2
                    If Vector < Vector2 Then
                        Adj(jj).Down = kk
                        Vector2 = Vector
                    End If
                End If
            End If
        Next kk
        ' Override if BC_X is equal
        Vector1 = HorizRes ^ 2 + VertRes ^ 2
        Vector2 = Vector1
        For kk = 1 To NumButs
            If jj <> kk Then
                If BC_X(kk) = BC_X(jj) Then
                    Vector = Abs(BC_Y(kk) - BC_Y(jj))
                    If BC_Y(kk) < BC_Y(jj) Then
                        If Vector < Vector1 Then
                            Adj(jj).Up = kk
                            Vector1 = Vector
                        End If
                    ElseIf BC_Y(kk) > BC_Y(jj) Then
                        If Vector < Vector2 Then
                            Adj(jj).Down = kk
                            Vector2 = Vector
                        End If
                    End If
                End If
            End If
        Next kk
        If Adj(jj).Up = 0 Then Adj(jj).Up = jj
        If Adj(jj).Down = 0 Then Adj(jj).Down = jj
    Next jj
    
    ' Define "Right" and "Left" highlight movements
    For jj = 1 To NumButs
        Vector1 = HorizRes ^ 2 + VertRes ^ 2
        Vector2 = Vector1
        For kk = 1 To NumButs
            If jj <> kk Then
                'If BC_X(kk) < BC_X(jj) Then
                If Pos(kk).X + Pos(kk).w < BC_X(jj) Then
                    Vector = (Abs(Pos(jj).X - (Pos(kk).X + Pos(kk).w))) ^ 2 + (Abs(BC_Y(jj) - BC_Y(kk))) ^ 2
                    If Vector < Vector1 Then
                        Adj(jj).Left = kk
                        Vector1 = Vector
                    End If
                End If
                'If BC_X(kk) > BC_X(jj) Then
                If Pos(kk).X > BC_X(jj) Then
                    Vector = (Abs((Pos(jj).X + Pos(jj).w) - Pos(kk).X)) ^ 2 + (Abs(BC_Y(jj) - BC_Y(kk))) ^ 2
                    If Vector < Vector2 Then
                        Adj(jj).Right = kk
                        Vector2 = Vector
                    End If
                End If
            End If
        Next kk
        ' Override if BC_Y is equal
        Vector1 = HorizRes ^ 2 + VertRes ^ 2
        Vector2 = Vector1
        For kk = 1 To NumButs
            If jj <> kk Then
                If BC_Y(kk) = BC_Y(jj) Then
                    Vector = Abs(BC_X(kk) - BC_X(jj))
                    If BC_X(kk) < BC_X(jj) Then
                        If Vector < Vector1 Then
                            Adj(jj).Left = kk
                            Vector1 = Vector
                        End If
                    ElseIf BC_X(kk) > BC_X(jj) Then
                        If Vector < Vector2 Then
                            Adj(jj).Right = kk
                            Vector2 = Vector
                        End If
                    End If
                End If
            End If
        Next kk
        If Adj(jj).Left = 0 Then Adj(jj).Left = jj
        If Adj(jj).Right = 0 Then Adj(jj).Right = jj
    Next jj

End Sub


