' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
' This file can be replaced  in one of the future versions,
' so please if you want to modify it, make  a copy, do your
' modifications  in that copy and  change Scripts.ini  file 
' appropriately. 
' If you do not do this, you will lose  all your changes in
' this script when you install a new version of MediaMonkey
' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
' MediaMonkey statistics script
' This script was adapted by TheRocket from the 
' MediaMonkey Web Extension (MMWBE) also made by myself.
' Coded in December 2004 - January 2005.
' Thanks to Rusty for his suggestions and letting me
' include this script into the next versions!
' It shows globaly the songs you have in your MediaMonkey,
' and what you listen often. It can be a great way to
' find what type of music a person likes.
' Send us new statistics ideas in the MediaMonkey Forum!
' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Option Explicit

Public booStyleOn

Const intTopCount = 10
Const mmAnchorRight = 4
Const mmAnchorBottom = 8
Const mmAlignTop = 1
Const mmAlignBottom = 2
Const mmAlignClient = 5
Const mmListDropdown = 2
Const mmFormScreenCenter = 4

'Set English - United States system locale.
SetLocale("en-us")

Sub ShowStats()
Dim UI
Dim Form
Dim Foot
Dim Btn
Dim Btn2
Dim WB
Dim doc
Dim DlgWidth

  Set UI = SDB.UI

  DlgWidth = 500

  ' Create the window to be shown
  Set Form = UI.NewForm
  Form.Common.SetRect 50, 50, DlgWidth, 400
  Form.Common.MinWidth = 200
  Form.Common.MinHeight = 150
  Form.FormPosition = mmFormScreenCenter
  Form.Caption = SDB.Localize("MediaMonkey Music Library Statistics")
  Form.StayOnTop = True

  ' Create a panel at the bottom of the window
  Set Foot = UI.NewPanel(Form)
  Foot.Common.Align = mmAlignBottom
  Foot.Common.Height = 35

  ' Create a button that saves the report
  Set Btn2 = UI.NewButton(Foot)
  Btn2.Caption = SDB.Localize("&Save as...")
  Btn2.Common.SetRect DlgWidth - 261, 5, 150, 25
  'Btn2.Common.Hint = SDB.Localize("Save this report")
  Btn2.Common.Anchors = mmAnchorRight + mmAnchorBottom
  Btn2.UseScript = Script.ScriptPath
  Btn2.OnClickFunc = "SaveAs"

  ' Create a button that closes the window
  Set Btn = UI.NewButton(Foot)
  Btn.Caption = SDB.Localize("&Close")
  Btn.Common.SetRect DlgWidth - 106, 5, 85, 25
  'Btn.Common.Hint = SDB.Localize("Close this report")
  Btn.Common.Anchors = mmAnchorRight + mmAnchorBottom
  Btn.Cancel = True
  Btn.UseScript = Script.ScriptPath
  Btn.OnClickFunc = "OnClose"
   
  ' Create a web browser component
  Set WB = UI.NewActiveX(Form, "Shell.Explorer")

  ' process background threads
  SDB.ProcessMessages

  WB.Common.Align = mmAlignClient      ' Fill all client rectangle
  WB.Common.ControlName = "WB"

  Form.SavePositionName = "StatisticsWindow"
  Form.Common.Visible = True                ' Only show the form, don't wait for user input
  SDB.Objects("Statistics") = Form  ' Save reference to the form somewhere, otherwise it would simply disappear
  WB.SetHTMLDocument( BuildReport(false))

  ' process background threads
  SDB.ProcessMessages

End Sub

Sub OnClose(Btn)
  SDB.Objects("Statistics") = Nothing ' Remove the last reference to our form which also causes it to disappear
End Sub

Function Style()
  booStyleOn = Not booStyleOn
  If booStyleOn Then
    Style = ""
  Else
    Style = " class=""Dark"""
  End If
End Function

Public Function FormatFileSize(intFileLength)
Dim strSize
    strSize = SDB.Localize("Bytes")
    If intFileLength >= 1024 Then
      intFileLength = intFileLength / 1024
      strSize = SDB.Localize("KB")
    End If
    If intFileLength >= 1024 Then
      intFileLength = intFileLength / 1024
      strSize = SDB.Localize("MB")
    End If
    If intFileLength >= 1024 Then
      intFileLength = intFileLength / 1024
      strSize = SDB.Localize("GB")
    End If
    If intFileLength >= 1024 Then
      intFileLength = intFileLength / 1024
      strSize = SDB.Localize("TB")
    End If
    strSize = " " & strSize
    If intFileLength < 10 Then
      FormatFileSize = FormatNumber(intFileLength,2)&strSize
    Else
      If intFileLength < 100 Then
        FormatFileSize = FormatNumber(intFileLength,1)&strSize
      Else
        FormatFileSize = FormatNumber(intFileLength,0)&strSize
      End If
    End If
End Function

Public Function FormatTime(intLength)
  Dim strLength, intLengthHeures, intLengthMinutes, intLengthSecondes, datLength
  Dim strTimeSeparator
  'Find out the current time separator (for some locales, it is a period)
  datLength = TimeSerial(11, 11, 11)
  strLength = FormatDateTime(datLength,vbshorttime)
  strTimeSeparator = left(replace(strLength,"1",""),1)

  intLength = CCur(intLength / 1000)
  intLengthHeures = Int((intLength / 60) / 60)
  intLengthMinutes = Int((intLength / 60) Mod 60)
  intLengthSecondes = Int(intLength Mod 60)

  strLength = intLengthHeures & strTimeSeparator
  if intLengthMinutes < 10 then strLength = strLength & "0"
  strLength = strLength & intLengthMinutes & strTimeSeparator

  if intLengthSecondes < 10 then strLength = strLength & "0"
  strLength = strLength & intLengthSecondes

  FormatTime = strLength
End Function

 ' escape XML string
Function MapXML(srcstring)
  srcstring = Replace(srcstring, "&", "&amp;")
  srcstring = Replace(srcstring, "<", "&lt;")
  srcstring = Replace(srcstring, ">", "&gt;")
  Dim i
  i=1
  While i<=Len(srcstring)
    ' process background threads
    SDB.ProcessMessages

    If (AscW(Mid(srcstring, i, 1))>127) Then
      srcstring = Mid( srcstring, 1, i-1)+"&#"+CStr( AscW( Mid( srcstring, i, 1)))+";"+Mid( srcstring, i+1, Len(srcstring))
    End If
    i=i+1
  WEnd
  If srcstring="" Then
    srcstring = "&nbsp;"
  End IF
  MapXML = srcstring
End Function


Function ExtractText(ByVal inText, ByVal inDebut, ByVal inFin)
    Dim pos1
    Dim pos2

    pos1 = InStr(1, inText, inDebut)
    If pos1 = 0 Then pos1 = 1 Else pos1 = pos1 + Len(inDebut)
    pos2 = InStr(pos1, inText, inFin)
    If pos2 < pos1 Then pos2 = Len(inText) + 1
    ExtractText = Mid(inText, pos1, pos2 - pos1)
    
End Function

Function ExtractTextInvert(ByVal inText, ByVal inDebut, ByVal inFin)
    ExtractTextInvert = StrReverse(ExtractText(StrReverse(inText), StrReverse(inDebut), StrReverse(inFin)))
End Function

function ExtractPathName(strPath)
  dim StrTemp
  StrTemp= ExtractTextInvert(strPath,"","\")
  ExtractPathName = Left(strPath, Len(strPath) - Len(StrTemp))
end function

Function ShowRating(intNo, booForExport)
Dim a
  If intNo = -1 Then
    ShowRating = " "
  ElseIf intNo = 0 Then
    if not booForExport then
      ShowRating = "<img src=""" & ExtractPathName(script.scriptpath) & "\bomb.png"" border=""0"" width=""10"" height=""11"">"
    else
      ShowRating = "0"
    end if
  Else
'    ShowRating = round(intNo / 10) / 2
    For a = 20 To (intNo + 4) Step 20
      ' process background threads
      SDB.ProcessMessages
      if not booForExport then
        ShowRating = ShowRating & "<img src=""" & ExtractPathName(script.scriptpath) & "\star.png"" width=""10"" height=""11"" border=""0"">"
      else
        ShowRating = ShowRating & "*"
      end if
    Next
  End If
  If ((intNo + 4)  Mod 20) >= 10 Then
    if not booForExport then
      ShowRating = ShowRating & "<img src=""" & ExtractPathName(script.scriptpath) & "\half-star.png"" width=""10"" height=""11"" border=""0"">"
    else
      ShowRating = ShowRating & "&quot;"
    end if
  End If
End Function

function NoNull(VarCanBeNull, varWhenNull)
  if IsNull (VarCanBeNull) Then
    NoNull = varWhenNull
  else
    if IsNumeric (VarCanBeNull) Then
      NoNull = VarCanBeNull
    else
      if VarType (VarCanBeNull) = vbString Then
        if Len (VarCanBeNull) > 0 Then
          NoNull = VarCanBeNull
        else
          NoNull = varWhenNull
        end if
      else
        NoNull = varWhenNull
      end if
    end if
  end if
end function

Sub SaveAS(Btn)
  Dim strExportTo
  Dim booSave
  Dim fout 
  Dim fso

  With SDB.CommonDialog
    .DefaultExt = "html"
    '.FileName = SDB.Localize("Save AS...")
    .Filter = "HTML (*.htm)|*.htm|All files (*.*)|*.*"
    .Title = SDB.Localize("Exporting...")
    .InitDir = SDB.IniFile.StringValue("Scripts", "LastExportStatsDir")
    .ShowSave
    booSave = .Ok
    strExportTo = .FileName
  End With

  if booSave then
    ' Connect to the FileSystemObject
    Set fso = SDB.Tools.FileSystem

    ' Create the output file 
    Set fout = fso.CreateTextFile(strExportTo, True) 

    ' Write header line 
    fout.Write BuildReport(true) 
    ' Close the output file and finish 
    fout.Close 
    
    set fout = nothing
    set fso = nothing

  end if

end sub

Function BuildReport(booForExport)
  Dim qryStats 
  Dim strSQL
  Dim intArtistsCount
  Dim intArtistsCountPlayed
  Dim intAlbumCount
  Dim intAlbumsCountPlayed
  Dim intGenreCount
  Dim intGenreCountPlayed
  Dim intLength
  Dim intFileLength
  Dim intLengthPlayed
  Dim intFileLengthPlayed
  Dim intYearCount
  Dim intYearCountPlayed
  Dim intPlaylistCount
  Dim intPlaylistCountPlayed
  Dim intPlayed
  Dim intAllCount

  Dim strOut

  strOut = ""
    
  'Building base page
  strOut = strOut & "<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">" & vbcrlf
  strOut = strOut & "<html>" & vbcrlf
  strOut = strOut & "  <head>" & vbcrlf
  strOut = strOut & "    <title>" & SDB.Localize("MediaMonkey Music Library Statistics") & "</title>" & vbcrlf
  strOut = strOut & "  </head>" & vbcrlf

  strOut = strOut & "<STYLE TYPE=text/css>" & vbcrlf
  strOut = strOut & "body{font-family:'Verdana',sans-serif; background-color:#FFFFFF; font-size:9pt; color:#000000;}" & vbcrlf
  strOut = strOut & "H1{font-family:'Verdana',sans-serif; font-size:13pt; font-weight:bold; color:#AAAAAA; text-align:left}" & vbcrlf
  strOut = strOut & "P{font-family:'Verdana',sans-serif; font-size:9pt; color:#000000;}" & vbcrlf
  strOut = strOut & "TH{font-family:'Verdana',sans-serif; font-size:10pt; font-weight:bold; color:#000000; border-color:#000000; border-style: solid; border-left-width:0px; border-right-width:0px; border-top-width:0px; border-bottom-width:3px;}" & vbcrlf
  strOut = strOut & "TD{font-family:'Verdana',sans-serif; font-size:9pt; color:#000000; border-color:#000000; border-style: solid; border-left-width:0px; border-right-width:0px; border-top-width:0px; border-bottom-width:1px;}" & vbcrlf
  strOut = strOut & "TR.dark{background-color:#EEEEEE}" & vbcrlf
  strOut = strOut & "TR.aleft TH{text-align:left}" & vbcrlf
  strOut = strOut & "</STYLE>" & vbcrlf

  strOut = strOut & "  <body>" & vbcrlf
  strOut = strOut & "    <H1>" & SDB.Localize("MediaMonkey Music Library Statistics") & "</H1>" & vbcrlf
  
  ' process background threads
  SDB.ProcessMessages
  
  'Totals
  strSQL = "SELECT Count(*) AS Nombre FROM Artists WHERE ID <> 0 AND Tracks>0"     ' Track artists only
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intArtistsCount = CLng(NoNull(qryStats.ValueByName("Nombre"),0))
  
  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count(Distinct Artists.ID) AS CountOfID FROM Artists WHERE Artists.ID IN ( SELECT ArtistsSongs.IDArtist FROM ArtistsSongs WHERE ArtistsSongs.PersonType = 1 AND ArtistsSongs.IDSong IN ( SELECT Played.IDSong FROM Played))"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intArtistsCountPlayed = CLng(NoNull(qryStats.ValueByName("CountOfID"),0))
  
  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count(*) AS Nombre FROM Albums WHERE Album<>'' AND Album<>' '"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intAlbumCount = CLng(NoNull(qryStats.ValueByName("Nombre"),0))
  
  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count(Distinct Albums.ID) AS CountOfID FROM Albums WHERE Albums.ID IN ( SELECT Songs.IDAlbum FROM Songs WHERE Songs.ID IN (SELECT Played.IDSong FROM Played))"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intAlbumsCountPlayed = CLng(NoNull(qryStats.ValueByName("CountOfID"),0))
  
  ' process background threads
  SDB.ProcessMessages
 
  strSQL = "SELECT Count(Genres.IDGenre) AS Nombre FROM Genres WHERE Genres.GenreName <> '' AND Genres.IDGenre IN (SELECT GenresSongs.IDGenre FROM GenresSongs)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intGenreCount = CLng(NoNull(qryStats.ValueByName("Nombre"),0))
  
  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count(Distinct Genres.IDGenre) AS CountOfID FROM Genres WHERE Genres.IDGenre IN (SELECT GenresSongs.IDGenre FROM GenresSongs WHERE GenresSongs.IDSong IN (SELECT Played.IDSong FROM Played))"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intGenreCountPlayed = CLng(NoNull(qryStats.ValueByName("CountOfID"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count(Distinct CAST((Songs.Year/10000) AS INTEGER)) AS Nombre FROM Songs WHERE Songs.Year > 0"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intYearCount = CLng(NoNull(qryStats.ValueByName("Nombre"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count(Distinct CAST((Songs.Year/10000) AS INTEGER)) AS CountOfID FROM Songs INNER JOIN Played ON Songs.ID = Played.IDSong WHERE Songs.Year > 0"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intYearCountPlayed = CLng(NoNull(qryStats.ValueByName("CountOfID"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count(*) AS Nombre FROM PlayLists WHERE (IsAutoPlaylist<>1 OR IsAutoPlaylist is null)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intPlaylistCount = CLng(NoNull(qryStats.ValueByName("Nombre"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count(Distinct PlayLists.IDPlaylist) AS CountOfID FROM "
  strSQL = strSQL & " PlayLists WHERE PlayLists.IDPlaylist "
  strSQL = strSQL & " IN (SELECT PlaylistSongs.IDPlaylist FROM PlaylistSongs WHERE PlaylistSongs.IDSong "
  strSQL = strSQL & " IN (SELECT Played.IDSong FROM Played)) "
  strSQL = strSQL & " AND (Playlists.IsAutoPlaylist<>1 OR IsAutoPlaylist is null)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intPlaylistCountPlayed = CLng(NoNull(qryStats.ValueByName("CountOfID"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count(Distinct Played.IDSong) AS Nombre FROM Played"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intPlayed = CLng(NoNull(qryStats.ValueByName("Nombre"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count(*) AS Nombre, Sum(Songs.SongLength) AS TotalLength, Sum(Songs.FileLength) AS TotalFileLength FROM Songs"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intAllCount = CLng(NoNull(qryStats.StringByName("Nombre"),0))
  intLength = CCur(NoNull(qryStats.ValueByName("TotalLength"),0))
  intFileLength = CCur(NoNull(qryStats.ValueByName("TotalFileLength"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Sum(Songs.SongLength) AS TotalLength, Sum(Songs.FileLength) AS TotalFileLength FROM Songs WHERE Songs.ID IN (SELECT Played.IdSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intLengthPlayed = CCur(NoNull(qryStats.ValueByName("TotalLength"),0))
  intFileLengthPlayed = CCur(NoNull(qryStats.ValueByName("TotalFileLength"),0))

  ' process background threads
  SDB.ProcessMessages

  strOut = strOut & "      <p/>" & vbcrlf
  strOut = strOut & "        <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  strOut = strOut & "          <tr><th colspan=""3"">" & SDB.Localize("Totals") & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr class=""aleft""><th>" & SDB.Localize("Type") & "</th><th>" & SDB.Localize("Library") & "</th><th>" & SDB.Localize("Played") & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Artists") & "</td><td>" & intArtistsCount & "</td><td>" & intArtistsCountPlayed & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Albums") & "</td><td>" & intAlbumCount & "</td><td>" & intAlbumsCountPlayed & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Genres") & "</td><td>" & intGenreCount & "</td><td>" & intGenreCountPlayed & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Years") & "</td><td>" & intYearCount & "</td><td>" & intYearCountPlayed & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Playlists") & "</td><td>" & intPlaylistCount & "</td><td>" & intPlaylistCountPlayed & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Tracks") & "</td><td>" & intAllCount & "</td><td>" & intPlayed & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Length") & " (h:mm:ss)</td><td>" & FormatTime(intLength) & "</td><td>" & FormatTime(intLengthPlayed) & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("File size") & "</td><td>" & FormatFileSize(intFileLength) & "</td><td>" & FormatFileSize(intFileLengthPlayed) & "</td></tr>" & vbcrlf
  'strOut = strOut & "          <tr><td colspan=""3"">* = " & SDB.Localize("Parts of item played") & "</td></tr>" & vbcrlf
  strOut = strOut & "        </table>" & vbcrlf
  strOut = strOut & "      <p/>" & vbcrlf
  
  ' process background threads
  SDB.ProcessMessages

  'Averages
  Dim intAvgYear
  Dim intAvgYearPlayed
  Dim intAvgBitrate
  Dim intAvgBitratePlayed
  Dim intAvgRating
  Dim intTracksPerAlbum
  Dim intTracksPerAlbumPlayed
  Dim intSongsPerGenre
  Dim intSongsPerGenrePlayed
  Dim intPlayPerDay
  Dim intPlayedRating
  Dim intSongsPerArtist
  Dim intSongsPerArtistPlayed
  Dim intSongsPerYear
  Dim intSongsPerYearPlayed
  'Dim intSongsPerRating
  'Dim intSongsPerRatingPlayed

  strSQL = "SELECT Avg(Distinct CAST((Songs.Year/10000) AS INTEGER)) AS avgYear FROM Songs WHERE Songs.Year > 0"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intAvgYear = CCur(NoNull(qryStats.ValueByName("avgYear"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Avg(Distinct Cast((Songs.Year/10000) AS Integer)) AS avgYearPlayed FROM Songs INNER JOIN Played ON Songs.ID = Played.IDSong WHERE Songs.Year > 0"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intAvgYearPlayed = CCur(NoNull(qryStats.ValueByName("avgYearPlayed"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Avg(SongLength) AS AvgLength, Avg(FileLength) AS AvgFileLength, Avg(Bitrate) AS AvgBitrate FROM Songs"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intLength = CCur(NoNull(qryStats.ValueByName("AvgLength"),0))
  intFileLength = CCur(NoNull(qryStats.ValueByName("AvgFileLength"),0))
  intAvgBitrate = CCur(NoNull(qryStats.ValueByName("AvgBitrate"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Avg(Songs.Bitrate) AS AvgBitratePlayed FROM Songs WHERE Songs.ID IN (SELECT Played.IDSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intAvgBitratePlayed = CCur(NoNull(qryStats.ValueByName("AvgBitratePlayed"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Avg(Songs.Rating) AS AvgRating FROM Songs WHERE Songs.Rating >= 0"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intAvgRating = CCur(NoNull(qryStats.ValueByName("AvgRating"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Avg(SongLength) AS AvgLength, Avg(FileLength) AS AvgFileLength FROM Songs INNER JOIN Played ON Songs.ID = Played.IdSong"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intLengthPlayed = CCur(NoNull(qryStats.ValueByName("AvgLength"),0))
  intFileLengthPlayed = CCur(NoNull(qryStats.ValueByName("AvgFileLength"),0))
  
  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count( Songs.ID) AS CountOfID FROM Songs WHERE (Songs.Album <> '') AND (Songs.Album NOTNULL)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  if intAlbumCount > 0 then
    intTracksPerAlbum = CCur(NoNull(qryStats.ValueByName("CountOfID"),0)) / intAlbumCount
  else
    intTracksPerAlbum = 0
  End If
  
  ' process background threads
  SDB.ProcessMessages
 
  strSQL = "SELECT Count( Songs.ID) AS CountOfID FROM Songs WHERE (Songs.Album <> '') AND (Songs.Album NOTNULL) AND Songs.IDAlbum IN "
  strSQL = strSQL & "(SELECT Albums.ID FROM Albums WHERE Albums.ID IN ( SELECT Songs2.IDAlbum FROM Songs AS Songs2 WHERE Songs2.ID IN (SELECT Played.IDSong FROM Played)))"
  
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  if intAlbumsCountPlayed > 0 then
    intTracksPerAlbumPlayed = CCur(NoNull(qryStats.ValueByName("CountOfID"),0)) / intAlbumsCountPlayed
  else  
    intTracksPerAlbumPlayed = 0
  end If

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Avg(CountOfID) AS AVGPlayed FROM (SELECT Count(Played.IdSong) AS CountOfID " 
  strSQL = strSQL & "FROM Played  "
  strSQL = strSQL & "GROUP BY Cast(Played.PlayDate AS Integer))"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intPlayPerDay = CCur(NoNull(qryStats.ValueByName("AVGPlayed"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Avg(Songs.Rating) AS AvgRatingPlayed FROM Songs WHERE Songs.Rating>0 AND PlayCounter>0"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intPlayedRating = CCur(NoNull(qryStats.ValueByName("AvgRatingPlayed"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count( GenresSongs.ID) AS CountOfID FROM GenresSongs"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  if intGenreCount > 0 then
    intSongsPerGenre = CCur(NoNull(qryStats.ValueByName("CountOfID"),0)) / intGenreCount
  else
    intSongsPerGenre = 0
  end If
  
  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count( GenresSongs.ID) AS CountOfID FROM GenresSongs WHERE GenresSongs.idGenre IN "
  strSQL = strSQL & "       (SELECT GenresSongs2.IDGenre FROM GenresSongs AS GenresSongs2 WHERE GenresSongs2.IDSong IN "
  strSQL = strSQL & "               (SELECT Played.IDSong FROM Played))"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  if intGenreCountPlayed > 0 then
    intSongsPerGenrePlayed = CCur(NoNull(qryStats.ValueByName("CountOfID"),0)) / intGenreCountPlayed
  else  
    intSongsPerGenrePlayed = 0
  end If  

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count( ArtistsSongs.ID) AS CountOfID FROM ArtistsSongs WHERE ArtistsSongs.PersonType = 1"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  if intArtistsCount > 0 then
    intSongsPerArtist = CCur(NoNull(qryStats.ValueByName("CountOfID"),0)) / intArtistsCount
  else
    intSongsPerArtist = 0
  end If  

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Count( ArtistsSongs.ID) AS CountOfID FROM ArtistsSongs WHERE ArtistsSongs.PersonType = 1 AND ArtistsSongs.idArtist IN " 
  strSQL = strSQL & "       (SELECT ArtistsSongs2.IDArtist FROM ArtistsSongs AS ArtistsSongs2 WHERE ArtistsSongs2.IDSong IN "
  strSQL = strSQL & "               (SELECT Played.IDSong FROM Played))"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  if intArtistsCountPlayed > 0 then
    intSongsPerArtistPlayed = CCur(NoNull(qryStats.ValueByName("CountOfID"),0)) / intArtistsCountPlayed
  else
    intSongsPerArtistPlayed = 0
  end If  

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Avg(CountOfID) AS AVGYear FROM ("
  strSQL = strSQL & "SELECT Count(Songs.ID) AS CountOfID "
  'strSQL = strSQL & "FROM Songs "
  strSQL = strSQL & "FROM Songs WHERE Songs.Year <> -1 "
  strSQL = strSQL & "GROUP BY Songs.Year)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intSongsPerYear = CCur(NoNull(qryStats.ValueByName("AVGYear"),0))

  ' process background threads
  SDB.ProcessMessages

  strSQL = "SELECT Avg(CountOfID) AS AVGYearPlayed FROM ("
  strSQL = strSQL & "SELECT Count(Songs.ID) AS CountOfID "
  strSQL = strSQL & "FROM Songs WHERE Songs.ID IN (SELECT Played.IDSong FROM Played) AND Songs.Year <> -1 "
  strSQL = strSQL & "GROUP BY Songs.Year)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  intSongsPerYearPlayed = CCur(NoNull(qryStats.ValueByName("AVGYearPlayed"),0))

  'strSQL = "SELECT Avg(CountOfID) AS AVGTracksRating FROM ("
  'strSQL = strSQL & "SELECT Count(Songs.ID) AS CountOfID "
  'strSQL = strSQL & "FROM Songs WHERE Songs.Rating>0 "
  'strSQL = strSQL & "GROUP BY Songs.Rating)"
  'Set qryStats = SDB.Database.OpenSQL(strSQL)
  'intSongsPerRating = CCur(NoNull(qryStats.ValueByName("AVGTracksRating"),0))

  'strSQL = "SELECT Avg(CountOfID) AS AVGTracksRatingPlayed FROM ("
  'strSQL = strSQL & "SELECT Count(Songs.ID) AS CountOfID "
  'strSQL = strSQL & "FROM Songs INNER JOIN Played ON Songs.ID = Played.IDSong WHERE Songs.Rating>0 "
  'strSQL = strSQL & "GROUP BY Songs.Rating)"
  'Set qryStats = SDB.Database.OpenSQL(strSQL)
  'intSongsPerRatingPlayed = CCur(NoNull(qryStats.ValueByName("AVGTracksRatingPlayed"),0))

  ' process background threads
  SDB.ProcessMessages

  strOut = strOut & "        <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  strOut = strOut & "          <tr><th colspan=""3"">" & SDB.Localize("Averages") & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr class=""aleft""><th>" & SDB.Localize("Type") & "</th><th>" & SDB.Localize("Library") & "</th><th>" & SDB.Localize("Played") & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Tracks per Artist") & "</td><td>" & Round(intSongsPerArtist, 1) & "</td><td>" & Round(intSongsPerArtistPlayed, 1) & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Tracks per Album") & "</td><td>" & Round(intTracksPerAlbum, 1) & "</td><td>" & Round(intTracksPerAlbumPlayed, 1) & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Tracks per Genre") & "</td><td>" & Round(intSongsPerGenre, 1) & "</td><td>" & Round(intSongsPerGenrePlayed, 1) & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Tracks per Year") & "</td><td>" & Round(intSongsPerYear, 1) & "</td><td>" & Round(intSongsPerYearPlayed, 1) & "</td></tr>" & vbcrlf
  'strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Tracks per Rating") & "</td><td>" & Round(intSongsPerRating, 1) & "</td><td>" & Round(intSongsPerRatingPlayed, 1) & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Bitrate (kbps)") & "</td><td>" & Round(intAvgBitrate/1000) & "</td><td>" & Round(intAvgBitratePlayed/1000) & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Year") & "</td><td>" & Round(intAvgYear) & "</td><td>" & Round(intAvgYearPlayed) & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Tracks played per day") & "</td><td>-</td><td>" & Round(intPlayPerDay, 1) & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Rating") & "</td><td>" & ShowRating(Round(intAvgRating),booForExport) & "</td><td>" & ShowRating(Round(intPlayedRating),booForExport) & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("Length") & " (h:mm:ss)</td><td>" & FormatTime(intLength) & "</td><td>" & FormatTime(intLengthPlayed) & "</td></tr>" & vbcrlf
  strOut = strOut & "          <tr" & Style & "><td>" & SDB.Localize("File size") & "</td><td>" & FormatFileSize(intFileLength) & "</td><td>" & FormatFileSize(intFileLengthPlayed) & "</td></tr>" & vbcrlf
  strOut = strOut & "        </table>" & vbcrlf
  strOut = strOut & "      <p/>" & vbcrlf

  ' process background threads
  SDB.ProcessMessages

  'Top 10 Artists
  strOut = strOut & "        <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  strOut = strOut & "          <tr><th colspan=""4"">" & SDB.LocalizedFormat("Top %d Artists", intTopCount, 0, 0) & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr class=""aleft"">" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Tracks") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Artist") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Length") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("File size") & "</th>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
  
  strSQL = "SELECT Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength, Artists.Artist "
  strSQL = strSQL &  "FROM ArtistsSongs, Songs, Artists "
  strSQL = strSQL &  "WHERE ArtistsSongs.PersonType = 1 AND Songs.ID = ArtistsSongs.IDSong AND ArtistsSongs.IDArtist = Artists.ID "
  strSQL = strSQL &  "GROUP BY ArtistsSongs.IDArtist "
  strSQL = strSQL &  "ORDER BY Count(Songs.ID) DESC LIMIT " & intTopCount & ""  
  
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  While Not qryStats.EOF

  ' process background threadsE
  SDB.ProcessMessages

  strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
  strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & MapXML(qryStats.StringByName("Artist")) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
    qryStats.Next
  Wend
  strOut = strOut & "        </table>" & vbcrlf
  strOut = strOut & "      <p/>" & vbcrlf
  
  ' process background threads
  SDB.ProcessMessages

  'Top 10 Artists Played
  strOut = strOut & "        <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  strOut = strOut & "          <tr><th colspan=""4"">" & SDB.LocalizedFormat("Top %d Artists played", intTopCount, 0, 0) & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr class=""aleft"">" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Tracks") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Artist") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Length") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("File size") & "</th>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
   
  strSQL = "SELECT Sum(PlayCounter) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength, Artists.Artist "
  strSQL = strSQL &  "FROM ArtistsSongs, Songs, Artists "
  strSQL = strSQL &  "WHERE ArtistsSongs.PersonType = 1 AND Songs.ID = ArtistsSongs.IDSong AND Songs.ID IN (SELECT Played.IDSong FROM Played) AND ArtistsSongs.IDArtist = Artists.ID "
  strSQL = strSQL &  "GROUP BY ArtistsSongs.IDArtist "
  strSQL = strSQL &  "ORDER BY Sum(PlayCounter) DESC LIMIT " & intTopCount & "" 

  Set qryStats = SDB.Database.OpenSQL(strSQL)
  While Not qryStats.EOF

  ' process background threads
  SDB.ProcessMessages

  strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
  strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & MapXML(qryStats.StringByName("Artist")) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
    qryStats.Next
  Wend
  strOut = strOut & "        </table>" & vbcrlf
  strOut = strOut & "      <p/>" & vbcrlf
 
  'Top 10 Albums
  strOut = strOut & "        <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  strOut = strOut & "          <tr><th colspan=""4"">" & SDB.LocalizedFormat("Top %d Albums", intTopCount, 0, 0) & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr class=""aleft"">" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Rating") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Album") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Length") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("File size") & "</th>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
  
  strSQL = "SELECT Songs.AlbumArtist AS Artist, Albums.Album AS Album, Avg( Songs.Rating) AS Rating, Sum(Songs.SongLength) AS TotalLength, Sum(Songs.FileLength) AS TotalFileLength "
  strSQL = strSQL & "FROM Songs, Albums "
  strSQL = strSQL & "WHERE Albums.ID <> 0 AND Albums.Album <> '' AND Albums.ID = Songs.IDAlbum "
  strSQL = strSQL & "GROUP BY Songs.IDAlbum, Albums.Album "
  strSQL = strSQL & "ORDER BY Rating Desc, TotalLength Desc Limit " & intTopCount & "" 
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  While Not qryStats.EOF
  
' process background threads
  SDB.ProcessMessages

  strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
  strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & MapXML(qryStats.StringByName("Artist")) & " - " & MapXML(qryStats.StringByName("Album")) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
    qryStats.Next
  Wend
  strOut = strOut & "        </table>" & vbcrlf
  strOut = strOut & "      <p/>" & vbcrlf

  'Top 10 Albums played
  strOut = strOut & "        <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  strOut = strOut & "          <tr><th colspan=""4"">" & SDB.LocalizedFormat("Top %d Albums played", intTopCount, 0, 0) & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr class=""aleft"">" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Tracks") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Album") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Length") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("File size") & "</th>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
  
  strSQL = "SELECT Songs.AlbumArtist AS Artist, Albums.Album AS Album, Sum( PlayCounter) AS CountOfID, Sum(Songs.SongLength) AS TotalLength, Sum(Songs.FileLength) AS TotalFileLength "
  strSQL = strSQL & "FROM Songs, Albums "
  strSQL = strSQL & "WHERE Albums.ID <> 0 AND Albums.Album <> '' AND Albums.ID = Songs.IDAlbum AND "
  strSQL = strSQL & "Songs.ID IN (SELECT Played.IDSong FROM Played) "
  strSQL = strSQL & "GROUP BY Songs.IDAlbum, Albums.Album "
  strSQL = strSQL & "ORDER BY Sum( PlayCounter) Desc Limit " & intTopCount & "" 
  
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  While Not qryStats.EOF

  ' process background threads
  SDB.ProcessMessages

  strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
  strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & MapXML(qryStats.StringByName("Artist")) & " - " & MapXML(qryStats.StringByName("Album")) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
    qryStats.Next
  Wend
  strOut = strOut & "        </table>" & vbcrlf
  strOut = strOut & "      <p/>" & vbcrlf
  
  ' process background threads
  SDB.ProcessMessages

  'Top 10 Genres
  strOut = strOut & "        <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  strOut = strOut & "          <tr><th colspan=""4"">" & SDB.LocalizedFormat("Top %d Genres", intTopCount, 0, 0) & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr class=""aleft"">" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Tracks") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Genre") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Length") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("File size") & "</th>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
  
  strSQL = "SELECT Count(Songs.ID) AS CountOfID, Sum(Songs.SongLength) AS TotalLength, Sum(Songs.FileLength) AS TotalFileLength, Genres.GenreName FROM GenresSongs, Songs, Genres WHERE Songs.ID = GenresSongs.IDSong AND GenresSongs.IDGenre = Genres.IDGenre GROUP BY GenresSongs.IDGenre ORDER BY Count(Songs.ID) DESC LIMIT " & intTopCount & ""
  
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  While Not qryStats.EOF

  ' process background threads
  SDB.ProcessMessages

  strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
  strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & MapXML(qryStats.StringByName("GenreName")) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
    qryStats.Next
  Wend
  strOut = strOut & "        </table>" & vbcrlf
  strOut = strOut & "      <p/>" & vbcrlf
  
  ' process background threads
  SDB.ProcessMessages

  'Top 10 genres played
  strOut = strOut & "        <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  strOut = strOut & "          <tr><th colspan=""4"">" & SDB.LocalizedFormat("Top %d Genres played", intTopCount, 0, 0) & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr class=""aleft"">" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Tracks") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Genre") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Length") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("File size") & "</th>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
  
  strSQL = "SELECT Count(Songs.ID) AS CountOfID, Sum(Songs.SongLength) AS TotalLength, Sum(Songs.FileLength) AS TotalFileLength, Genres.GenreName FROM GenresSongs, Songs, Genres WHERE Songs.ID = GenresSongs.IDSong AND Songs.ID IN (SELECT Played.IDSong FROM Played) AND GenresSongs.IDGenre = Genres.IDGenre GROUP BY GenresSongs.IDGenre ORDER BY Count(Songs.ID) DESC LIMIT " & intTopCount & ""
  
  Set qryStats = SDB.Database.OpenSQL(strSQL)
  While Not qryStats.EOF

  ' process background threads
  SDB.ProcessMessages

  strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
  strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & MapXML(qryStats.StringByName("GenreName")) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf
    qryStats.Next
  Wend
  strOut = strOut & "        </table>" & vbcrlf
  strOut = strOut & "      <p/>" & VbCrLf

  ' process background threads
  SDB.ProcessMessages

  'ratings
  strOut = strOut & "        <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  strOut = strOut & "          <tr><th colspan=""4"">" & SDB.Localize("Ratings") & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr class=""aleft"">" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Tracks") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Rating") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Length") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("File size") & "</th>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf

  '96 - 100 ratings
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 96) AND (Songs.Rating <= 100)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '86 - 95 ratings
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 86) AND (Songs.Rating <= 95)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '76 - 85 ratings
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 76) AND (Songs.Rating <= 85)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '66 - 75 ratings
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 66) AND (Songs.Rating <= 75)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '56 - 65 ratings
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 56) AND (Songs.Rating <= 65)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '46 - 55 ratings
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 46) AND (Songs.Rating <= 55)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '36 - 45 ratings
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 36) AND (Songs.Rating <= 45)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '26 - 35 ratings
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 26) AND (Songs.Rating <= 35)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '16 - 25 ratings
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 16) AND (Songs.Rating <= 25)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '6 - 15 ratings
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 6) AND (Songs.Rating <= 15)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '0 ratings
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE Songs.Rating = 0"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  strOut = strOut & "        </table>" & vbcrlf
  strOut = strOut & "      <p/>" & vbcrlf

  'rating played
  strOut = strOut & "        <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  strOut = strOut & "          <tr><th colspan=""4"">" & SDB.Localize("Ratings played") & "</th></tr>" & vbcrlf
  strOut = strOut & "          <tr class=""aleft"">" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Tracks") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Rating") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("Length") & "</th>" & vbcrlf
  strOut = strOut & "            <th>" & SDB.Localize("File size") & "</th>" & vbcrlf
  strOut = strOut & "          </tr>" & vbcrlf

  '96 - 100 ratings played
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 96) AND (Songs.Rating <= 100) AND Songs.ID IN (SELECT Played.IDSong FROM Played)"  
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '86 - 95 ratings played
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 86) AND (Songs.Rating <= 95) AND Songs.ID IN (SELECT Played.IDSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '76 - 85 ratings played
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 76) AND (Songs.Rating <= 85) AND Songs.ID IN (SELECT Played.IDSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '66 - 75 ratings played
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 66) AND (Songs.Rating <= 75) AND Songs.ID IN (SELECT Played.IDSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '56 - 65 ratings played
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 56) AND (Songs.Rating <= 65) AND Songs.ID IN (SELECT Played.IDSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '46 - 55 ratings played
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 46) AND (Songs.Rating <= 55) AND Songs.ID IN (SELECT Played.IDSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '36 - 45 ratings played
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 36) AND (Songs.Rating <= 45) AND Songs.ID IN (SELECT Played.IDSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '26 - 35 ratings played
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 26) AND (Songs.Rating <= 35) AND Songs.ID IN (SELECT Played.IDSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '16 - 25 ratings played
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 16) AND (Songs.Rating <= 25) AND Songs.ID IN (SELECT Played.IDSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '6 - 15 ratings played
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE (Songs.Rating >= 6) AND (Songs.Rating <= 15) AND Songs.ID IN (SELECT Played.IDSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  '0 ratings played
  strSQL = "SELECT Songs.Rating, Count(Songs.ID) AS CountOfID, Sum(SongLength) AS TotalLength, Sum(FileLength) AS TotalFileLength FROM Songs WHERE Songs.Rating = 0 AND Songs.ID IN (SELECT Played.IDSong FROM Played)"
  Set qryStats = SDB.Database.OpenSQL(strSQL)

  If CLng(qryStats.StringByName("CountOfID")) > 0 Then
    While Not qryStats.EOF

      ' process background threads
      SDB.ProcessMessages

      strOut = strOut & "          <tr" & Style() & ">" & vbcrlf
      strOut = strOut & "            <td>" & qryStats.StringByName("CountOfID") & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & ShowRating(qryStats.StringByName("Rating"),booForExport) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatTime(CCur(NoNull(qryStats.ValueByName("TotalLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "            <td>" & FormatFileSize(CCur(NoNull(qryStats.ValueByName("TotalFileLength"), 0))) & "</td>" & vbcrlf
      strOut = strOut & "          </tr>" & vbcrlf
      qryStats.Next
    Wend
  End If

  strOut = strOut & "        </table>" & vbcrlf
  strOut = strOut & "      <p/>" & vbcrlf
 
  strOut = strOut & "      <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" & vbcrlf
  strOut = strOut & "        <tr><td style='border-bottom-width:0px'>" & vbcrlf
  strOut = strOut & "          " & SDB.Localize("Generated by ") & "<a href='http://www.mediamonkey.com'>MediaMonkey</a>" & SDB.Localize(" ON ") & MapXML(FormatDateTime(date(), vbLongDate)) & " " & SDB.Localize("at") & " " & MapXml(FormatDateTime(time(), vbLongTime))
  strOut = strOut & "        </td></tr>" & vbcrlf
  strOut = strOut & "      </table>" & vbcrlf
  strOut = strOut & "    <p/>" & vbcrlf

  strOut = strOut & "  </body>" & vbcrlf
  strOut = strOut & "</html>" & vbcrlf


  ' process background threads
  SDB.ProcessMessages

  BuildReport = strOut
End Function

