VERSION 5.00
Begin VB.Form frmMusic 
   Appearance      =   0  'Flat
   AutoRedraw      =   -1  'True
   BackColor       =   &H00C0C0C0&
   BorderStyle     =   0  'None
   ClientHeight    =   11490
   ClientLeft      =   15
   ClientTop       =   15
   ClientWidth     =   15330
   ControlBox      =   0   'False
   BeginProperty Font 
      Name            =   "Arial"
      Size            =   8.25
      Charset         =   0
      Weight          =   700
      Underline       =   0   'False
      Italic          =   0   'False
      Strikethrough   =   0   'False
   EndProperty
   Icon            =   "frmMusic.frx":0000
   LinkTopic       =   "Web"
   MaxButton       =   0   'False
   MinButton       =   0   'False
   Moveable        =   0   'False
   NegotiateMenus  =   0   'False
   PaletteMode     =   2  'Custom
   ScaleHeight     =   766
   ScaleMode       =   3  'Pixel
   ScaleWidth      =   1022
   ShowInTaskbar   =   0   'False
   WindowState     =   2  'Maximized
   Begin VB.Timer Timer2 
      Interval        =   400
      Left            =   450
      Top             =   8940
   End
   Begin VB.CommandButton cmd_DelQueSong 
      BackColor       =   &H00C0C0C0&
      Caption         =   "Remove Song"
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   11.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   660
      Left            =   930
      MaskColor       =   &H00FF8080&
      TabIndex        =   17
      Top             =   6990
      Width           =   1950
   End
   Begin VB.CommandButton cmd_ClearQue 
      BackColor       =   &H00C0C0C0&
      Caption         =   "Clear"
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   11.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      Height          =   660
      Left            =   930
      TabIndex        =   16
      Top             =   7770
      Width           =   1950
   End
   Begin VB.HScrollBar scrlVolume 
      Height          =   315
      LargeChange     =   5
      Left            =   30
      Max             =   100
      TabIndex        =   12
      Top             =   10170
      Visible         =   0   'False
      Width           =   705
   End
   Begin VB.ListBox lstSongTypes 
      BackColor       =   &H0075544A&
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   12
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00FFFFFF&
      Height          =   2805
      IntegralHeight  =   0   'False
      ItemData        =   "frmMusic.frx":08CA
      Left            =   90
      List            =   "frmMusic.frx":08D1
      MultiSelect     =   1  'Simple
      TabIndex        =   9
      Top             =   2550
      Width           =   2880
   End
   Begin VB.CheckBox chkRandomPlay 
      BackColor       =   &H00F7E9DD&
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   5.25
         Charset         =   0
         Weight          =   400
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00FFFFFF&
      Height          =   240
      Left            =   315
      MaskColor       =   &H00F7E9DD&
      TabIndex        =   2
      Top             =   6195
      Width           =   210
   End
   Begin VB.Timer Timer1 
      Enabled         =   0   'False
      Interval        =   2000
      Left            =   60
      Top             =   8940
   End
   Begin VB.ListBox lstArtists 
      BackColor       =   &H0075544A&
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   14.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00F7E9DD&
      Height          =   7290
      IntegralHeight  =   0   'False
      ItemData        =   "frmMusic.frx":08E3
      Left            =   11490
      List            =   "frmMusic.frx":08EA
      MultiSelect     =   1  'Simple
      TabIndex        =   1
      Top             =   1170
      Width           =   3720
   End
   Begin VB.ListBox lstSongs 
      BackColor       =   &H0075544A&
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   14.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00FFFFFF&
      Height          =   4200
      IntegralHeight  =   0   'False
      ItemData        =   "frmMusic.frx":08FA
      Left            =   3030
      List            =   "frmMusic.frx":0901
      TabIndex        =   0
      Top             =   1170
      Width           =   8400
   End
   Begin VB.OptionButton optServer2 
      BackColor       =   &H00F7E9DD&
      Caption         =   "Server 2"
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   12
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00400000&
      Height          =   300
      Left            =   90
      MaskColor       =   &H00413933&
      TabIndex        =   6
      Top             =   1080
      Width           =   2790
   End
   Begin VB.OptionButton optServer3 
      BackColor       =   &H00F7E9DD&
      Caption         =   "Server 3"
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   12
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00400000&
      Height          =   300
      Left            =   90
      MaskColor       =   &H00413933&
      TabIndex        =   7
      Top             =   1380
      Width           =   2790
   End
   Begin VB.OptionButton optServer4 
      BackColor       =   &H00F7E9DD&
      Caption         =   "Server 4"
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   12
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00400000&
      Height          =   300
      Left            =   90
      MaskColor       =   &H00413933&
      TabIndex        =   8
      Top             =   1680
      Width           =   2790
   End
   Begin VB.ListBox lstPlayQue 
      BackColor       =   &H0075544A&
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   12
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00FFFFFF&
      Height          =   3000
      IntegralHeight  =   0   'False
      ItemData        =   "frmMusic.frx":090F
      Left            =   3030
      List            =   "frmMusic.frx":0916
      TabIndex        =   3
      Top             =   5460
      Width           =   8400
   End
   Begin VB.OptionButton optServer1 
      BackColor       =   &H00F7E9DD&
      Caption         =   "Server 1"
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   12
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00400000&
      Height          =   300
      Left            =   90
      MaskColor       =   &H004F3933&
      TabIndex        =   5
      Top             =   780
      Value           =   -1  'True
      Width           =   2790
   End
   Begin VB.Label always_Date 
      BackColor       =   &H00FFFFFF&
      BackStyle       =   0  'Transparent
      Caption         =   "Date"
      BeginProperty Font 
         Name            =   "Century Gothic"
         Size            =   15.75
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H0075544A&
      Height          =   375
      Left            =   30
      TabIndex        =   21
      Top             =   9690
      Width           =   7710
   End
   Begin VB.Label always_Time 
      Alignment       =   1  'Right Justify
      BackColor       =   &H00FFFFFF&
      BackStyle       =   0  'Transparent
      Caption         =   "Time"
      BeginProperty Font 
         Name            =   "Century Gothic"
         Size            =   15.75
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H0075544A&
      Height          =   375
      Left            =   8010
      TabIndex        =   20
      Top             =   9690
      Width           =   7230
   End
   Begin VB.Label txtTrackLength 
      Alignment       =   2  'Center
      BorderStyle     =   1  'Fixed Single
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   14.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00000000&
      Height          =   405
      Left            =   11460
      TabIndex        =   19
      Top             =   270
      Width           =   3735
   End
   Begin VB.Label txtCurrentSong 
      BorderStyle     =   1  'Fixed Single
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   14.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00FF8080&
      Height          =   405
      Left            =   3000
      TabIndex        =   18
      Top             =   270
      Width           =   8400
   End
   Begin VB.Image cmdStop 
      Height          =   990
      Left            =   6270
      Top             =   8580
      Width           =   900
   End
   Begin VB.Image cmdNext 
      Height          =   990
      Left            =   7470
      Top             =   8580
      Width           =   900
   End
   Begin VB.Image cmdPlay 
      Height          =   990
      Left            =   5040
      Top             =   8580
      Width           =   900
   End
   Begin VB.Image cmd_Visualization 
      Height          =   990
      Left            =   8970
      Top             =   8580
      Width           =   900
   End
   Begin VB.Image cmdAllSongs 
      Height          =   990
      Left            =   14100
      Top             =   8550
      Width           =   900
   End
   Begin VB.Image cmdMute 
      Height          =   990
      Left            =   10440
      Top             =   8580
      Width           =   900
   End
   Begin VB.Image cmdVolDown 
      Height          =   990
      Left            =   11580
      Top             =   8550
      Width           =   900
   End
   Begin VB.Image cmdVolUp 
      Height          =   990
      Left            =   12750
      Top             =   8550
      Width           =   900
   End
   Begin VB.Image cmdPrevious 
      Height          =   990
      Left            =   3810
      Top             =   8580
      Width           =   900
   End
   Begin VB.Image cmd_Exit 
      Appearance      =   0  'Flat
      Height          =   645
      Left            =   30
      Top             =   10830
      Width           =   1080
   End
   Begin VB.Label always_lblControl 
      Alignment       =   2  'Center
      BackColor       =   &H00FFFFFF&
      BackStyle       =   0  'Transparent
      Caption         =   "Music Center"
      BeginProperty Font 
         Name            =   "Century Gothic"
         Size            =   20.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   -1  'True
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H00400000&
      Height          =   600
      Left            =   60
      TabIndex        =   15
      Top             =   60
      Width           =   2850
   End
   Begin VB.Label lblSongs 
      BackStyle       =   0  'Transparent
      Caption         =   "Song List:"
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   14.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   -1  'True
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H004F3933&
      Height          =   375
      Left            =   3000
      TabIndex        =   14
      Top             =   780
      Width           =   1620
   End
   Begin VB.Image optLightControl 
      Height          =   1170
      Left            =   1740
      Top             =   10170
      Width           =   2640
   End
   Begin VB.Image optMP3Control 
      Height          =   1140
      Left            =   5160
      Top             =   10200
      Width           =   2640
   End
   Begin VB.Image optWebControl 
      Height          =   1140
      Left            =   8670
      Top             =   10170
      Width           =   2370
   End
   Begin VB.Image optMediaControl 
      Height          =   1170
      Left            =   11910
      Top             =   10170
      Width           =   2565
   End
   Begin VB.Line line_Volume_High 
      BorderColor     =   &H00E0E0E0&
      BorderWidth     =   4
      Visible         =   0   'False
      X1              =   783
      X2              =   819
      Y1              =   565
      Y2              =   565
   End
   Begin VB.Line line_Volume_Low 
      BorderColor     =   &H00E0E0E0&
      BorderWidth     =   4
      Visible         =   0   'False
      X1              =   709
      X2              =   745
      Y1              =   565
      Y2              =   565
   End
   Begin VB.Line line_Volume_Middle 
      BorderColor     =   &H00E0E0E0&
      BorderWidth     =   4
      Visible         =   0   'False
      X1              =   745
      X2              =   783
      Y1              =   565
      Y2              =   565
   End
   Begin VB.Label lblchkRandomPlay 
      AutoSize        =   -1  'True
      BackStyle       =   0  'Transparent
      Caption         =   "Random Playback"
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   12
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H004F3933&
      Height          =   285
      Left            =   585
      TabIndex        =   13
      Top             =   6195
      Width           =   2085
   End
   Begin VB.Label lblArtists 
      BackStyle       =   0  'Transparent
      Caption         =   "Artists Filter:"
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   14.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   -1  'True
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H004F3933&
      Height          =   375
      Left            =   11460
      TabIndex        =   11
      Top             =   780
      Width           =   3060
   End
   Begin VB.Label lblSongTypes 
      BackStyle       =   0  'Transparent
      Caption         =   "Category Filter:"
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   14.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   -1  'True
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H004F3933&
      Height          =   375
      Left            =   90
      TabIndex        =   10
      Top             =   2160
      Width           =   2790
   End
   Begin VB.Label lblPlayQue 
      BackStyle       =   0  'Transparent
      Caption         =   "Songs in the Queue:"
      BeginProperty Font 
         Name            =   "Arial"
         Size            =   14.25
         Charset         =   0
         Weight          =   700
         Underline       =   0   'False
         Italic          =   0   'False
         Strikethrough   =   0   'False
      EndProperty
      ForeColor       =   &H004F3933&
      Height          =   375
      Left            =   90
      TabIndex        =   4
      Top             =   5460
      Width           =   2910
   End
   Begin VB.Menu mnuSongs 
      Caption         =   ""
      Visible         =   0   'False
      Begin VB.Menu mnuRefresh 
         Caption         =   "Refresh"
      End
   End
End
Attribute VB_Name = "frmMusic"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Dim WithEvents RemoteFile As DataConnection 'Class used to communicate with Web Command Server
Attribute RemoteFile.VB_VarHelpID = -1
Dim inifile As String               'Holds location of INI file
Dim HostIP As String                'INI -Actual IP address of Web Command Server
Dim HostPort As String              'INI -Port number to use for Web Command Server
Dim Skin As String                  'INI -Name of the current skin in use
Dim Dbg As Boolean                  'INI -Indicates if Debug message should shown

Dim WebSvr As String                'Holds the initial URL with IP and Port of Web Command Server
Dim Header As String                'Holds the HTML header to be stripped from received messages
Dim Footer As String                'Holds the HTML footer to be stripped from received messages
Dim Web1Busy As Boolean             'Global Flag to indicate a Web message is being processed
Dim Web1Response As String          'Holds the incoming messages from the Web Command Server
Dim Timeout1 As Long                'Tracks when the incoming Web Command Server messages timeout
Dim m_bMouseUp As Boolean           'Flag to indicate mouse up event (for volume control)

Dim SkinPath As String              'Holds path to current skin
Dim imgpath As String               'Hold path to images for skinning

Dim VolumeSpeed As Long             'INI -Changes how fast the volume will change
Dim VolType As Long                 'INI -Use WinAmp volume (Type 1) or Wave mixer volume (Type 2)
Dim FullVol As Long                 'Holds tracking for full volume level
Dim SavedVolume As Long             'Use to store old volume when a mute event has occured

Dim ListLen As Long                 'Number of songs currently in the Playlist
Dim ArtistsCount As Long            'Number of unique Artists in the current Playlist
Dim ListS() As String               'Array for the full track name from MP3 Player
Dim ListSongs() As String           'Array for the names of the Songs from MP3 Player
Dim ListArtists() As String         'Array for the names of the Artists from MP3 Player
Dim ListSongType() As String        'Array for the Song Category based on the file's directory
Dim ListI() As Long                 'Array for the actual index number from MP3 Player

Dim Status As Long                  'Status of MP3 Player (PLAYING, STOPPED, PAUSED)
Dim CurrentSong As String           'Name of currently playing song
Dim CurrentSongType As String       'Category of currently playing song
Dim Previous() As Long              'An array to hold songs played previously
Dim tmpPrevious As Long             'Tracks the last track added to previous array
Dim ServerNum As Long               'Currently active MP3 server (1-4) is zero on initial run
Dim AllSongs As Boolean             'Flag to indicate if any filters are active for random playback
Dim SongTypeFilter As String        'Holds all current Song Types for Playlist filtering
Dim ArtistFilter As String          'Holds all current Artists for Playlist filtering
Dim TrackTime As Long               'Current position in playing Track - updated by Timer2
Dim TrackLength As Long             'Current length of playing Track - updated by Timer1

Private Declare Function GetTickCount Lib "kernel32.dll" () As Long
Const White = 16777215
Const Yellow = 65535

Private Sub Form_Load()
    Dim temptag As String               'Temporary holder for values read from INI file
    Set RemoteFile = New DataConnection 'Create new instance of the Web communication class
    StartWinsock vbNullString           'Initialize the Web communication class
    Footer = "<BR></BODY></HTML>"       'and setup Header and Footer variables
    Header = "<HTML><HEAD><TITLE>---</TITLE><META HTTP-EQUIV=" & Chr(34) & "Pragma" & Chr(34) & " CONTENT=" & Chr(34) & "no-cache" & Chr(34) & "><META HTTP-EQUIV=" & Chr(34) & "Expires" & Chr(34) & " CONTENT=" & Chr(34) & "-1" & Chr(34) & "></HEAD><BODY>"

    Web1Busy = False                    'Initialize the three Web communication variables
    Timeout1 = 0
    Web1Response = ""
    SavedVolume = 0: FullVol = 37       'Set the initial volume levels
    txtCurrentSong.Tag = -1: tmpPrevious = -1  'more initial defaults
    Dbg = False                         'Turn of Debugging by default
    imgpath = App.Path & "\images\"     'Set two initial paths
    inifile = App.Path & "\HomePanel.ini"
    always_Date.Caption = ""            'Initialize the Date and Time captions
    always_Time.Caption = ""
    
    'INI -For creation of a skin while running within VB (this will be removed in future)
    fReadValue inifile, "Options", "MakeSkin", "S", "0", temptag
    If temptag = "1" Then PrintControl frmMusic, "Section2": frmWeb.Show: Unload frmMusic: Exit Sub
    
    Screen.MousePointer = vbHourglass   'Make hourglass - Wait til here due to skin output above
    
    'INI -Read the Debug flag and reset it if necessary
    fReadValue inifile, "Options", "Debug", "S", "0", temptag
    If temptag = "1" Then Dbg = True
    
    'INI -Read and load background picture
    fReadValue inifile, "Section2", "Background", "S", "err", temptag
    If temptag <> "err" Then frmMusic.Picture = LoadPicture(imgpath & temptag)
    
    'INI -Read and show the text label for the form's Title
    fReadValue inifile, "Section2", "MainLabel", "S", "err", temptag
    If temptag <> "err" Then frmMusic.always_lblControl.Caption = temptag

    'Go setup the Skin and optionally show Debug message if successful
    SkinMe "Section2", frmMusic
    If Dbg Then MsgBox "Finished Skinning Module.", vbOKOnly, "Debug Message: Form_Load"
    
    'By default all the Servers in Option list are invisible
    optServer1.Visible = False: optServer2.Visible = False: optServer3.Visible = False: optServer4.Visible = False
    'INI -Read the four Servers and display them if they are setup
    fReadValue inifile, "Section2", "HostName1", "S", "", temptag
    If temptag <> "" Then optServer1.Caption = temptag: optServer1.Visible = True
    fReadValue inifile, "Section2", "HostName2", "S", "", temptag
    If temptag <> "" Then optServer2.Caption = temptag: optServer2.Visible = True
    fReadValue inifile, "Section2", "HostName3", "S", "", temptag
    If temptag <> "" Then optServer3.Caption = temptag: optServer3.Visible = True
    fReadValue inifile, "Section2", "HostName4", "S", "", temptag
    If temptag <> "" Then optServer4.Caption = temptag: optServer4.Visible = True
    
    ServerNum = 0: PickServer (0)   'Initial server is zero, then go Pick server to read files
    'If we get here then the file reads were successful, optionally output Debug message
    If Dbg Then MsgBox "Finished setting up songs, artists, and song types.", vbOKOnly, "Debug Message: Form_Load"
    
    'INI -Set the default Volume speed to 50 and then read the setting from INI
    VolumeSpeed = 50
    fReadValue inifile, "Section2", "VolumeSpeed", "S", "50", temptag
    If IsNumeric(temptag) Then VolumeSpeed = CLng(temptag)
    
    'INI -Set the default Volume Type to 1 (Winamp control) and then read the setting from INI
    '     Note: if the player is not Winamp then this setting will always be for Wave Mixer
    VolType = 1
    fReadValue inifile, "Section2", "VolumeType", "S", "50", temptag
    If IsNumeric(temptag) Then VolType = CLng(temptag)
    'Now go read the current volume levels and save that as default, optionally output debug msg
    If VolType = 1 Then
        scrlVolume = (CLng(WebCmd1("winamp:getvolume")) / 255) * 100
    Else
        scrlVolume = CLng(WebCmd1("cmd:getvolume"))
    End If
    SavedVolume = scrlVolume
    If Dbg Then MsgBox "Finished Setting Up Volume Control.", vbOKOnly, "Debug Message: Form_Load"
    
    Screen.MousePointer = vbDefault 'Reset the mouse pointer to normal.
End Sub

Private Sub PickServer(i As Long)       'Routine used to initially pick of change MP3 servers
    If i <> 0 And i <> ServerNum Then   'Are we changing the server to another after initial load?
        If MsgBox("Changing servers will clear all Songs currently in the Queue. Are you sure you wish to do this?", vbYesNo + vbQuestion, "Are you Sure?") = vbNo Then Exit Sub
    End If
    If i = 0 Then i = 1                 'Set the default initial server to first one
    If i <> ServerNum Then              'Are we really picking a new server?
        TimerStop                       'Disable Timers so we are not interrupted
        ServerNum = i                   'Set the currently selected Server Number
        ArtistsCount = 0                'Initialize the Count of Artists
        AllSongs = True                 'Default to no filters
        lstPlayQue.Clear                'Clear the Que of any prior picked songs
        'INI -Read the Host IP and Port for the Server selected
        fReadValue inifile, "Section2", "HostIP" & i, "S", "192.168.0.100", HostIP
        fReadValue inifile, "Section2", "HostPort" & i, "S", "8888", HostPort
        'Setup the Web Server URL and optionally output Debug message
        WebSvr = "http://" & HostIP & ":" & HostPort & "/"
        If Dbg Then MsgBox WebSvr & " sucessfully bound. Starting ReadList.", vbOKOnly, "Debug Message: PickServer"
        
        ReadList                            'Reads the Songs and fills in Lists
        WebCmdSilent "winamp:stop:after"    'Tell player to stop after current song (only for Winamp)
        TimerStart                          'Turn Timers back on
    End If
End Sub

Private Sub ReadList()  'This routine will read the list of songs and populate the Lists
    Dim i As Long, j As Long, tmpStr As String, stage As String     'Temp variables
    Dim tmpTitle As String, tmpFile() As String, tmpArr() As String
    On Error GoTo Err_ReadList                                      'Error Handler
    stage = "Reading number of songs."                              'Message for Debugging
    
    'Get number of songs in playlist and optionally output Debug message
    tmpStr = WebCmd1("winamp:playlist:length")      'Send Web command to get count of songs
    If IsNumeric(tmpStr) = False Then tmpStr = "0"  'Trap errors
    ListLen = CLng(tmpStr)
    If Dbg Then MsgBox "Winamp says it has " & ListLen & " files.", vbOKOnly, "Debug Message: ReadList"
    
    'Clear the listboxes and hide them while we populate (makes things much faster)
    lstSongs.Clear:             lstArtists.Clear
    lstSongs.Visible = False:   lstArtists.Visible = False
    
    'Initialize all the Arrays to the selected playlist length
    ReDim ListSongs(ListLen)    'Holds the names of the Songs from MP3 Player
    ReDim ListArtists(ListLen)  'Holds the names of the Artists from MP3 Player
    ReDim ListI(ListLen)        'Holds for the actual index number from MP3 Player
    ReDim ListS(ListLen)        'Holds the full track name from MP3 Player
    ReDim ListSongType(ListLen) 'Holds the Song Category based on the file's directory
    ReDim Previous(20)
    
    'Clear the Previously played list
    ClearPrevious
    stage = "Start."                                                'Message for Debugging

ReReadList:         'If the list read is not right we can restart here.
    'The following gets the entire list of Titles and Files in one big string from Server
    'tmpTitle = Split(WebCmd1("winamp:playlist:title:all"), "<BR>")
    tmpStr = WebCmd1("winamp:playlist:file:all")
    Do                                              'Loop to take off all extra <BR>'s
        If Right(tmpStr, 4) = "<BR>" Then
            tmpStr = Left(tmpStr, Len(tmpStr) - 4)
        Else
            Exit Do
        End If
    Loop
    tmpFile = Split(tmpStr, "<BR>")                 'Now parse the file into an array
    
    'Verify the number of entries in the received string
    If UBound(tmpFile) <> ListLen - 1 Then GoTo ReReadList
    
    'Loop through the reade list and fill in all the arrays
    For i = 0 To ListLen - 1
        stage = "Got File #" & i & "-" & tmpFile(i)                 'Message for Debugging
        ListI(i) = i                        'Save the Playlist position
        tmpTitle = DecodeTitle(tmpFile(i))  'Extract the title from Filename
        'Check if there is a Artist listed, if not add "Unkown-"
        If InStr(1, tmpTitle, "-") = 0 Then tmpTitle = "Unknown-" & tmpTitle
        ListS(i) = tmpTitle                 'Put it in Array
        tmpArr = Split(tmpTitle, "-")       'Fill in temp Array with the Song Artist and Names
        AddArtist Trim(tmpArr(0))           'Add Artist to List and Artist Array
        ListSongs(i) = Trim(tmpArr(1))      'Add Song Name to List and SongName Array
        stage = "Got Filename #" & i & "-" & tmpFile(i)             'Message for Debugging
        ListSongType(i) = GetSongType(tmpFile(i))   'Determine Song Category
        stage = "Got Songtype for #" & i & " of " & ListSongType(i) 'Message for Debugging
    Next i
    If Dbg Then MsgBox "Finished reading songs titles.", vbOKOnly, "Debug Message: ReadList"
    
    'Sort the list alphabetically
    SortArtistList
    
    'Since there are no Filters, populate the ListBoxes from Arrays
    lstSongTypes.ForeColor = White: lstArtists.ForeColor = White 'Default colors
    j = CLng(WebCmd1("winamp:current:num"))     'Get currently playing song
    stage = "Current List Position is #" & j                        'Message for Debugging
    For i = 0 To ListLen - 1                      'Loop through Playlist
        'Add the item with the playlist number
        lstSongs.AddItem CStr(Format(i + 1, "0000")) & ".  " & ListS(i)
        If ListI(i) = j Then j = i              'Find which track is playing
    Next i
    If Dbg Then MsgBox "Finished adding songs titles to Listbox.", vbOKOnly, "Debug Message: ReadList"
    lstSongs.ListIndex = j                      'Now set the List to the current song

    'Now fill in Artists List
    For i = 0 To ArtistsCount - 1: lstArtists.AddItem ListArtists(i): Next i
    BuildSongTypeList   'And fill in Category List
    
    'Unhide the List Boxes and Make sure Filters are cleared
    lstSongs.Visible = True:   lstArtists.Visible = True
    AllSongs = True: SongTypeFilter = "": ArtistFilter = ""
    Exit Sub
Err_ReadList:
    If Dbg Then MsgBox "(Error #" & Err.Number & ") Crash trapped just after: " & stage, vbOKOnly, "Debug Message: ReadList"
    Err.Clear
End Sub

Private Sub Timer1_Timer()  'Runs every 2 Seconds to check playing status
    Dim SongStat As String, QSong As Long, SongIndex As Long
    Dim i As Long, j As Long, oldStatus As Long
    Dim tmpStr As String, tmpStr2 As String
    Dim tmpArr As Variant, tmpArr2 As Variant
    Dim tmpBol As Boolean, tmpBol2 As Boolean
    
    On Error GoTo BadWeb2       'Error Handler
    'Has the date changed?
    If always_Date.Caption <> Format(Date, "mmm-dd-yyyy") Then always_Date.Caption = Format(Date, "mmm-dd-yyyy")
    
    'Are we in the middle of another Web command - if yes increase Timeout and exit for now
    If Web1Busy And Timeout1 < 5 Then Timeout1 = Timeout1 + 1: Exit Sub
    'Have we hit the Timeout value (10 seconds)? if yes, clear Web1busy and reset Timeout
    If Web1Busy And Timeout1 > 5 Then Web1Busy = False: Timeout1 = 0: Exit Sub
    
    'Are we in the middle of trying to find another track to play?
    If txtCurrentSong = "Searching for next song based on filters..." Then Exit Sub
    
    'Get the current volume
    If scrlVolume <> 0 Then scrlVolume = CLng(WebCmd1("cmd:getvolume")): DrawVolume
    
    'Save the current Status the client has
    oldStatus = Status
    
    'Now update the Current song number, status, and song length from Winamp
    tmpStr = WebCmd1("winamp:current:num~winamp:current:status~winamp:current:length")
    
    tmpArr = Split(tmpStr, "<BR>")          'Parse the received message
    If UBound(tmpArr) <> 2 Then Exit Sub    'Did we get a full reply?
    j = CLng(tmpArr(0)): tmpStr = tmpArr(1) 'Save the received track and status
    Status = StatusDecode(tmpStr)           'Go Decode the Status message
    TrackLength = CLng(tmpArr(2))           'Convert TrackLength to a number and save
    If txtCurrentSong.Tag = -1 Then tmpPrevious = j
    'Now check if the song or status has changed
    If j = CLng(txtCurrentSong.Tag) And Status = oldStatus Then
        'If it has not then see if we need to add it to the previously played list
        If chkRandomPlay And InPrevious(tmpPrevious) = False Then
            InsertPrevious tmpPrevious
            tmpPrevious = j
        End If
        Exit Sub        'Exit since the status and Current track have not changed.
    End If
    
    SongStat = ""       'Clear the Status message so we can build a new one
    If Status = 1 Then SongStat = "Playing: "
    If Status = 3 Then SongStat = "Paused: "
    If CLng(txtCurrentSong.Tag) <> j And Status <> 0 Then 'Is a new song playing or paused?
        For i = 0 To ListLen - 1  'Find it in the List
            If ListI(i) = j Then CurrentSong = ListS(i): CurrentSongType = ListSongType(i): Exit For
        Next i
    End If
    SongIndex = j                                              'Save the currently playing song
    If Status <> 0 Then SongStat = SongStat & ListS(j)         'And get ready to show the Message
    
    'In Random mode with no Filters and in Stop status? If yes, randomly choose next track
    If chkRandomPlay And AllSongs And Status = 0 Then
        WebCmdSilent "winamp:play:playlist:" & GetRandomSong + 1 & "~winamp:stop:after": Status = 1
    End If
    
    'In Random mode with active Filters and in Playing status? Is song within allowed filters?
    If chkRandomPlay And AllSongs = False And Status = 1 Then
        If SongTypeFilter <> "" And (InStr(1, SongTypeFilter, CurrentSongType & "~~", vbBinaryCompare) = 0) Then
            'Song's Category is not allowed according to Filters.  Pause things and
            '  set status to stop so a valid song will be chosen by this Client
            WebCmdSilent "winamp:pause": Status = 0
            If scrlVolume <> 0 Then cmdMute_Click   'Mute things while we work
        ElseIf ArtistFilter <> "" Then
            'Song's Artist is not allowed according to Filters.  Pause things and
            '  set status to stop so a valid song will be chosen by this Client
            tmpArr2 = Split(CurrentSong, "-"): tmpStr2 = Trim(tmpArr2(0)) & "~~"
            If (InStr(1, ArtistFilter, tmpStr2, vbBinaryCompare) = 0) Then
                WebCmdSilent "winamp:pause": Status = 0
                If scrlVolume <> 0 Then cmdMute_Click   'Mute things while we work
            End If
        End If
    End If

    'Are we stopped?  If yes, check if we need to play another song.
    If Status = 0 Then
        SongStat = "Stopped."           'Set Status Message
        txtTrackLength = ""             'Clear the Track counter
        QSong = -1: SongIndex = -1      'Initialize the Que to search for next song to play
        'If in Non-Random mode and there are queued songs then play queued song
        If chkRandomPlay = 0 And lstPlayQue.ListCount > 0 Then
            For i = 0 To lstPlayQue.ListCount - 1   'Find the next song to be sent from que
                If Left(lstPlayQue.List(i), 7) <> "(Sent) " Then QSong = Val(Left(lstPlayQue.List(i), 4)) - 1: Exit For
            Next i
            If QSong <> -1 Then                 'As long as we found a queued song
                SongIndex = ListI(QSong)        'Find its index
                CurrentSong = ListS(QSong)
                CurrentSongType = ListSongType(QSong)
                SongStat = "Playing: " & CurrentSong
                txtCurrentSong.Tag = SongIndex
                lstPlayQue.List(i) = "(Sent) " & lstPlayQue.List(i)
                lstPlayQue.ListIndex = lstPlayQue.ListCount - 1
            End If
            If SongIndex <> -1 Then             'If we must have found our queued song, play it
                WebCmdSilent "winamp:play:playlist:" & SongIndex + 1 & "~winamp:stop:after"
                Status = 1                      'Set Status to playing
            Else
                SongIndex = CLng(txtCurrentSong.Tag)
            End If
        End If
    
        'Are we in Random mode with active filters
        If chkRandomPlay And AllSongs = False Then
            If scrlVolume <> 0 Then cmdMute_Click: WebCmdSilent "winamp:pause" 'mute and pause while we work
            txtCurrentSong = "Searching for next song based on filters..."
            tmpBol = False: tmpBol2 = False         'Set Flags saying whether we have found song
            Do Until tmpBol And tmpBol2             'Loop until we find a valid song
                QSong = GetRandomSong()             'Random pick next song to play
                If SongTypeFilter <> "" Then            'Are there Category filters?
                    tmpStr = ListSongType(QSong) & "~~" 'if yes, check if song is acceptable
                    tmpBol = InStr(1, SongTypeFilter, tmpStr, vbBinaryCompare)
                Else
                    tmpBol = True                       'There are no Category Filters
                End If
                If ArtistFilter <> "" Then              'Are there Artist filters?
                    tmpArr2 = Split(ListS(QSong), "-")  'if yes, check if song is acceptable
                    tmpStr2 = Trim(tmpArr2(0)) & "~~"
                    tmpBol2 = InStr(1, ArtistFilter, tmpStr2, vbBinaryCompare)
                Else
                    tmpBol2 = True                      'There are no Artist Filters
                End If
                DoEvents                            'Make sure other things still run okay
            Loop
            
            SongIndex = ListI(QSong)                'Get the playlist number for song selected
            CurrentSong = ListS(QSong)              'And the name of the song
            CurrentSongType = ListSongType(QSong)   'And its Category
            SongStat = "Playing: " & CurrentSong    'Prepare status message
            'Send selected song to server and tell it to stop after playing it (Winamp only)
            WebCmdSilent "winamp:play:playlist:" & (SongIndex + 1) & "~winamp:play~winamp:stop:after"
            Status = 1                              'Set the status to playing
            If scrlVolume = 0 Then cmdMute_Click    'If we are muted then unmute
        End If
    End If
    txtCurrentSong = SongStat                       'Show Status Message
    txtCurrentSong.Tag = SongIndex                  'And saved current song's playlist number
    Exit Sub
BadWeb2:
    Err.Clear
    On Error GoTo 0
End Sub

Private Sub RefreshList()       'This is called when the All Songs Refresh is needed
    Dim i As Long, j As Long, TempArray() As String, tmpStr As String
    Timer1.Enabled = False: Timer2.Enabled = False  'Do not want to get interrupted
    'Clear the listboxes and hide them while we populate (makes things much faster)
    lstSongs.Clear:             lstArtists.Clear
    lstSongs.Visible = False:   lstArtists.Visible = False

    lstSongTypes.ForeColor = White: lstArtists.ForeColor = White    'Default Colors
    AllSongs = True: SongTypeFilter = "": ArtistFilter = ""         'Turn off filters
    
    j = CLng(WebCmd1("winamp:current:num"))     'Get currently playing song
    For i = 0 To ListLen - 1                    'Loop through Playlist
        'Add the item with the playlist number
        lstSongs.AddItem CStr(Format(i + 1, "0000")) & ".  " & ListS(i)
        If ListI(i) = j Then j = i              'Find which track is playing
    Next i
    lstSongs.ListIndex = j                      'Now set the List to the current song

    'Now fill in Artists List
    For i = 0 To ArtistsCount - 1: lstArtists.AddItem ListArtists(i): Next i
    BuildSongTypeList   'And fill in Category List
    
    'Unhide the List Boxes and turn Timers back on
    lstSongs.Visible = True:   lstArtists.Visible = True
    Timer1.Enabled = True: Timer2.Enabled = True
End Sub

Private Sub Timer2_Timer()      'This just updates the time, track position and length
    always_Time.Caption = Format(Now, "hh:mm:ss AM/PM") 'Update time on screen
    If Status <> 0 Then         'Are are playing or paused?
        On Error GoTo BadWeb    'Error handler for bad communication with server
        TrackTime = CLng(WebCmd1("winamp:current:position"))    'Get current position
        If TrackLength >= 3600 Then                             'Is tracks hours long?
            txtTrackLength = Format$(TrackTime / 86400, "hh:nn:ss") & " of " & Format$(TrackLength / 86400, "hh:nn:ss")
        Else                                                    'Or minutes
            txtTrackLength = Format$(TrackTime / 86400, "nn:ss") & " of " & Format$(TrackLength / 86400, "nn:ss")
        End If
BadWeb:
        Err.Clear
        On Error GoTo 0         'Clear the Error and keep going
    End If
End Sub

Private Function GetRandomSong() As Long
    Randomize                                   'Initialize Random function
    GetRandomSong = Int(ListLen * Rnd)    'Random pick next song to play
End Function

Private Sub cmd_ClearQue_Click()    'Clears the play Que
    lstPlayQue.Clear
End Sub

Private Sub cmd_DelQueSong_Click()  'Deletes the currently selected song from Que
    If lstPlayQue.ListIndex >= 0 Then lstPlayQue.RemoveItem (lstPlayQue.ListIndex)
End Sub

Private Sub cmd_Exit_Click()        'Command button to Exit program
    Unload frmMediaControl          'Unload all the other forms
    Unload frmMain
    Unload frmWeb
    Unload frmMusic                 'Finally, unload this form
End Sub

Private Sub cmd_Visualization_Click()   'Turns on Visuals for Winamp only
    WebCmdSilent "winamp:plugin"
End Sub

Private Sub chkRandomPlay_Click()   'Random play mode was clicked
    If chkRandomPlay Then           'If checked, then hide the que box
        lstPlayQue.Visible = False: lblPlayQue.Visible = False
    Else                            'If unchecked, then make sure the que is visible
        lstPlayQue.Visible = True: lblPlayQue.Visible = True
    End If
    txtCurrentSong.Tag = -1         'Clear the tag to force Timer1 to check playing song
End Sub

Private Sub cmdAllSongs_Click()     'Clear all filters and display all songs
    RefreshList
End Sub

Private Sub cmdMute_Click()         'To simulate mute we actually set Volume to zero
    If scrlVolume <> 0 Then         'Not currently muted so
        SavedVolume = scrlVolume    'Save the current volume
        scrlVolume = 0              'And set the new volume to zero
        SetVolume                   'and make it happen
    Else
        scrlVolume = SavedVolume    'Unmuted, so restore saved volume
        SetVolume                   'and make it happen
    End If
End Sub

Private Sub cmdNext_Click()         'Tells player to goto next track
    If chkRandomPlay = 0 Then           'if not in Random play mode
        If lstPlayQue.ListCount = 0 Then            'If no songs are qued,
            WebCmdSilent "winamp:play:playlist:" & GetRandomSong + 1 & "~winamp:stop:after" 'Random song
            Status = 1                              'Set status to playing
            txtCurrentSong.Tag = -1                 'Force Timer1 to update
        Else                            'Songs must be queued
            WebCmdSilent "winamp:stop"  'So just stop and let Timer1 handle the selection
        End If
    Else                                'We must be in Random play mode
        If AllSongs = True Then                     'If no filters are active
            WebCmdSilent "winamp:play:playlist:" & GetRandomSong + 1 & "~winamp:stop:after" 'Random song
            Status = 1                              'Set status to playing
            txtCurrentSong.Tag = -1                 'Force Timer1 to update
        Else                            'There must be filter active
            WebCmdSilent "winamp:stop"  'So just stop and let Timer1 handle the selection
        End If
    End If
End Sub

Private Sub cmdPlay_Click()         'User wants to play something
    If Status <> 1 Then                 'Are we stopped or paused?
        WebCmdSilent "winamp:play"              'if yes, go ahead and start playing again
        txtCurrentSong.Tag = -1                 'Force Timer1 to update
    End If
End Sub

Private Sub cmdPrevious_Click()     'Play previously playing track
    Dim i As Long, QSong As Long
    If chkRandomPlay Or lstPlayQue.ListCount = 0 Then
        i = GetPrevious
        If i = -1 Then
            WebCmdSilent "winamp:previous"
        Else
            WebCmdSilent "winamp:play:playlist:" & (i + 1) & "~winamp:play~winamp:stop:after"
            Status = 1: txtCurrentSong.Tag = -1
        End If
    Else
        If lstPlayQue.ListCount > 0 Then
            For QSong = 0 To lstPlayQue.ListCount - 1
                If Left(lstPlayQue.List(QSong), 7) <> "(Sent) " Then QSong = QSong - 1: Exit For
            Next QSong
            If QSong = lstPlayQue.ListCount Then
                lstPlayQue.List(QSong - 1) = Right(lstPlayQue.List(QSong - 1), Len(lstPlayQue.List(QSong - 1)) - 7)
                lstPlayQue.List(QSong - 2) = Right(lstPlayQue.List(QSong - 2), Len(lstPlayQue.List(QSong - 2)) - 7)
            End If
            
            If Status <> 0 And QSong <= lstPlayQue.ListCount - 1 And QSong > 0 Then
                lstPlayQue.List(QSong) = Right(lstPlayQue.List(QSong), Len(lstPlayQue.List(QSong)) - 7)
                lstPlayQue.List(QSong - 1) = Right(lstPlayQue.List(QSong - 1), Len(lstPlayQue.List(QSong - 1)) - 7)
            End If
            If Status <> 0 And QSong <= lstPlayQue.ListCount - 1 And QSong = 0 Then
                lstPlayQue.List(QSong) = Right(lstPlayQue.List(QSong), Len(lstPlayQue.List(QSong)) - 7)
            End If
            If Status <> 0 Then Status = 0: WebCmdSilent "winamp:stop"
        End If
    End If
End Sub

Private Sub cmdStop_Click()     'Stop and Pause are the same here
    If Status <> 0 Then WebCmdSilent "winamp:pause"     'Send Pause if we are not stopped
    If Status = 3 Then              'If we were already paused,
        Status = 1                  '  we are now playing
    Else
        Status = 3                  'Otherwise we are now paused
    End If
End Sub

Private Sub cmdVolDown_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    'This routine tracks Mouse button push on the Volume and changes drawn volume.
    'Volume is set once the button is released.
    Dim iEndSeconds As Long, iStartSeconds As Long
    m_bMouseUp = False
    If scrlVolume = 0 Then scrlVolume = SavedVolume     'Undo any mutes
    If scrlVolume > 0 Then scrlVolume = scrlVolume - 1: SavedVolume = scrlVolume
    iStartSeconds = CLng(GetTickCount() \ VolumeSpeed)  'VolumeSpeed modifies speed of changes
    Do While Not m_bMouseUp                             'Loop while button is down
        iEndSeconds = CLng(GetTickCount() \ VolumeSpeed) 'Uses counter to decide how much changes
        If iEndSeconds - iStartSeconds >= 1 Then
            iStartSeconds = iEndSeconds
            If scrlVolume > 0 Then scrlVolume = scrlVolume - 1: SavedVolume = scrlVolume
            If scrlVolume = 0 Then Exit Do              'Reached mute levels
        End If
        DrawVolume                                      'Draw the requested volume level
        DoEvents                                        'Do any events that need to be done
    Loop
End Sub

Private Sub cmdVolDown_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    'This routine tracks Mouse button push on the Volume and setvolume when user is done
    m_bMouseUp = True: SetVolume
End Sub

Private Sub cmdVolUp_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    'This routine tracks Mouse button push on the Volume and changes drawn volume.
    'Volume is set once the button is released.
    Dim iEndSeconds As Long, iStartSeconds As Long
    m_bMouseUp = False
    If scrlVolume = 0 Then scrlVolume = SavedVolume
    If scrlVolume < 100 Then scrlVolume = scrlVolume + 1: SavedVolume = scrlVolume
    iStartSeconds = CLng(GetTickCount() \ VolumeSpeed)
    Do While Not m_bMouseUp
        iEndSeconds = CLng(GetTickCount() \ VolumeSpeed)
        If iEndSeconds - iStartSeconds >= 1 Then
            iStartSeconds = iEndSeconds
            If scrlVolume < 100 Then scrlVolume = scrlVolume + 1: SavedVolume = scrlVolume
            If scrlVolume = 100 Then Exit Do
        End If
        DrawVolume
        DoEvents
    Loop
End Sub

Private Sub cmdVolUp_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    'This routine tracks Mouse button push on the Volume and setvolume when user is done
    m_bMouseUp = True: SetVolume
End Sub

Private Sub Form_Unload(Cancel As Integer)  'Unload the form
    Set RemoteFile = Nothing                'Clear the class
    EndWinsock                              'Make sure the Windows Sockets are not still open
    Do Until Web1Busy = False               'And now further commands are expected from server
        Web1Busy = False                    'Force failure
        DoEvents                            'And finish any left over processes
    Loop
    Set frmMusic = Nothing                  'Finally destroy the form
End Sub

Private Sub ClearPrevious()                 'Clear any Previous songs in the saved list
    Dim i As Long
    For i = 0 To 19: Previous(i) = -1: Next i    'Loop to clear them all
End Sub

Private Sub InsertPrevious(j As Long)       'Insert the song number into lsit
    Dim i As Long
    If j = -1 Then Exit Sub                 'No song selected?
    For i = 18 To 0 Step -1: Previous(i + 1) = Previous(i): Next i  'Loop to make insert point
    Previous(0) = j
End Sub

Private Function GetPrevious() As Long      'Get last Previously played song
    Dim i As Long
    If InPrevious(CLng(txtCurrentSong.Tag)) Then
        GetPrevious = Previous(1)               'Take from bottom of list
        For i = 0 To 17: Previous(i) = Previous(i + 2): Next i  'And move others down
        Previous(18) = -1: Previous(19) = -1    'Make sure last two are cleared out
    Else
        GetPrevious = Previous(0)               'Take from bottom of list
        For i = 0 To 18: Previous(i) = Previous(i + 1): Next i  'And move others down
        Previous(19) = -1                       'Make sure last one is cleared out
    End If
End Function

Private Function InPrevious(j As Long) As Boolean   'Search for song in Previous list
    Dim i As Long
    InPrevious = False                              'By Default we do not find it
    For i = 0 To 19
        If Previous(i) = -1 Then Exit For           'not found so exit
        If Previous(i) = j Then InPrevious = True: Exit For   'Is this the song?
    Next i
End Function

Private Sub SortArtistList()                        'SimpleSort of Artists List
    Dim i As Long, j As Long, tmpStr As String
    For i = 0 To ArtistsCount - 1
        For j = 0 To ArtistsCount - 1
            If UCase(ListArtists(i)) < UCase(ListArtists(j)) Then
                tmpStr = ListArtists(i)
                If tmpStr <> "" And ListArtists(j) <> "" Then
                    ListArtists(i) = ListArtists(j)
                    ListArtists(j) = tmpStr
                End If
            End If
        Next j
    Next i
End Sub

Private Sub AddArtist(addStr As String)     'Build the Artists ListBox, no duplicates
    Dim i As Long, blnFound As Boolean
    blnFound = False                                    'By default this is a new Artists
    For i = 0 To ArtistsCount
        If ListArtists(i) = addStr Then blnFound = True 'Opps, it is a duplicate
    Next i
    If Not blnFound And Trim(addStr) <> "" Then         'If this is a new Aritst
        ListArtists(ArtistsCount) = addStr              'Add it to Listbox
        ArtistsCount = ArtistsCount + 1                 'and up the Counter
    End If
End Sub

Private Sub BuildSongTypeList()             'Build the Category Listbox, no duplicates
    Dim i As Long, AlreadyAddedItems As String
    AlreadyAddedItems = ""                  'Track all the Categories already added
    lstSongTypes.Clear: lstSongTypes.Visible = False    'Clear and hide Listbox for speed
    For i = 0 To ListLen - 1
        If InStr(1, AlreadyAddedItems, ListSongType(i)) = 0 Then    'Do we have this Category?
            If AlreadyAddedItems = "" Then              'If not, is this the first added?
                AlreadyAddedItems = ListSongType(i)     'If it is, just add it to tracking list
            Else                                        'Otherwise add it with a comma
                AlreadyAddedItems = AlreadyAddedItems & "," & ListSongType(i)
            End If
            lstSongTypes.AddItem ListSongType(i)        'Add Category to Listbox
        End If
    Next i
    lstSongTypes.Visible = True                         'Unhide Listbox
End Sub

Private Sub lstPlayQue_DblClick()       'Will move the selected Que entry to top of Que
    Dim i As Long, tempSong As String
    i = lstPlayQue.ListIndex                'Find selected song in Que
    tempSong = lstPlayQue.List(i)           'Save it
    lstPlayQue.List(i) = lstPlayQue.List(0) 'Move the first entry to this place
                                            'If selected song already Sent, clear to send again
    If Left(tempSong, 7) = "(Sent) " Then tempSong = Right(tempSong, Len(tempSong) - 7)
    lstPlayQue.List(0) = tempSong           'Finally put selected song at top of Que
End Sub

Private Sub lstSongs_DblClick()         'User wants to add song to Que or play it immediately
    Dim SongIndex As Long, i As Long
    If chkRandomPlay Then               'if in Random mode then must play track immediately
        SongIndex = 0
        For i = 0 To ListLen - 1
            If Left(Trim(ListS(i)), Len(Trim(ListS(i))) - 1) = Right(lstSongs, Len(lstSongs) - 7) Then
                SongIndex = ListI(i)
                CurrentSong = ListS(i)
                CurrentSongType = ListSongType(i)
                txtCurrentSong = "Playing: " & ListS(i)
                txtCurrentSong.Tag = SongIndex
                Exit For
            End If
        Next i
        If SongIndex <> 0 Then WebCmdSilent "winamp:play:playlist:" & SongIndex + 1
    Else
        lstPlayQue.AddItem lstSongs     'Not in Random Mode, add to Que
    End If
End Sub

Private Sub lstSongs_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = vbRightButton Then PopupMenu mnuSongs
End Sub

Private Sub lstSongTypes_Click()        'Filter by Categories
    Dim tmpType As String, i As Long, ArtistIndex As Long
    lstSongTypes.ForeColor = Yellow: lstArtists.ForeColor = White   'Set colors
    lstSongs.Clear                      'Clear the Songs list
    AllSongs = False                    'Make sure filters are now Active
    SongTypeFilter = ""                 'Start with new filter selections
    For i = 0 To lstSongTypes.ListCount - 1 'Find which ones are selected and add to list
        If lstSongTypes.Selected(i) Then SongTypeFilter = SongTypeFilter & lstSongTypes.List(i) & "~~"
    Next i
    FillSongsList                       'Now add all the songs to Listbox based on Filters
    If SongTypeFilter <> "" Then txtCurrentSong.Tag = -1 'Force Timer1 to check song playing
End Sub

Private Sub lstArtists_Click()          'Filter by Artists
    Dim tmpType() As String, i As Long, ArtistIndex As Long
    lstSongTypes.ForeColor = White: lstArtists.ForeColor = Yellow   'Set colors
    lstSongs.Clear                      'Clear the Songs list
    AllSongs = False                    'Make sure filters are now Active
    ArtistFilter = ""                   'Start with new filter selections
    For i = 0 To lstArtists.ListCount - 1 'Find which ones are selected and add to list
        If lstArtists.Selected(i) Then ArtistFilter = ArtistFilter & lstArtists.List(i) & "~~"
    Next i
    FillSongsList                       'Now add all the songs to Listbox based on Filters
    If ArtistFilter <> "" Then txtCurrentSong.Tag = -1 'Force Timer1 to check song playing
End Sub

Private Sub FillSongsList()             'Repopulates Song Listbox after Filters
Dim tmpSongType As String, tmpArtist() As String, i As Long
    For i = 0 To ListLen - 1
        tmpSongType = ListSongType(i) & "~~"
        If SongTypeFilter = "" Or InStr(1, SongTypeFilter, tmpSongType, vbBinaryCompare) Then
            tmpArtist = Split(ListS(i), "-")
            If ArtistFilter = "" Or InStr(1, ArtistFilter, Trim(tmpArtist(0)) & "~~", vbBinaryCompare) Then
                lstSongs.AddItem CStr(Format(i + 1, "0000")) & ".  " & ListS(i)
            End If
        End If
    Next i
End Sub

Private Sub mnuRefresh_Click()          'Refresh list on right button menu click
    RefreshList
End Sub

Private Sub optLightControl_Click()     'Wants to change to Light control screen
    If Section1 Then
        frmMusic.TimerStop              'Stop music form's Timers
        frmMain.Show                    'Show Light control screen
        frmMusic.Hide                   'Hide music form
        frmMain.optLightControl_Click   'Click the Light screen button to initialize it
        frmMain.TimerStart              'Turn on Light screen's Timers
    End If
End Sub

Private Sub optWebControl_Click()       'Wants to change to Web screen
    If Section3 Then
        frmMusic.TimerStop              'Stop music form's Timers
        frmWeb.Show                     'Show Web screen
        frmMusic.Hide                   'Hide music form
        frmWeb.TimerStart               'Turn on Web screen's Timers
    End If
End Sub

Private Sub optMediaControl_Click()     'Wants to change to Media Control screen
    If Section4 Then
        frmMusic.TimerStop                      'Stop music form's Timers
        frmMediaControl.Show                    'Show Media Control screen
        frmMusic.Hide                           'Hide music form
        frmMediaControl.TimerStart              'Turn on Media Control screen's Timers
    End If
End Sub

Private Sub optServer1_Click()          'User has picked the first server
    optServer1.Value = True
    optServer2.Value = False
    optServer3.Value = False
    optServer4.Value = False
    PickServer (1)
End Sub

Private Sub optServer2_Click()          'User has picked the second server
    optServer1.Value = False
    optServer2.Value = True
    optServer3.Value = False
    optServer4.Value = False
    PickServer (2)
End Sub

Private Sub optServer3_Click()          'User has picked the third server
    optServer1.Value = False
    optServer2.Value = False
    optServer3.Value = True
    optServer4.Value = False
    PickServer (3)
End Sub

Private Sub optServer4_Click()          'User has picked the fourth server
    optServer1.Value = False
    optServer2.Value = False
    optServer3.Value = False
    optServer4.Value = True
    PickServer (4)
End Sub

Private Function StatusDecode(s As String) As Long  'Decodes the Status message to a number
    StatusDecode = Status
    If s = "PAUSED" Then StatusDecode = 3
    If s = "PLAYING" Then StatusDecode = 1
    If s = "STOPPED" Then StatusDecode = 0
End Function

Public Sub TimerStart()             'Turn Timers back on
    Timer1.Enabled = True:  Timer2.Enabled = True
End Sub

Public Sub TimerStop()              'Turn Timers off
    Timer1.Enabled = False:  Timer2.Enabled = False
End Sub

Private Sub SetVolume()                         'Tell server to actually enact selected volume
    If scrlVolume < 0 Then scrlVolume = 0       'Should never be less than zero
    If scrlVolume > 100 Then scrlVolume = 100   'or greater than 100
    If VolType = 1 Then                         'Winamp type volume then use number 0-255
        WebCmdSilent "winamp:setvolume:" & CLng(255 * (scrlVolume / 100))
    Else                                        'Otherwise just send it as a normal % volume
        WebCmdSilent "cmd:setvolume:" & scrlVolume
    End If
    DrawVolume                                  'Update screen to match selected volume
End Sub

Private Sub DrawVolume()                        'Draws the volume bar on the screen
    If scrlVolume = 0 Then                      'Must be muted, so hide the volume bar
        line_Volume_Low.Visible = False
        line_Volume_Middle.Visible = False
        line_Volume_High.Visible = False
    ElseIf scrlVolume <= 33 Then                'First third only
        line_Volume_Low.X2 = line_Volume_Low.X1 + FullVol * (scrlVolume / 33)
        line_Volume_Low.Visible = True
        line_Volume_Middle.Visible = False
        line_Volume_High.Visible = False
    ElseIf scrlVolume <= 67 Then                'Middle section, first third is full
        line_Volume_Middle.X2 = line_Volume_Low.X1 + 2 * (FullVol) * (scrlVolume / 67)
        line_Volume_Low.X2 = line_Volume_Low.X1 + FullVol
        line_Volume_Low.Visible = True
        line_Volume_Middle.Visible = True
        line_Volume_High.Visible = False
    Else                                        'Top part only, first two sections filled
        line_Volume_High.X2 = line_Volume_Low.X1 + 3 * (FullVol) * (SavedVolume / 100)
        line_Volume_Middle.X2 = line_Volume_Low.X1 + 2 * (FullVol)
        line_Volume_Low.X2 = line_Volume_Low.X1 + FullVol
        line_Volume_Low.Visible = True
        line_Volume_Middle.Visible = True
        line_Volume_High.Visible = True
    End If
End Sub

Private Function GetSongType(txtFile As String) As String   'Decodes the Category from Filename
    Dim i As Long, j As Long
    j = InStr(1, StrReverse(txtFile), "\")                  'Find the rightmost "\"
    i = InStr(j + 1, StrReverse(txtFile), "\")              'Find the 2nd rightmost "\"
    j = Len(txtFile) - j + 1: i = Len(txtFile) - i + 2      'i & j define directory name bounds
    If j > i And j <> 0 And i <> 0 Then                     'If i & j are valid,
        GetSongType = Mid(txtFile, i, j - i)                '   get the Category
    Else
        GetSongType = "Other"                               'Otherwise, set to Other
    End If
End Function

Public Function gc(n As String) As Control      'Generic function to get the handle to a control
    Dim tempctl As Control                      '  given its name
    For Each tempctl In frmMusic                'Loop thru the form to find the control
        If tempctl.Name = n Then Set gc = tempctl: Exit For 'save its handle to return
    Next tempctl
End Function

Private Sub SkinMe(Section As String, frm As Form)  'This will skin the screen
    Dim ctl As Control, temptag As String, FontMod As Long
    Dim pos As Variant, size As Variant, c As Variant
    
    fReadValue inifile, "Options", "Skin", "S", "", Skin
    If Skin = "" Then Exit Sub
    SkinPath = App.Path & "\skin\" & Skin & "\"
    Skin = SkinPath & "skin.ini"
    fReadValue Skin, Section, "FontSizeMod", "S", "0", temptag
    FontMod = Val(temptag)
    For Each ctl In frm
        On Error Resume Next
        Err.Clear
        fReadValue Skin, Section, "Image_" & ctl.Name, "S", "", temptag
        If LCase(temptag) = "none" Then ctl.Picture = LoadPicture(): temptag = ""
        If temptag <> "" Then ctl.Picture = LoadPicture(SkinPath & temptag)
        If Err.Number <> 0 Then Err.Clear
        ctl.FontSize = ctl.FontSize + FontMod
        If Err.Number <> 0 Then Err.Clear
        fReadValue Skin, Section, "PosXY_" & ctl.Name, "S", "", temptag
        If temptag <> "" Then
            pos = Split(temptag, ",", 2)
            If Err.Number <> 0 Then Err.Clear
            ctl.Move pos(0), pos(1)
            If Err.Number <> 0 Then Err.Clear
        End If
        
        fReadValue Skin, Section, "FontName_" & ctl.Name, "S", "", temptag
        If temptag <> "" Then ctl.Font = temptag
        If Err.Number <> 0 Then Err.Clear
        
        fReadValue Skin, Section, "FontColorRGB_" & ctl.Name, "S", "", temptag
        c = Split(temptag, ",")
        If Err.Number <> 0 Then Err.Clear: temptag = ""
        If temptag <> "" Then
            ctl.ForeColor = RGB(c(0), c(1), c(2))
            If Err.Number <> 0 Then Err.Clear
        End If
        
        fReadValue Skin, Section, "FontSize_" & ctl.Name, "S", "", temptag
        If temptag <> "" Then ctl.FontSize = Val(temptag)
        If Err.Number <> 0 Then Err.Clear
        
        fReadValue Skin, Section, "BorderColorRGB_" & ctl.Name, "S", "", temptag
        c = Split(temptag, ",")
        If Err.Number <> 0 Then Err.Clear: temptag = ""
        If temptag <> "" Then
            ctl.BorderColor = RGB(c(0), c(1), c(2))
            If Err.Number <> 0 Then Err.Clear
        End If
        
        fReadValue Skin, Section, "BackColorRGB_" & ctl.Name, "S", "", temptag
        If LCase(temptag) = "none" Then
            ctl.BackStyle = 0
            If Err.Number <> 0 Then Err.Clear
        Else
            If temptag <> "" Then ctl.BackStyle = 1
            If Err.Number <> 0 Then Err.Clear
        End If
        c = Split(temptag, ",")
        If Err.Number <> 0 Then Err.Clear: temptag = ""
        If temptag <> "" Then
            ctl.BackColor = RGB(c(0), c(1), c(2))
            If Err.Number <> 0 Then Err.Clear
        End If
        
        fReadValue Skin, Section, "SizeWH_" & ctl.Name, "S", "", temptag
        If temptag <> "" Then
            size = Split(temptag, ",", 2)
            If Err.Number <> 0 Then Err.Clear
            ctl.Move ctl.Left, ctl.Top, size(0), size(1)
            If Err.Number <> 0 Then Err.Clear
            
            If Left(ctl.Name, 5) = "line_" Then
                ctl.X1 = pos(0): ctl.X2 = pos(0) + size(0)
                ctl.Y1 = pos(1): ctl.Y2 = pos(1): FullVol = size(0)
            End If
        End If
    Next ctl
    
    fReadValue Skin, Section, "Background", "S", "", temptag
    If temptag <> "" Then frm.Picture = LoadPicture(SkinPath & temptag)
End Sub

Private Sub PrintControl(frm As Form, sect As String)   'Used to produce new skins
    Dim c As Control, x As String, temptag As String    '  really only in VB's IDE though
    Skin = "": SkinPath = ""
    fReadValue inifile, "Options", "Skin", "S", "", Skin
    If Skin = "" Then Exit Sub
    SkinPath = App.Path & "\skin\" & Skin & "\"
    Skin = SkinPath & "skin.ini"
    For Each c In frm
        x = c.Name
        If LCase(Left(x, 5)) <> "timer" And LCase(Left(x, 5)) <> "winso" And LCase(Left(x, 5)) <> "line_" Then
            x = "PosXY_" & c.Name
            fReadValue Skin, sect, x, "S", "err", temptag
            If temptag <> "err" Then fWriteValue Skin, sect, x, "S", c.Left & "," & c.Top
            x = "SizeWH_" & c.Name
            fReadValue Skin, sect, x, "S", "err", temptag
            If temptag <> "err" Then fWriteValue Skin, sect, x, "S", c.Width & "," & c.Height
            x = "FontSize_" & c.Name
            fReadValue Skin, sect, x, "S", "err", temptag
            If temptag <> "err" Then fWriteValue Skin, sect, x, "S", c.FontSize
            x = "FontColorRGB_" & c.Name
            fReadValue Skin, sect, x, "S", "err", temptag
            If temptag <> "err" Then fWriteValue Skin, sect, x, "S", RGBS(c.ForeColor)
            x = "BorderColorRGB_" & c.Name
            fReadValue Skin, sect, x, "S", "err", temptag
            If temptag <> "err" Then fWriteValue Skin, sect, x, "S", RGBS(c.BorderColor)
            x = "BackColorRGB_" & c.Name
            fReadValue Skin, sect, x, "S", "err", temptag
            If temptag <> "err" Then fWriteValue Skin, sect, x, "S", RGBS(c.BackColor)
            Debug.Print "Sent Music - " & c.Name
        End If
        If LCase(Left(x, 5)) = "line_" Then
            x = "PosXY_" & c.Name
            fReadValue Skin, sect, x, "S", "err", temptag
            If temptag <> "err" Then fWriteValue Skin, sect, x, "S", c.X1 & "," & c.Y1
            x = "SizeWH_" & c.Name
            fReadValue Skin, sect, x, "S", "err", temptag
            If temptag <> "err" Then fWriteValue Skin, sect, x, "S", (c.X2 - c.X1) & "," & (c.Y2 - c.Y1)
        End If
    Next c
End Sub

Private Function WebCmd1(strURL As String) As String    'Sends command to server and
    Dim tmpStr As String                                '  gets an answer
    Do While Web1Busy               'Are we already running another Web command?
        DoEvents                    'if yes, loop until it is cleared
    Loop
    tmpStr = FetchURL(strURL)       'Call the actual Fetch routine with Command, get answer
    If Len(tmpStr) > 3 Then         'hopefully the answer is always greater than 3 characters
        tmpStr = Replace(Replace(tmpStr, Header, ""), Footer, "")   'Remove Header and Footer
    End If
    WebCmd1 = tmpStr                'Return the answer
End Function

Private Function WebCmdSilent(strURL As String)         'Sends command to server and
    Dim tmpStr As String                                '  ignores the answer
    Do While Web1Busy               'Are we already running another Web command?
        DoEvents                    'if yes, loop until it is cleared
    Loop
    tmpStr = FetchURL(strURL)       'Call the actual Fetch routine with Command
End Function

Private Function FetchURL(tmpStr As String) As String   'Here is actual routine to talk to server
RestartURL:                         'Return here on retries, stopped by Timer1 after 10 seconds
    Web1Busy = True                 'Set the Web1Busy flag so we don't step on each other
    Web1Response = ""               'Clear the response variable
    With RemoteFile                 'Use the Web communication class object to...
        .DownloadType = dtToBuffer  'Set the Type to Buffer - best for our transmissions
        .AutoRedirect = True        'Really doesn't matter but should be set anyway
        .AllowCache = False         'Do not want to cache pages or we will get lots of bad data
        .UseResume = False          'Clear the Resume flag so we can safely Disconnect
        .Disconnect                 'Make sure any current connections are cleared
        .UseHttpAuthorization = True    'Really doesn't matter but should be set anyway
        .UseResume = True           'Will try to resume failed downloads - rarely used
        'If we are getting the entire list then increase the packet size for speed
        If tmpStr = "winamp:playlist:title:all" Or tmpStr = "winamp:playlist:file:all" Then
            .PacketSize = 2048      '2K is probably enough.  Good for lists over 3000 songs
        Else
            .PacketSize = 1024      '1K is good for most communications
        End If
        .FetchURLString WebSvr & tmpStr 'Set the URL to be sent
        .MaxDownload = -1               'There is no limit on the size of the message we can get
    End With
    Do While Web1Busy               'Now loop until we get a complete answer
        DoEvents                    'Be sure to keep doing normal events
    Loop
    If Web1Response = "error" Or Web1Response = "" Then GoTo RestartURL  'Retry
    FetchURL = Web1Response         'Send Response
    Web1Response = ""               'Clear it for the next message
End Function

Private Sub RemoteFile_Disconnected(ID As Long)     'Event fired when Disconnected
    If RemoteFile.DownloadType = dtToBuffer Then    'If we are using buffer then
        Web1Response = RemoteFile.GetBufferAsString 'get the message and
        RemoteFile.ClearBuffer                      'clear it
    End If
    Web1Busy = False                                'No longer waiting for answer!
End Sub

Private Sub RemoteFile_DownloadFailed(Why As DOWNLOAD_FAILURE, ID As Long)
    'Uhoh... the download failed :(
    If Dbg Then If MsgBox("Communication failure:" & vbCrLf & RemoteFile.FailureToString(Why) & vbCrLf & vbCrLf & "Do you want to quit?", vbYesNo + vbExclamation, "Comm failure.") = vbYes Then End: Exit Sub
    Web1Response = "error"                          'This will trigger a retry
    Web1Busy = False                                'No longer waiting for answer!
End Sub

