Attribute VB_Name = "modul_Calaym_PlaylistFormats"
' Calaym - Media player GUI for sound systems
' Copyright (C) 2002-2014 Jan Vorel
'
' You can redistribute the official software packages under the terms of the
' User-friendly Distribution License Version 2.00, published by Jan Vorel
'
' You can use this software under the terms of the
' User-friendly Open-source License Version 1.00, published by Jan Vorel
'
' You should have received copies of the licenses along with this program. If
' not, contact the author.
'
' If you want to use or distribute this software under a different license, ask
' the author.
'
' The software is provided "as is" without warrenty of any kind. The Licensor
' cannot be held responsible for any damage caused by using, extracting or
' installing the software.

Option Explicit
Option Base 0

Public Function GetPlaylistTitle(ByVal Filename As String) As String
  Dim xLong1 As Long
  GetPlaylistTitle = SimpleFile(Filename)
  xLong1 = InStrRev(GetPlaylistTitle, ".")
  If Not xLong1 = 0& Then
    GetPlaylistTitle = Left(GetPlaylistTitle, xLong1 - 1&)
    End If
  End Function

Public Function IsPureFile(ByRef xFile As String, ByVal xPLPath As String) As Boolean
  If LCase(Left(xFile, 5&)) = "file:" Then
    IsPureFile = True
    xFile = Replace(Mid(xFile, 6&), "/", "\")
    If Left(xFile, 2&) = "\\" Then
      While Left(xFile, 3&) = "\\\"
        xFile = Mid(xFile, 2&)
        Wend
      If Mid(xFile, 4&, 2&) = ":\" Then
        xFile = Mid(xFile, 3&)
        End If
      Else
      If Left(xFile, 1&) = "\" Then
        xFile = Mid(xFile, 2&)
        End If
      'If Not (Mid(xLine, 2&, 2&) = ":\" Or Left(xLine, 2&) = "\\") Then
      If Not Mid(xFile, 2&, 2&) = ":\" Then
        xFile = GetFullFromRelativeFilename(xPLPath, xFile)
        End If
      End If
    Else
    If (InStr(xFile, "://") = 0&) Then
      IsPureFile = True
      xFile = Replace(xFile, "/", "\")
      If Not (Mid(xFile, 2&, 2&) = ":\" Or Left(xFile, 2&) = "\\") Then
        xFile = GetFullFromRelativeFilename(xPLPath, xFile)
        End If
      End If
    End If
  End Function

' Pure Non-Calym-playlist stuff only
' LoadPList stuffs use byref, allowing them to clear the buffer before further processing!
Public Sub LoadPList_PlsAap(ByRef hTextFileIn As Long, ByVal Filename As String, ByVal xLine As String, ByVal EntryString As String)
  Dim xPLPath As String
  Dim xCounter As Long
  Dim xBrkCnt As Long
  Dim xEStrLen As Long
  Dim xLong3 As Long

  #If UseFileLogging Then
    If EntryString = "File" Then
      MainForm_ctConsoleA_AddLog "  (pls playlist)"
      Else
      MainForm_ctConsoleA_AddLog "  (aap Apollo playlist)"
      End If
    #End If
  xPLPath = SimpleDir(Filename)
  xEStrLen = Len(EntryString)
  Do
    If LCase(Left(xLine, xEStrLen)) = EntryString Then
      xLong3 = InStr(xEStrLen + 1&, xLine, "=")
      If Not (xLong3 = 0& Or xLong3 = Len(xLine)) Then
        xLine = Mid(xLine, xLong3 + 1&)
        If IsPureFile(xLine, xPLPath) Then
          If Not xCounter = sCharA1Max Then
            If RemoveMissingOnPLLoad Then
              If AllowedItem(xLine, True) = 1& Then
                sCharA1(xCounter) = xLine
                xCounter = xCounter + 1&
                End If
              ElseIf AllowedItemSongFast(xLine, True) Then
              sCharA1(xCounter) = xLine
              xCounter = xCounter + 1&
              End If
            End If
          Else
          Call RadioForm_AddRadioEx(xLine, xLine, "", False)
          End If
        End If
      End If
    xBrkCnt = (xBrkCnt + 1&) Mod 64&
    If xBrkCnt = 0& Then
      Call DoEventsEx_SleepPeriodicalLW(0&)
      If AbortReading Then Exit Do
      End If
    Loop While TxtFile_ReadLine(hTextFileIn, xLine)
  Call TxtFile_ReadClose(hTextFileIn)
  GenCalaymStructure True, xCounter, xSorting
  End Sub

Public Sub LoadPList_M3uGeneric(ByRef hTextFileIn As Long, ByVal Filename As String, ByVal xLine As String)
  Dim xPLPath As String
  Dim xCounter As Long
  Dim xBrkCnt As Long

  #If UseFileLogging Then
    MainForm_ctConsoleA_AddLog "  (m3u playlist)"
    #End If
  xPLPath = SimpleDir(Filename)
  Do
    If Not Left(xLine, 1&) = "#" Then
      If IsPureFile(xLine, xPLPath) Then
        If Not xCounter = sCharA1Max Then
          If RemoveMissingOnPLLoad Then
            If AllowedItem(xLine, True) = 1& Then
              sCharA1(xCounter) = xLine
              xCounter = xCounter + 1&
              End If
            ElseIf AllowedItemSongFast(xLine, True) Then
            sCharA1(xCounter) = xLine
            xCounter = xCounter + 1&
            End If
          End If
        Else
        Call RadioForm_AddRadioEx(xLine, xLine, "", False)
        End If
      End If
    xBrkCnt = (xBrkCnt + 1&) Mod 64&
    If xBrkCnt = 0& Then
      Call DoEventsEx_SleepPeriodicalLW(0&)
      If AbortReading Then Exit Do
      End If
    Loop While TxtFile_ReadLine(hTextFileIn, xLine)
  Call TxtFile_ReadClose(hTextFileIn)
  GenCalaymStructure True, xCounter, xSorting
  End Sub

Public Sub LoadPList_Wpl(ByRef hTextFileIn As Long, ByVal Filename As String, ByVal xLine As String)
  Dim xPLPath As String
  Dim xCounter As Long
  Dim xBrkCnt As Long
  Dim xFindPos1 As Long
  Dim xLong1 As Long
  Dim xLong2 As Long
  Dim xChar1 As String

  #If UseFileLogging Then
    MainForm_ctConsoleA_AddLog "  (wpl playlist)"
    #End If
  xPLPath = SimpleDir(Filename)
  Do
    Do
      xBrkCnt = (xBrkCnt + 1&) Mod 64&
      If xBrkCnt = 0& Then
        Call DoEventsEx_SleepPeriodicalLW(0&)
        If AbortReading Then Exit Do
        End If
      xFindPos1 = InStr(xFindPos1 + 1&, xLine, "<media ", vbTextCompare)
      If xFindPos1 = 0& Then Exit Do
      GoSub AddThis
      Loop
    Loop While TxtFile_ReadLine(hTextFileIn, xLine)
  Call TxtFile_ReadClose(hTextFileIn)
  GenCalaymStructure True, xCounter, xSorting
  Exit Sub
  
AddThis:
  xLong1 = InStr(xFindPos1 + 7&, xLine, ">")
  If xLong1 = 0& Then xFindPos1 = Len(xLine): Return
  xChar1 = Mid(xLine, xFindPos1 + 6&, xLong1 - xFindPos1 - 6&)
  xFindPos1 = xLong2
  
  xLong1 = InStr(xChar1, " src=" + Chr(34))
  If xLong1 = 0& Then Return
  xLong2 = InStr(xLong1 + 6&, xChar1, Chr(34))
  If xLong2 = 0& Then Return
  xChar1 = Trim(Mid(xChar1, xLong1 + 6&, xLong2 - xLong1 - 6&))
  If IsPureFile(xLine, xPLPath) Then
    If Not xCounter = sCharA1Max Then
      If RemoveMissingOnPLLoad Then
        If AllowedItem(xChar1, True) = 1& Then
'Debug.Print "Add:" + xChar1
          sCharA1(xCounter) = xChar1
          xCounter = xCounter + 1&
          End If
        ElseIf AllowedItemSongFast(xChar1, True) Then
        sCharA1(xCounter) = xChar1
        xCounter = xCounter + 1&
        End If
      End If
    Else
    Call RadioForm_AddRadioEx(xChar1, xChar1, "", False)
    End If
  Return
  End Sub

Private Function FetchTag(ByRef hTextFileIn As Long, ByVal xFindTag As String, ByRef xLine As String, ByRef xFoundResult As String, ByRef xBrkCnt As Long) As Boolean
  Dim xLong1 As Long
  Dim xChar1 As String

'Debug.Print "FetchTag: Enter"

SkipToNextTag:
  Do
    xLong1 = 0&
    Do
      xLong1 = InStr(xLong1 + 1&, xLine, "<")
      If xLong1 = 0& Then Exit Do
      If LCase(Mid(xLine, xLong1 + 1&, Len(xFindTag))) = xFindTag Then
        Select Case Mid(xLine, xLong1 + Len(xFindTag) + 1&, 1&)
          Case ">", " "
            Exit Do
          End Select
        End If
      Loop
    If Not xLong1 = 0& Then Exit Do
    xBrkCnt = (xBrkCnt + 1&) Mod 64&
    If xBrkCnt = 0& Then
      Call DoEventsEx_SleepPeriodicalLW(0&)
      If AbortReading Then Exit Do
      End If
    Loop While TxtFile_ReadLine(hTextFileIn, xLine)
  If xLong1 = 0& Then
    xLine = ""
    Else
    xLine = LTrim(Mid(xLine, xLong1 + Len(xFindTag) + 1&))
    Do
      xLong1 = InStr(xLine, ">")
      If Not xLong1 = 0& Then
        xFoundResult = RTrim(Left(xLine, xLong1 - 1&))
        xLine = LTrim(Mid(xLine, xLong1 + 1&))
        FetchTag = True
        Exit Do
        End If
      If Len(xLine) > 4096& Then
        xLine = ""
        GoTo SkipToNextTag
        End If
      xBrkCnt = (xBrkCnt + 1&) Mod 64&
      If xBrkCnt = 0& Then
        Call DoEventsEx_SleepPeriodicalLW(0&)
        If AbortReading Then Exit Do
        End If
      If Not TxtFile_ReadLine(hTextFileIn, xChar1) Then
        Exit Do
        End If
      xLine = xLine + " " + xChar1
      Loop
    End If
'Debug.Print "FetchTag: Done"
  End Function

Private Function FetchToNextMarkup(ByRef hTextFileIn As Long, ByRef xLine As String, ByRef xFoundInner As String, ByRef xBrkCnt As Long) As Boolean
  Dim xLong1 As Long
  Dim xChar1 As String

'Debug.Print "FetchToNextMarkup: Enter"
SkipToNextTag:
  Do
    xLong1 = InStr(xLine, "<")
    If Not xLong1 = 0& Then
      FetchToNextMarkup = True
      xFoundInner = Left(xLine, xLong1 - 1&)
      xLine = Mid(xLine, xLong1)
      Exit Do
      End If
    If Len(xLine) > 16384 Then
      Exit Do
      End If
    xBrkCnt = (xBrkCnt + 1&) Mod 64&
    If xBrkCnt = 0& Then
      Call DoEventsEx_SleepPeriodicalLW(0&)
      If AbortReading Then Exit Do
      End If
    If Not TxtFile_ReadLine(hTextFileIn, xChar1) Then
      Exit Do
      End If
    xLine = xLine + " " + xChar1
    Loop
'Debug.Print "FetchToNextMarkup: Exit"
  End Function

Private Function DynOpenXmlEnc(ByRef hTextFileIn As Long, ByVal xFindTag As String, ByRef xLine As String, ByRef xBrkCnt As Long)
  Dim xChar1 As String
  If FetchTag(hTextFileIn, "?" + xFindTag, xLine, xChar1, xBrkCnt) Then
    If Not InStr(9&, xChar1, "UTF-8", vbTextCompare) = 0& Then
      If Not TxtFile_GetEncoding(hTextFileIn) = CP_UTF8 Then
        If Not TxtFile_SetEncoding(hTextFileIn, CP_UTF8, True) Then
          GoTo Fail
          End If
        ' ReOpen!
        xLine = ""
        If Not FetchTag(hTextFileIn, "?" + xFindTag, xLine, xChar1, xBrkCnt) Then
          GoTo Fail
          End If
        End If
      End If
    End If
  DynOpenXmlEnc = True
Fail:
  End Function

Public Sub LoadPList_Xspf(ByRef hTextFileIn As Long, ByVal Filename As String, ByVal xLine As String)
  Dim xPLPath As String
  Dim xCounter As Long
  Dim xBrkCnt As Long
  'Dim xLong1 As Long
  'Dim xLong2 As Long
  Dim xChar1 As String

  #If UseFileLogging Then
    MainForm_ctConsoleA_AddLog "  (xspf playlist)"
    #End If
  If DynOpenXmlEnc(hTextFileIn, "xml", xLine, xBrkCnt) Then
    xPLPath = SimpleDir(Filename)
    Do While FetchTag(hTextFileIn, "location", xLine, "", xBrkCnt)
      If Not FetchToNextMarkup(hTextFileIn, xLine, xChar1, xBrkCnt) Then
        Exit Do
        End If
      xChar1 = URLDecode(xChar1)
      Debug.Print "Process? " + xChar1
      If IsPureFile(xChar1, xPLPath) Then
        Debug.Print "  File " + xChar1
        If Not xCounter = sCharA1Max Then
          If RemoveMissingOnPLLoad Then
            If AllowedItem(xChar1, True) = 1& Then
              sCharA1(xCounter) = xChar1
              xCounter = xCounter + 1&
              End If
            ElseIf AllowedItemSongFast(xChar1, True) Then
            sCharA1(xCounter) = xChar1
            xCounter = xCounter + 1&
            End If
          End If
        Else
        Debug.Print "  URL " + xChar1
        Call RadioForm_AddRadioEx(xChar1, xChar1, "", False)
        End If
      Loop
    Call TxtFile_ReadClose(hTextFileIn)
    GenCalaymStructure True, xCounter, xSorting
    End If
  End Sub

Public Sub LoadPList_AIMP(ByRef hTextFileIn As Long, ByVal Filename As String, ByVal xLine As String, ByVal EntryString As String)
  Dim xPLPath As String
  Dim xCounter As Long
  Dim xBrkCnt As Long
  Dim xEStrLen As Long
  Dim xLong3 As Long

  #If UseFileLogging Then
    If EntryString = "1|" Then
      MainForm_ctConsoleA_AddLog "  (AIMP2 playlist)"
      Else
      MainForm_ctConsoleA_AddLog "  (AIMP3 playlist)"
      End If
    #End If
  xPLPath = SimpleDir(Filename)
  xEStrLen = Len(EntryString)
  Do
    If LCase(Left(xLine, xEStrLen)) = EntryString Then
      xLong3 = InStr(xEStrLen + 1&, xLine, "|")
      If xLong3 = 0& Then xLong3 = Len(xLine) + 1&
      If Not (xLong3 = xEStrLen + 1&) Then
        xLine = Mid(xLine, xEStrLen + 1&, xLong3 - xEStrLen - 1&)
        If IsPureFile(xLine, xPLPath) Then
          If Not xCounter = sCharA1Max Then
            If RemoveMissingOnPLLoad Then
              If AllowedItem(xLine, True) = 1& Then
                sCharA1(xCounter) = xLine
                xCounter = xCounter + 1&
                End If
              ElseIf AllowedItemSongFast(xLine, True) Then
              sCharA1(xCounter) = xLine
              xCounter = xCounter + 1&
              End If
            End If
          Else
          Call RadioForm_AddRadioEx(xLine, xLine, "", False)
          End If
        End If
      End If
    xBrkCnt = (xBrkCnt + 1&) Mod 64&
    If xBrkCnt = 0& Then
      Call DoEventsEx_SleepPeriodicalLW(0&)
      If AbortReading Then Exit Do
      End If
    Loop While TxtFile_ReadLine(hTextFileIn, xLine)
  Call TxtFile_ReadClose(hTextFileIn)
  GenCalaymStructure True, xCounter, xSorting
  End Sub

Public Sub SavePList_M3uGeneric(ByRef hTxtFileOut As Long)
  Dim xLong1 As Long

  For xLong1 = 0& To PLCount - 1&
    If (PLI(xLong1).DirDepthFlags And PLI_IsAuto) = 0& Then
      If Not (PLI(xLong1).DirDepthFlags And PLI_IsDir) = PLI_IsDir Then
        Call TxtFile_WriteLine(hTxtFileOut, PLI(xLong1).Filename)
        End If
      End If
    Next
  For xLong1 = 0& To xRadioCount - 1&
    Call TxtFile_WriteLine(hTxtFileOut, xRadioURL(xLong1))
    Next
  End Sub

Public Function SavePList_PlsAap(ByVal Filename As String, ByVal EntryString As String, ByVal ApolloAap As Boolean) As Boolean ', ByVal UseUTF8 As Boolean) as boolean
  Dim hTxtFileOut As Long
  Dim xLong1 As Long
  Dim xLong2 As Long
  
  #If UseFileLogging Then
    Dim xSuccess As Boolean
    If ApolloAap Then
      MainForm_ctConsoleA_AddLog "Saving playlist (Apollo aap ansi): " & Filename
      Else
      MainForm_ctConsoleA_AddLog "Saving playlist (Generic pls ansi): " & Filename
      End If
    #End If
    
  'If UseUTF8 Then
  '  hTxtFileOut = TxtFile_WriteCreateEx(Filename, CP_UTF8, True)
  '  Else
    hTxtFileOut = TxtFile_WriteCreateEx(Filename, CP_ACP, False)
  '  End If
  If Not hTxtFileOut = 0& Then
    If ApolloAap Then
      Call TxtFile_WriteLine(hTxtFileOut, "[Apollo Advanced Playlist]")
      Call TxtFile_WriteLine(hTxtFileOut, "Version=1.00")
      Call TxtFile_WriteLine(hTxtFileOut, "[Entries]")
      Else
      Call TxtFile_WriteLine(hTxtFileOut, "[playlist]")
      End If
    For xLong1 = 0& To PLCount - 1&
      If (PLI(xLong1).DirDepthFlags And PLI_IsAuto) = 0& Then
        If Not (PLI(xLong1).DirDepthFlags And PLI_IsDir) = PLI_IsDir Then
          xLong2 = xLong2 + 1&
          Call TxtFile_WriteLine(hTxtFileOut, EntryString + CStr(xLong2) + "=" + PLI(xLong1).Filename)
          End If
        End If
      Next
    For xLong1 = 0& To xRadioCount - 1&
      Call TxtFile_WriteLine(hTxtFileOut, EntryString + CStr(xLong2) + "=" + xRadioURL(xLong1))
      Next
    Call TxtFile_WriteLine(hTxtFileOut, "NumberOfEntries=" + CStr(xLong2 + xRadioCount))
    If Not ApolloAap Then
      Call TxtFile_WriteLine(hTxtFileOut, "Version=2")
      End If
    Call TxtFile_WriteClose(hTxtFileOut)
    SavePList_PlsAap = True
#If UseFileLogging Then
    Else
    MainForm_ctConsoleA_AddLog "  failed"
#End If
    End If
  End Function

Public Function SavePList_Wpl(ByVal Filename As String) As Boolean  ', ByVal UseUTF8 As Boolean) as boolean
  Dim hTxtFileOut As Long
  Dim xLong1 As Long
  Dim xLong2 As Long
  
  #If UseFileLogging Then
    Dim xSuccess As Boolean
    MainForm_ctConsoleA_AddLog "Saving playlist (wpl utf8): " & Filename
    #End If
    
  'If UseUTF8 Then
    hTxtFileOut = TxtFile_WriteCreateEx(Filename, CP_UTF8, False)
  '  Else
  '  hTxtFileOut = TxtFile_WriteCreateEx(Filename, CP_ACP, False)
  '  End If
  If Not hTxtFileOut = 0& Then
    For xLong1 = 0& To PLCount - 1&
      If (PLI(xLong1).DirDepthFlags And PLI_IsAuto) = 0& Then
        If Not (PLI(xLong1).DirDepthFlags And PLI_IsDir) = PLI_IsDir Then
          xLong2 = xLong2 + 1&
          End If
        End If
      Next
    
    Call TxtFile_WriteLine(hTxtFileOut, "<?wpl version=" + Chr(34) + "1.0" + Chr(34) + "?>")
    Call TxtFile_WriteLine(hTxtFileOut, "<smil>")
    Call TxtFile_WriteLine(hTxtFileOut, "    <head>")
    Call TxtFile_WriteLine(hTxtFileOut, "        <meta name=" + Chr(34) + "Generator" + Chr(34) + " content=" + Chr(34) + "Calaym" + Chr(34) + "/>")
    Call TxtFile_WriteLine(hTxtFileOut, "        <meta name=" + Chr(34) + "ItemCount" + Chr(34) + " content=" + Chr(34) + CStr(xLong2 + xRadioCount) + Chr(34) + "/>")
    'Call TxtFile_WriteLine(hTxtFileOut, "        <title>" + getplaylisttitle(Filename) + "</title>")
    Call TxtFile_WriteLine(hTxtFileOut, "    </head>")
    Call TxtFile_WriteLine(hTxtFileOut, "    <body>")
    Call TxtFile_WriteLine(hTxtFileOut, "        <seq>")
    For xLong1 = 0& To PLCount - 1&
      If (PLI(xLong1).DirDepthFlags And PLI_IsAuto) = 0& Then
        If Not (PLI(xLong1).DirDepthFlags And PLI_IsDir) = PLI_IsDir Then
          Call TxtFile_WriteLine(hTxtFileOut, "            <media src=" + Chr(34) + PLI(xLong1).Filename + Chr(34) + "/>")
          End If
        End If
      Next
    For xLong1 = 0& To xRadioCount - 1&
      Call TxtFile_WriteLine(hTxtFileOut, "            <media src=" + Chr(34) + xRadioURL(xLong1) + Chr(34) + "/>")
      Next
    Call TxtFile_WriteLine(hTxtFileOut, "        </seq>")
    Call TxtFile_WriteLine(hTxtFileOut, "    </body>")
    Call TxtFile_WriteLine(hTxtFileOut, "</smil>")
    Call TxtFile_WriteClose(hTxtFileOut)
    SavePList_Wpl = True
#If UseFileLogging Then
    Else
    MainForm_ctConsoleA_AddLog "  failed"
#End If
    End If
  End Function

Public Function SavePList_Xspf(ByVal Filename As String) As Boolean
  Dim hTxtFileOut As Long
  Dim xLong1 As Long
  
  #If UseFileLogging Then
    Dim xSuccess As Boolean
    MainForm_ctConsoleA_AddLog "Saving playlist (xspf utf8): " & Filename
    #End If
    
  'If UseUTF8 Then
    hTxtFileOut = TxtFile_WriteCreateEx(Filename, CP_UTF8, True)
  '  Else
  '  hTxtFileOut = TxtFile_WriteCreateEx(Filename, CP_ACP, False)
  '  End If
  If Not hTxtFileOut = 0& Then
    Call TxtFile_WriteLine(hTxtFileOut, "<?xml version=" + Chr(34) + "1.0" + Chr(34) + " encoding=" + Chr(34) + "UTF-8" + Chr(34) + "?>")
    Call TxtFile_WriteLine(hTxtFileOut, "<playlist version=" + Chr(34) + "1" + Chr(34) + " xmlns=" + Chr(34) + "http://xspf.org/ns/0/" + Chr(34) + ">")
    Call TxtFile_WriteLine(hTxtFileOut, "  <trackList>")
    For xLong1 = 0& To PLCount - 1&
      If (PLI(xLong1).DirDepthFlags And PLI_IsAuto) = 0& Then
        If Not (PLI(xLong1).DirDepthFlags And PLI_IsDir) = PLI_IsDir Then
          Call TxtFile_WriteLine(hTxtFileOut, "    <track>")
          If Left(PLI(xLong1).Filename, 2&) = "\\" Then
            Call TxtFile_WriteLine(hTxtFileOut, "      <location>file:" + URLEncode(Replace(PLI(xLong1).Filename, "\", "/"), ":/") + "</location>")
            Else
            Call TxtFile_WriteLine(hTxtFileOut, "      <location>file:///" + URLEncode(Replace(PLI(xLong1).Filename, "\", "/"), ":/") + "</location>")
            End If
          Call TxtFile_WriteLine(hTxtFileOut, "    </track>")
          End If
        End If
      Next
    For xLong1 = 0& To xRadioCount - 1&
      Call TxtFile_WriteLine(hTxtFileOut, "    <track>")
      Call TxtFile_WriteLine(hTxtFileOut, "      <location>" + xRadioURL(xLong1) + "</location>")
      Call TxtFile_WriteLine(hTxtFileOut, "    </track>")
      Next
    Call TxtFile_WriteLine(hTxtFileOut, "  </trackList>")
    Call TxtFile_WriteLine(hTxtFileOut, "</playlist>")
    Call TxtFile_WriteClose(hTxtFileOut)
    SavePList_Xspf = True
#If UseFileLogging Then
    Else
    MainForm_ctConsoleA_AddLog "  failed"
#End If
    End If
  End Function

Public Function SavePList_AIMP(ByVal Filename As String, ByVal Header As String, ByVal EntryString As String) As Boolean  ', ByVal UseUTF8 As Boolean) as boolean
  Dim hTxtFileOut As Long
  Dim xLong1 As Long
  Dim xLong2 As Long
  
  #If UseFileLogging Then
    Dim xSuccess As Boolean
    If EntryString = "1|" Then
      MainForm_ctConsoleA_AddLog "Saving playlist (AIMP2): " & Filename
      Else
      MainForm_ctConsoleA_AddLog "Saving playlist (AIMP3): " & Filename
      End If
    #End If
    
  'If UseUTF8 Then
  '  hTxtFileOut = TxtFile_WriteCreateEx(Filename, CP_UTF8, True)
  '  Else
    hTxtFileOut = TxtFile_WriteCreateEx(Filename, CP_WINUNICODE, True)
  '  End If
  If Not hTxtFileOut = 0& Then
    Call TxtFile_WriteLine(hTxtFileOut, Header)
    For xLong1 = 0& To PLCount - 1&
      If (PLI(xLong1).DirDepthFlags And PLI_IsAuto) = 0& Then
        If Not (PLI(xLong1).DirDepthFlags And PLI_IsDir) = PLI_IsDir Then
          xLong2 = xLong2 + 1&
          Call TxtFile_WriteLine(hTxtFileOut, EntryString + PLI(xLong1).Filename)
          End If
        End If
      Next
    For xLong1 = 0& To xRadioCount - 1&
      xLong2 = xLong2 + 1&
      Call TxtFile_WriteLine(hTxtFileOut, EntryString + Replace(xRadioURL(xLong1), "|", "_"))
      Next
    Call TxtFile_WriteClose(hTxtFileOut)
    SavePList_AIMP = True
#If UseFileLogging Then
    Else
    MainForm_ctConsoleA_AddLog "  failed"
#End If
    End If
  End Function

