001/*
002 *  $Source: /cvsroot2/open/projects/jOggPlayer/ca/bc/webarts/widgets/PlayList.java,v $
003 *  $Name:  $
004 *  $Revision: 551 $
005 *  $Date: 2012-06-19 19:02:26 -0700 (Tue, 19 Jun 2012) $
006 *  $Locker:  $
007 */
008/*
009 *  PlayList -- A helper widget class used with the jOggPlayer.
010 *
011 *  Written by Tom Gutwin - WebARTS Design.
012 *  Copyright (C) 2001-2012 WebARTS Design, North Vancouver Canada
013 *  http://www..webarts.bc.ca/jOggPlayer
014 *
015 *  This program is free software; you can redistribute it and/or modify
016 *  it under the terms of the GNU General Public License as published by
017 *  the Free Software Foundation; either version 2 of the License, or
018 *  (at your option) any later version.
019 *
020 *  This program is distributed in the hope that it will be useful,
021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
023 *  GNU General Public License for more details.
024 *
025 *  You should have received a copy of the GNU General Public License
026 *  along with this program; if not, write to the Free Software
027 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
028 */
029package ca.bc.webarts.widgets;
030
031import ca.bc.webarts.widgets.Util;
032import ca.bc.webarts.widgets.VorbisInfo;
033import ca.bc.webarts.tools.JOrbisComment;
034
035import java.io.File;
036import java.io.FileWriter;
037import java.io.IOException;
038import java.io.InputStream;
039import java.net.MalformedURLException;
040import java.net.URL;
041import java.net.URLConnection;
042
043import java.util.Arrays;
044import java.util.Comparator;
045import java.util.Vector;
046import javax.swing.JCheckBox;
047
048import javax.swing.JPanel;
049
050
051/**
052 *  A simple class to encapsulate the storage of references to Ogg files in a
053 *  Playlist style.
054 *
055 * @author     tgutwin
056 * @created    April 4, 2002
057 */
058public class PlayList
059{
060
061  /**  Description of the Field */
062  private static final String SYSTEM_FILE_SEPERATOR = File.separator;
063  /**  This is the meat of the class; it holds OggFileRef objects. **/
064  private Vector songs = null;
065
066
067  /**  basic constructor to initialize things. * */
068  public PlayList()
069  {
070    songs = new Vector();
071  }
072
073
074  /**
075   *  Constructor to get things init and load up an initial list of URLs *
076   *
077   * @param  urls  Description of the Parameter
078   */
079  public PlayList( URL[] urls )
080  {
081    songs = new Vector();
082//      System.out.println("*** Creating a NEW PlayList "+urls.length);
083    if ( urls != null )
084    {
085      for ( int i = 0; i < urls.length; i++ )
086      {
087        songs.add( new OggFileRef( urls[i] ) );
088      }
089    }
090  }
091
092
093  /**
094   *  Parses the passed filenames looking for OGG files. It will recurse
095   *  directories if a dir is in the passed array.
096   *
097   * @param  fileNames  an array containg files and/or dir names to parse for
098   *      OGG files.
099   * @return            an array of OGG files that have been found within the
100   *      passed in array of filenames.
101   */
102  public static String[] getPlaylistArray( String[] fileNames )
103  {
104    String[] retVal = null;
105    if ( fileNames != null )
106    {
107      Vector v = getPlaylistVector( fileNames );
108      int size = v.size();
109      retVal = new String[size];
110//      System.out.println("Loading PlayList... "+size);
111      if ( size > 0 )
112      {
113        for ( int i = 0; i < size; i++ )
114        {
115          retVal[i] = v.get( i ).toString();
116        }
117      }
118    }
119    return retVal;
120  }
121
122
123  /**
124   *  Parses the passed filenames looking for OGG files. It will recurse
125   *  directories if a dir is in the passed array.
126   *
127   * @param  fileNames  an array containg files and/or dir names to parse for
128   *      OGG files.
129   * @return            a vector of OGG files that have been found within the
130   *      passed in array of filenames.
131   */
132  public static Vector getPlaylistVector( String[] fileNames )
133  {
134    Vector retVal = new Vector();
135    File f;
136    if ( fileNames != null )
137    {
138//      System.out.println("Loading Vector... "+fileNames.length);
139      for ( int i = 0; i < fileNames.length; i++ )
140      {
141        f = new File( fileNames[i].trim() );
142        //System.out.print(" "+i+"> " +fileNames[i]);
143        if ( f.isDirectory() )
144        {
145          // && checkBoxRecursePlaylist.isSelected() )
146
147          // fill from dir
148          File oggDir = new File( fileNames[i] );
149//          playListDir_ = fileNames[i];
150          String[] oggDirFiles = oggDir.list();
151          for ( int j = 0; j < oggDirFiles.length; j++ )
152          {
153            oggDirFiles[j] = fileNames[i].trim() +
154                ( fileNames[i].endsWith( SYSTEM_FILE_SEPERATOR ) ?
155                "" : SYSTEM_FILE_SEPERATOR ) +
156                oggDirFiles[j];
157          }
158          // recurse on the dir
159          //System.out.println(" is a Directory");
160          retVal.addAll( getPlaylistVector( oggDirFiles ) );
161        }
162        else if ( fileNames[i].trim().toUpperCase().endsWith( ".OGG" ) )
163        {
164          //System.out.println(" is a File");
165          retVal.addElement( fileNames[i] );
166        }
167        else if ( fileNames[i].trim().toUpperCase().endsWith( ".M3U" ) ||
168            fileNames[i].trim().toUpperCase().endsWith( ".PLS" ) )
169        {
170          //System.out.println(" is a Playlist");
171          retVal.addAll( getPlaylistVector( Util.getFileBaseURL( fileNames[i] ) ) );
172        }
173      }
174    }
175    return retVal;
176  }
177
178
179  /**
180   *  Parses the passed URL as a plylist looking for OGG files.
181   *
182   * @param  playlistURL  a URL pointing at a playlist file.
183   * @return              a vector of OGG files that have been found within the
184   *      passed in URL.
185   */
186  public static Vector getPlaylistVector( URL playlistURL )
187  {
188    Vector retVal = new Vector();
189
190    InputStream is = null;
191    if ( playlistURL != null )
192    {
193      /*
194       *  get the file ready to read
195       */
196      try
197      {
198        // load it as a URL
199
200        URLConnection urlc = playlistURL.openConnection();
201        // throws IOException
202        is = urlc.getInputStream();
203
204        /*
205         *  Now load the songs listed
206         */
207        String line = null;
208        int indx = -1;
209        // check each time if the is has not disappeared
210        while ( is != null &&
211            ( line = readline( is ) ) != null )
212        {
213          if ( line.indexOf( "#EXTM3U" ) == -1 )
214          {
215            try
216            {
217              indx = line.indexOf( "=" );
218              if ( indx != -1 )
219              {
220                retVal.add( new URL( line.substring( indx + 1 ) ) );
221              }
222              else
223              {// just assume its a URL all on its own
224                retVal.add( new URL( line ) );
225              }
226            }
227            catch ( MalformedURLException ee )
228            {
229              // NOTHING JUST GO TO NEXT to save load time
230            }
231          }
232        }
233      }
234      catch ( MalformedURLException ee )
235      {
236        System.out.println( "The Playlist Filename has some errors. " +
237            "Please check the filename." );
238      }
239      catch ( IOException ee )
240      {
241        System.out.println( "The Playlist Filename cannot be read." );
242      }
243    }
244    if (is != null)
245      try{is.close();}catch(IOException ioEx){}
246
247    return retVal;
248  }
249
250
251  /**
252   *  Reads a single line from the InputStream.
253   *
254   * @param  is  Description of the Parameter
255   * @return     the line read as a String
256   */
257  private static String readline( InputStream is )
258  {
259    StringBuffer rtn = new StringBuffer();
260    int temp;
261    do
262    {
263      try
264      {
265        temp = is.read();
266      }
267      catch ( Exception e )
268      {
269        return ( null );
270      }
271      if ( temp == -1 )
272      {
273        return ( null );
274      }
275      if ( temp != 0 && temp != '\n' )
276      {
277        rtn.append( (char)temp );
278      }
279    } while ( temp != '\n' );
280    return ( rtn.toString() );
281  }
282
283
284  /**
285   *  Gets the songNamesVector attribute of the PlayList object
286   *
287   * @return    The songNamesVector value
288   */
289  public Vector getSongNamesVector()
290  {
291    int size = songs.size();
292    Vector retVal = new Vector();
293//      System.out.println("SongNamesVectorSize="+size);
294    for ( int i = 0; i < size; i++ )
295    {
296      retVal.add( ( (OggFileRef)( songs.get( i ) ) ).name_ );
297    }
298    return retVal;
299  }
300
301
302  /**
303   *  Gets the songNames attribute of the PlayList object
304   *
305   * @return    The songNames value
306   */
307  public String[] getSongFileNames()
308  {
309    int size = songs.size();
310    String[] retVal = new String[size];
311    for ( int i = 0; i < size; i++ )
312    {
313      retVal[i] = ( (OggFileRef)( songs.get( i ) ) ).name_;
314    }
315    return retVal;
316  }
317
318
319  /**
320   *  Gets an array of the song titles.
321   *
322   * @return    The song title values in an array
323   */
324  public String[] getSongTitles()
325  {
326    int size = songs.size();
327    String[] retVal = new String[size];
328    for ( int i = 0; i < size; i++ )
329    {
330      retVal[i] = ( (OggFileRef)( songs.get( i ) ) ).getTitle();
331    }
332    return retVal;
333  }
334
335
336  /**
337   *  Gets an array of the song hashes consisting of the songs ArtistAlbumTrackTitle.
338   *
339   * @return    The song songs ArtistAlbumTrackTitlevalues in an array
340   */
341  public String[] getSongHashes()
342  {
343    int size = songs.size();
344    //String[] retVal = new String[size];
345    //for ( int i = 0; i < size; i++ )
346    //{
347    //  retVal[i] = ( (OggFileRef)( songs.get( i ) ) ).getArtistAlbumTrackTitle();
348    //}
349    return getSongHashes(size);
350  }
351
352
353  /**
354   *  Gets an array of the song hashes consisting of the songs ArtistAlbumTrackTitle starting at position 0 in the Playlist..
355   *
356   * @param maxSize is the number of songs to process in this call
357   * @return    The song songs ArtistAlbumTrackTitlevalues in an array in an array of size less than or equal to maxSize
358   */
359  public String[] getSongHashes(int maxSize)
360  {
361    int size = songs.size();
362    return getSongHashes(0, size);
363  }
364
365
366  /**
367   *  Gets an array of the song hashes consisting of the songs ArtistAlbumTrackTitle.
368   *
369   * @param startSpot is the starting position in the songs Vectorto start the retireval at
370   * @param maxSize is the number of songs to process in this call
371   * @return    The song songs ArtistAlbumTrackTitlevalues in an array of size less than or equal to maxSize
372   */
373  public String[] getSongHashes(int startSpot, int maxSize)
374  {
375    int size = songs.size();
376    if (maxSize >= size) maxSize = size;
377    if (maxSize < 1 ) maxSize = 1;
378    if (startSpot < 0 ) startSpot = 0;
379    if (startSpot > size ) startSpot = size;
380    String[] retVal = new String[maxSize];
381    for ( int i = startSpot; i < maxSize; i++ )
382    {
383      retVal[i-startSpot] = ( (OggFileRef)( songs.get( i ) ) ).getArtistAlbumTrackTitle();
384    }
385    return retVal;
386  }
387
388
389  /**
390   *  Gets an array of the song hashes consisting of the songs ArtistAlbumTrackNum.
391   *
392   * @return    The song songs ArtistAlbumTrackNum values in an array
393   */
394  public String[] getSongNumHashes()
395  {
396    int size = songs.size();
397    return getSongNumHashes(0, size);
398  }
399
400
401  /**
402   *  Gets an array of the song hashes consisting of the songs ArtistAlbumTrackNum.
403   *
404   * @param startSpot is the starting position in the songs Vectorto start the retireval at
405   * @param maxSize is the number of songs to process in this call
406   * @return    The song songs ArtistAlbumTrackNum values in an array
407   */
408  public String[] getSongNumHashes(int startSpot, int maxSize)
409  {
410    int size = songs.size();
411    if (maxSize >= size) maxSize = size;
412    if (maxSize < 1 ) maxSize = 1;
413    if (startSpot < 0 ) startSpot = 0;
414    if (startSpot > size ) startSpot = size;
415    String[] retVal = new String[maxSize];
416    for ( int i = startSpot; i < maxSize; i++ )
417    {
418      retVal[i-startSpot] = ( (OggFileRef)( songs.get( i ) ) ).getArtistAlbumTrackNum();
419    }
420    return retVal;
421  }
422
423
424  /**
425   *  Gets the song Name Comment attribute of the selected Song object or the filename
426   *
427   * @param  songIndex  The index for the songname to retrieve
428   * @return            The title comment value or filename if null
429   */
430  public String getSongName( int songIndex )
431  {
432    String retVal = ( (OggFileRef)( songs.get( songIndex ) ) ).getTitle();
433    if (retVal.equals("")) retVal = ( (OggFileRef)( songs.get( songIndex ) ) ).name_;
434    return retVal;
435  }
436
437
438  /**
439   *  Gets the song file Name attribute of the selected Song object
440   *
441   * @param  songIndex  The index for the songname to retrieve
442   * @return            The songName value
443   */
444  public String getSongFileName( int songIndex )
445  {
446    String retVal = "";
447    retVal = ( (OggFileRef)( songs.get( songIndex ) ) ).name_;
448    return retVal;
449  }
450
451
452  /**
453   *  Sets the song Name comment of the selected Song object
454   *
455   * @param  songIndex  The index for the songname to retrieve
456   * @param  name    The name to set
457   * @return            The songName value
458   */
459  public void setSongName( int songIndex, String name )
460  {
461    setTitle(songIndex, name );
462  }
463
464
465  /**
466   *  Sets the song Name comment of the selected Song object
467   *
468   * @param  songIndex  The index for the songname to retrieve
469   * @param  name    The name to set
470   * @return            The songName value
471   */
472  public void setTitle( int songIndex, String name )
473  {
474    if (songs != null)
475    {
476      ( (OggFileRef)( songs.get( songIndex ) ) ).setTitle(name);
477    }
478  }
479
480
481  /**
482   *  Sets the song Artist comment of the selected Song object
483   *
484   * @param  songIndex  The index for the songname to retrieve
485   * @param  name    The name to set
486   * @return            The songName value
487   */
488  public void setArtist( int songIndex, String name )
489  {
490    if (songs != null)
491    {
492      ( (OggFileRef)( songs.get( songIndex ) ) ).setArtist(name);
493    }
494  }
495
496
497  /**
498   *  Gets the URL attribute of the selected Song object
499   *
500   * @param  songIndex  The index for the song to retrieve
501   * @return            The URL for the spec'd song value
502   */
503  public URL getSongUrl( int songIndex )
504  {
505    URL retVal = null;
506    retVal = ( (OggFileRef)( songs.get( songIndex ) ) ).url_;
507    return retVal;
508  }
509
510
511  /**
512   *  Gets the songUrls attribute of the PlayList object
513   *
514   * @return    The songUrls value
515   */
516  protected URL[] getSongUrls()
517  {
518    int size = songs.size();
519
520    URL[] retVal = new URL[size];
521    for ( int i = 0; i < size; i++ )
522    {
523      retVal[i] = getSongUrl(i);
524    }
525    return retVal;
526  }
527
528
529  /**
530   *  Gets the uRL attribute of the PlayList object
531   *
532   * @param  songName  Description of the Parameter
533   * @return           The uRL value
534   */
535  public URL getURL( String songName )
536  {
537    URL retVal = null;
538    if ( songName != null )
539    {
540      for ( int i = 0; i < songs.size(); i++ )
541      {
542        if ( ( (OggFileRef)( songs.get( i ) ) ).name_.equals( songName ) )
543        {
544          retVal = ( (OggFileRef)songs.get( i ) ).url_;
545          break;
546        }
547      }
548    }
549    return retVal;
550  }
551
552
553  /**  Sorts the Playlist Alphabetically. */
554  public void sortSongs()
555  {
556    sortSongsByFilename();
557    //sortSongsByArtistAlbumTrackNum();
558  }
559
560
561  /**  Sorts the Playlist Alphabetically by its filenames. */
562  public void sortSongsByFilename()
563  {
564    Object [] songsArray = getSongFileNames();
565    // sorting alphabetically
566    Arrays.sort(songsArray, new Comparator()
567        {
568            public int compare(Object o1, Object o2)
569            {
570                return (((String) o1).toLowerCase().
571                        compareTo(((String) o2).toLowerCase()));
572            }
573        });
574
575    Vector sortedSongs = new Vector(songsArray.length);
576    for (int i = 0; i < songsArray.length; i++)
577    {
578      sortedSongs.add(i, songs.get(findSong((String)songsArray[i])));
579    }
580    songs = null;
581    songs = sortedSongs;
582  }
583
584
585  /**  Sorts the Playlist Alphabetically by its song titles. */
586  public void sortSongsBySongTitle()
587  {
588    Object [] songsTitlesArray = getSongTitles();
589    // sorting alphabetically
590    Arrays.sort(songsTitlesArray, new Comparator()
591        {
592            public int compare(Object o1, Object o2)
593            {
594                return (((String) o1).toLowerCase().
595                        compareTo(((String) o2).toLowerCase()));
596            }
597        });
598
599    Vector sortedSongs = new Vector(songsTitlesArray.length);
600    for (int i = 0; i < songsTitlesArray.length; i++)
601    {
602      sortedSongs.add(i, songs.get(findSongByTitle((String)songsTitlesArray[i])));
603    }
604    songs = null;
605    songs = sortedSongs;
606  }
607
608
609  /**  Sorts the Playlist Alphabetically by its artistAlbumTrackTitle. */
610  public void sortSongsByArtistAlbumTrackTitle()
611  {
612    int chunkSize = 100;
613    int songsSize = songs.size();
614    int numchunks = songsSize/chunkSize;
615    Vector sortedSongs = new Vector();//songsArray.length);
616    int sortedI=0;
617    int hashedSongIndex = 0;
618    int i=0;
619    Comparator cmp = new Comparator()
620          {
621              public int compare(Object o1, Object o2)
622              {
623                  return (((String) o1).toLowerCase().
624                          compareTo(((String) o2).toLowerCase()));
625              }
626          };
627    System.out.println("sortSongsByArtistAlbumTrackTitle with chunkSize="+chunkSize);
628    for (int songChunk = 0; songChunk < numchunks; songChunk++)
629    {
630      Object [] songsArray = getSongHashes(songChunk*chunkSize, chunkSize);
631      Arrays.sort(songsArray, cmp);
632
633      hashedSongIndex = 0;
634      i=0;
635      while ( i < chunkSize)
636      {
637        hashedSongIndex = findSongByHash((String)songsArray[i]);
638        if (hashedSongIndex!=-1)
639        {
640          System.out.println(""+sortedI+") "+(String)songsArray[i]+"  "+hashedSongIndex);
641          sortedSongs.add(sortedI++, songs.get(hashedSongIndex ));
642        }
643        else
644        {
645          System.out.println("SKIPPING: "+(String)songsArray[i]+"  "+hashedSongIndex);
646        }
647        i++;
648      }
649    }
650    songs = null;
651    songs = sortedSongs;
652  }
653
654
655  /**  Sorts the Playlist Alphabetically by its artistAlbumTTrackNum. */
656  public void sortSongsByArtistAlbumTrackNum()
657  {
658    int songsSize = songs.size();
659    int chunkSize = songsSize; //100;
660    int numchunks = songsSize/chunkSize;
661    Vector sortedSongs = new Vector();//songsArray.length);
662    int sortedI=0;
663    int hashedSongIndex = 0;
664    int i=0;
665    Comparator cmp = new Comparator()
666          {
667              public int compare(Object o1, Object o2)
668              {
669                  return (((String) o1).toLowerCase().
670                          compareTo(((String) o2).toLowerCase()));
671              }
672          };
673    //System.out.println("sortSongsByArtistAlbumTrackTitle with chunkSize="+chunkSize);
674    for (int songChunk = 0; songChunk < numchunks; songChunk++)
675    {
676      //System.out.println("sorting songs="+songChunk*chunkSize+" to " + (songChunk*chunkSize+chunkSize-1));
677      Object [] songsArray = getSongNumHashes(songChunk*chunkSize, chunkSize);
678      Arrays.sort(songsArray, cmp);
679
680      sortedSongs = new Vector();//songsArray.length);
681      hashedSongIndex = 0;
682      i=0;
683      while ( i < chunkSize)
684      {
685        hashedSongIndex = findSongByNumHash((String)songsArray[i]);
686        if (hashedSongIndex!=-1)
687        {
688          //System.out.println(""+songChunk+"-"+sortedI+") "+(String)songsArray[i]+"  "+hashedSongIndex);
689          sortedSongs.add(sortedI++, songs.get(hashedSongIndex ));
690        }
691        else
692        {
693          //System.out.println("SKIPPING: "+(String)songsArray[i]+"  "+hashedSongIndex);
694        }
695        i++;
696      }
697    }
698    songs = null;
699    songs = sortedSongs;
700  }
701
702
703  /**  Sorts the Playlist Alphabetically by its artist Then Album deaults to sortSongsByArtistAlbumTrackTitle(). */
704  public void sortSongsByArtistAlbum()
705  {
706    sortSongsByArtistAlbumTrackTitle();
707  }
708
709
710  /**
711   *  Finds a song in the playlist and returns the index to it.
712   *
713   * @param  songName  The Songname to look for
714   * @return           the index postion of the found song in the playlist (-1
715   *      if not found)
716   */
717  public int findSong( String songName )
718  {
719    int retVal = -1;
720    for ( int i = 0; i < songs.size(); i++ )
721    {
722      if ( ( (OggFileRef)songs.get( i ) ).name_.equals( songName ) )
723      {
724        return i;
725      }
726    }
727    return retVal;
728  }
729
730
731  /**
732   *  Finds a song in the playlist by its song title and returns the index to it.
733   *
734   * @param  songName  The Songname to look for
735   * @return           the index postion of the found song in the playlist (-1
736   *      if not found)
737   */
738  public int findSongByTitle( String songTitle )
739  {
740    int retVal = -1;
741    for ( int i = 0; i < songs.size(); i++ )
742    {
743      if ( ( (OggFileRef)songs.get( i ) ).getTitle().equals( songTitle ) )
744      {
745        return i;
746      }
747    }
748    return retVal;
749  }
750
751
752  /**
753   *  Finds a song in the playlist by its song ArtistAlbumTrackTitle and returns the index to it.
754   *
755   * @param  ArtistAlbumTrackTitle  The ArtistAlbumTrackTitle hash to look for
756   * @return           the index postion of the found song in the playlist (-1
757   *      if not found)
758   */
759  public int findSongByHash( String artistAlbumTrackTitle )
760  {
761    int retVal = -1;
762    for ( int i = 0; i < songs.size(); i++ )
763    {
764      if ( ( (OggFileRef)songs.get( i ) ).getArtistAlbumTrackTitle().equals( artistAlbumTrackTitle ) )
765      {
766        return i;
767      }
768    }
769    return retVal;
770  }
771
772
773  /**
774   *  Finds a song in the playlist by its song ArtistAlbumTrackNum and returns the index to it.
775   *
776   * @param  ArtistAlbumTrackTitle  The ArtistAlbumTrackNum hash to look for
777   * @return           the index postion of the found song in the playlist (-1
778   *      if not found)
779   */
780  public int findSongByNumHash( String artistAlbumTrackNum )
781  {
782    int retVal = -1;
783    for ( int i = 0; i < songs.size(); i++ )
784    {
785      if ( ( (OggFileRef)songs.get( i ) ).getArtistAlbumTrackNum().equals( artistAlbumTrackNum ) )
786      {
787        return i;
788      }
789    }
790    return retVal;
791  }
792
793
794  /**
795   *  Finds a song in the playlist and returns the index to it.
796   *
797   * @param  songUrl  Description of the Parameter
798   * @return          the index postion of the found song in the playlist (-1 if
799   *      not found)
800   */
801  public int findSong( URL songUrl )
802  {
803    int retVal = -1;
804    for ( int i = 0; i < songs.size(); i++ )
805    {
806      if ( ( (OggFileRef)songs.get( i ) ).url_.equals( songUrl ) )
807      {
808        return i;
809      }
810    }
811    return retVal;
812  }
813
814
815  /**
816   *  Tells you if the Playlist contains a certain song.
817   *
818   * @param  songName  The Songname to look for
819   * @return           True if the song was found
820   */
821  public boolean contains( String songName )
822  {
823    boolean retVal = false;
824    int indx = findSong( songName );
825    if ( indx >= 0 )
826    {
827      retVal = true;
828    }
829    return retVal;
830  }
831
832
833  /**
834   *  Checks to see if the list of songs in this playlist is empty.
835   *
836   * @return    true if the list of songs in this playlist is empty, false if
837   *      not.
838   */
839  public boolean isEmpty()
840  {
841    return songs.isEmpty();
842  }
843
844
845  /**
846   *  Adds the specified song to the playlist.
847   *
848   * @param  url  the specification for the song to add.
849   * @return      the OggFileRef name of the added song.
850   */
851  public String addSong( URL url )
852  {
853    OggFileRef oggFileRef = new OggFileRef( url );
854    songs.add( oggFileRef );
855    //System.out.println("Added "+songs.size()+") "+url);
856    return oggFileRef.name_;
857  }
858
859
860  /**
861   *  Creates and returns a small JCheckBox with the selected song name and a
862   *  small checkbox indicating if the song is selected.
863   *
864   * @param  songName  Description of the Parameter
865   * @return           a JCheckBox containing a checkbox and Name of the song.
866   */
867  public JCheckBox createSongCheckBox( String songName )
868  {
869    return createSongCheckBox( findSong( songName ) );
870  }
871
872
873  /**
874   *  Creates and returns a small JCheckBox with the selected song name and a
875   *  small checkbox indicating if the song is selected.
876   *
877   * @param  index  the song num to look up
878   * @return        a JCheckBox containing a checkbox and Name of the song.
879   */
880  public JCheckBox createSongCheckBox( int index )
881  {
882    JCheckBox jc = new JCheckBox( "uninit", false );
883    if (index>=0)
884    {
885      OggFileRef oggRef = ( (OggFileRef)songs.get( index ) );
886
887      if ( oggRef != null )
888      {
889        jc.setText( oggRef.name_ );
890        jc.setSelected( oggRef.isSongSelected() );
891      }
892    }
893    return jc;
894  }
895
896
897  /**
898   *  Creates and returns a small JPanel with the selected song name and a small
899   *  checkbox indicating if the song is selected. This Panel is suitable to use
900   *  a as a JComboBox Item.
901   *
902   * @param  index  the song num to look up
903   * @return        a JPanel containing a checkbox and Name of the song.
904   */
905  public JPanel createSongPanel( int index )
906  {
907    OggFileRef oggRef = ( (OggFileRef)songs.get( index ) );
908    JPanel retVal = new JPanel();
909    retVal.add( new JCheckBox( oggRef.name_, oggRef.isSongSelected() ) );
910    return retVal;
911  }
912
913
914  /**
915   *  Creates and returns a small JPanel with the selected song name and a small
916   *  checkbox indicating if the song is selected. This Panel is suitable to use
917   *  a as a JComboBox Item.
918   *
919   * @param  song  the song name to look up
920   * @return       a JPanel containing a checkbox and Name of the song.
921   */
922  public JPanel createSongPanel( String song )
923  {
924    OggFileRef oggRef = ( (OggFileRef)songs.get( findSong( song ) ) );
925    JPanel retVal = new JPanel();
926    retVal.add( new JCheckBox( oggRef.name_, oggRef.isSongSelected() ) );
927    return retVal;
928  }
929
930
931  /**
932   *  Parses the passed filename looking for OGG files. It will recurse
933   *  directories if a dir is in the passed String.
934   *
935   * @param  fileName  an String (a file or dir name) to parse for OGG files.
936   * @return           a vector of OGG files that have been found within the
937   *      passed in String.
938   */
939  public Vector getPlaylistVector( String fileName )
940  {
941    Vector retVal = new Vector();
942    String[] temp = {fileName};
943    if ( fileName != null )
944    {
945      retVal = getPlaylistVector( temp );
946    }
947    return retVal;
948  }
949
950
951  /**
952   *  The number of entries in the PlayList.
953   *
954   * @return    The number of entries in the PlayList.
955   */
956  public int size()
957  {
958    int retVal = 0;
959    if ( songs != null )
960    {
961      retVal = songs.size();
962    }
963    return retVal;
964  }
965
966
967    /**
968   *  Selects ALL OggFileRef
969   *
970   */
971  public void selectAllSongs( )
972  {
973    int i;
974    for ( i = 0; i < size(); i++ )
975    {
976      ( (OggFileRef)songs.get( i ) ).setSelected( true );
977    }
978  }
979
980
981    /**
982   *  De-Selects ALL OggFileRef
983   *
984   */
985  public void deSelectAllSongs( )
986  {
987    int i;
988    for ( i = 0; i < size(); i++ )
989    {
990      ( (OggFileRef)songs.get( i ) ).setSelected( false );
991    }
992  }
993
994
995  /**
996   *  De-Selects the spec'd OggFileRef
997   *
998   * @param  songIndex  The song to select
999   * @param  select     for select or de-select
1000   */
1001  public void deSelectSong( int songIndex, boolean select )
1002  {
1003    if (songIndex>=0)
1004      ( (OggFileRef)songs.get( songIndex ) ).setSelected( select );
1005  }
1006
1007
1008  /**
1009   *  Marks the OggFileRef as selected
1010   *
1011   * @param  songIndex  The song to select
1012   * @param  select     for select or de-select
1013   */
1014  public void selectSong( int songIndex, boolean select )
1015  {
1016    if (songIndex>=0)
1017      ( (OggFileRef)songs.get( songIndex ) ).setSelected( select );
1018  }
1019
1020
1021  /**
1022   *  Gets the information from an Ogg Vorbis reference in a nice, humanly-readable format.
1023   *
1024   * @param  songIndex  The song to select
1025   * @return the information from an Ogg Vorbis stream in a nice, humanly-readable format.
1026   */
1027  public String getSongInfo( int songIndex )
1028  {
1029    String retVal = "";
1030    if (songIndex>=0)
1031      retVal = ( (OggFileRef)songs.get( songIndex ) ).toString();
1032    return retVal;
1033  }
1034
1035
1036  /**
1037   *  Gets the Channels information from an Ogg Vorbis reference.
1038   *
1039   * @param  songIndex  The song to select
1040   * @return the information from an Ogg Vorbis stream in a nice, humanly-readable format.
1041   */
1042  public int getSongChannels( int songIndex )
1043  {
1044    int retVal = 0;
1045    if (songIndex>=0)
1046      retVal = ( (OggFileRef)songs.get( songIndex ) ).getChannels();
1047    return retVal;
1048  }
1049
1050
1051  /**
1052   *  Gets the Average Bitrate information from an Ogg Vorbis reference.
1053   *
1054   * @param  songIndex  The song to select
1055   * @return the information from an Ogg Vorbis stream in a nice, humanly-readable format.
1056   */
1057  public long getSongBitrate( int songIndex )
1058  {
1059    long retVal = 0;
1060    if (songIndex>=0)
1061      retVal = ( (OggFileRef)songs.get( songIndex ) ).getBitrate();
1062    return retVal;
1063  }
1064
1065
1066  /**
1067   *  Gets the ALBUM information from an Ogg Vorbis reference.
1068   *
1069   * @param  songIndex  The song to select
1070   * @return the information from an Ogg Vorbis stream in a nice, humanly-readable format.
1071   */
1072  public String getSongAlbum( int songIndex )
1073  {
1074    String retVal = "";
1075    if (songIndex>=0)
1076      retVal = ( (OggFileRef)songs.get( songIndex ) ).getAlbum();
1077    return retVal;
1078  }
1079
1080
1081  /**
1082   *  Gets the ARTIST information from an Ogg Vorbis reference.
1083   *
1084   * @param  songIndex  The song to select
1085   * @return the information from an Ogg Vorbis stream in a nice, humanly-readable format.
1086   */
1087  public String getSongArtist( int songIndex )
1088  {
1089    String retVal = "";
1090    if (songIndex>=0)
1091      retVal = ( (OggFileRef)songs.get( songIndex ) ).getArtist();
1092    return retVal;
1093  }
1094
1095
1096  /**
1097   *  Gets the TrackNumber information from an Ogg Vorbis reference.
1098   *
1099   * @param  songIndex  The song to select
1100   * @return the Track Number (0 if not valid or not found).
1101   */
1102  public int getTrackNumber( int songIndex )
1103  {
1104    int retVal = 0;
1105    if (songIndex>=0)
1106      retVal = ( (OggFileRef)songs.get( songIndex ) ).getTrackNumber();
1107    return retVal;
1108  }
1109
1110
1111  /**
1112   *  Gets the TITLE information from an Ogg Vorbis reference.
1113   *
1114   * @param  songIndex  The song to select
1115   * @return the information from an Ogg Vorbis stream in a nice, humanly-readable format.
1116   */
1117  public String getSongTitle( int songIndex )
1118  {
1119    String retVal = "";
1120    if (songIndex>=0)
1121      retVal = ( (OggFileRef)songs.get( songIndex ) ).getTitle();
1122    return retVal;
1123  }
1124
1125
1126  /**
1127   *  Gets the songSelected attribute of the PlayList object
1128   *
1129   * @param  songName  Description of the Parameter
1130   * @return           The songSelected value
1131   */
1132  public boolean isSongSelected( String songName )
1133  {
1134    return isSongSelected( findSong( songName ) );
1135  }
1136
1137
1138  /**
1139   *  Gets the songSelected attribute of the PlayList object
1140   *
1141   * @param  songIndex  Description of the Parameter
1142   * @return            The songSelected value
1143   */
1144  public boolean isSongSelected( int songIndex )
1145  {
1146    boolean retVal = false;
1147    if (songIndex>=0)
1148      retVal = ( (OggFileRef)songs.get( songIndex ) ).isSongSelected();
1149    return retVal;
1150  }
1151
1152
1153  /**
1154   *  Loads a playlist from the playlist file specified in the playListFilename_
1155   *  field. It first trys to load each line as a URL; if that fails it loads
1156   *  them as files. It simply adds the songs listed to the playList.
1157   *
1158   * @param  filenameURL  the filename to use as the playlist - specified as a
1159   *      URL
1160   */
1161  public void loadPlaylist( URL filenameURL )
1162  {
1163    InputStream is = null;
1164    if ( filenameURL != null )
1165    {
1166      /*
1167       *  get the file ready to read
1168       */
1169      try
1170      {
1171        // load it as a URL
1172
1173        URLConnection urlc = filenameURL.openConnection();
1174        // throws IOException
1175        is = urlc.getInputStream();
1176
1177        /*
1178         *  Now load the songs listed
1179         */
1180        String line = null;
1181        int indx = -1;
1182        // check each time if the is has not disappeared
1183        while ( is != null && ( line = readline( is ) ) != null )
1184        {
1185          try
1186          {
1187            indx = line.indexOf( "=" );
1188            if ( indx != -1 )
1189            {
1190              addSong( new URL( line.substring( indx + 1 ) ) );
1191            }
1192            else
1193            {// just assume its a URL all on its own
1194              addSong( new URL( line ) );
1195            }
1196          }
1197          catch ( MalformedURLException ee )
1198          {
1199            // NOTHING JUST GO TO NEXT to save load time
1200          }
1201        }
1202      }
1203      catch ( MalformedURLException ee )
1204      {
1205        System.out.println( "The Playlist Filename has some errors. " +
1206            "Please check the filename." );
1207      }
1208      catch ( IOException ee )
1209      {
1210        System.out.println( "The Playlist Filename cannot be read." );
1211      }
1212    }
1213    if (is != null)
1214      try{is.close();}catch(IOException ioEx){}
1215  }
1216
1217
1218
1219  /**
1220   *  Saves the playlist to the file specified in the playListFilename_ field.
1221   *  <PRE>[playlist]
1222   * File1=H:\MP3s\U2\October\02 - I Fall Down.mp3
1223   * File2=H:\MP3s\Leonard Cohen\01 - Suzanne.mp3
1224   * NumberOfEntries=2
1225   * </PRE>
1226   *
1227   * @param  filename  Description of the Parameter
1228   */
1229  public void savePlaylistFile( String filename )
1230  {
1231    try
1232    {
1233      FileWriter out = new FileWriter( filename, false );
1234      String currUrlStr = "";
1235      URL[] playUrls = getSongUrls();
1236      out.write( "[playlist]" +
1237          System.getProperty( "line.separator", "\n" ) );
1238      String tempNumStr = "";
1239      int i;
1240      for ( i = 0; i < playUrls.length; i++ )
1241      {
1242        tempNumStr = "File" + ( i + 1 ) + "=";
1243        currUrlStr = playUrls[i].toString();
1244        out.write( tempNumStr + currUrlStr +
1245            System.getProperty( "line.separator", "\n" ) );
1246      }
1247      out.write( "NumberOfEntries=" + i );
1248      out.close();
1249    }
1250    catch ( IOException ex )
1251    {
1252      System.out.println( "Could Not Save To Playlist File " + filename );
1253    }
1254  }
1255
1256
1257  /**
1258   *  Saves the favourites selected in the playlist to the file specified in the playListFilename_ field.
1259   *  <PRE>[playlist]
1260   * File1=H:\MP3s\U2\October\02 - I Fall Down.mp3
1261   * File2=H:\MP3s\Leonard Cohen\01 - Suzanne.mp3
1262   * NumberOfEntries=2
1263   * </PRE>
1264   *
1265   * @param  filename  Description of the Parameter
1266   */
1267  public void saveFavourites(String filename )
1268  {
1269    try
1270    {
1271      FileWriter out = new FileWriter( filename, false );
1272      String currUrlStr = "";
1273      URL[] playUrls = getSongUrls();
1274      out.write( "[playlist]" +
1275          System.getProperty( "line.separator", "\n" ) );
1276      String tempNumStr = "";
1277      int i;
1278      int selectedSongs = 0;
1279      for ( i = 0; i < playUrls.length; i++ )
1280      {
1281        if (isSongSelected(i))
1282        {
1283          tempNumStr = "File" + ( selectedSongs + 1 ) + "=";
1284          currUrlStr = playUrls[i].toString();
1285          out.write( tempNumStr + currUrlStr +
1286              System.getProperty( "line.separator", "\n" ) );
1287          selectedSongs++;
1288        }
1289      }
1290      out.write( "NumberOfEntries=" + selectedSongs );
1291      out.close();
1292    }
1293    catch ( IOException ex )
1294    {
1295      System.out.println( "Could Not Save To Playlist File " + filename );
1296    }
1297  }
1298
1299
1300  /**
1301   *  Description of the Method
1302   *
1303   * @param  songName  Description of the Parameter
1304   * @return           Description of the Return Value
1305   */
1306  public boolean removeSong( String songName )
1307  {
1308    boolean retVal = false;
1309    int indx = findSong( songName );
1310    if ( indx >= 0 )
1311    {
1312      songs.removeElementAt( indx );
1313      retVal = true;
1314    }
1315    return retVal;
1316  }
1317}
1318
1319
1320/**
1321 *  A simple class to encapsulate the information required to use/reference an
1322 *  Ogg file.
1323 *
1324 * @author     unknown
1325 * @created    April 4, 2002
1326 */
1327class OggFileRef
1328{
1329  /**  File Name of the song. */
1330  public String name_ = "";
1331
1332  /**  The URL for the song resource. */
1333  public URL url_ = null;
1334
1335  /**  Select This song for playing. */
1336  private boolean selected_ = true;
1337
1338  /**  The VorbisInfo object for this file. */
1339  private VorbisInfo vorbisInfo_ = null;
1340  /**  Select This song for playing. */
1341  private JOrbisComment jOrbisComment_ = null;
1342
1343  /**
1344   *  Constructor for the OggFileRef object
1345   *
1346   * @param  newUrl  Description of the Parameter
1347   */
1348  OggFileRef( URL newUrl )
1349  {
1350    url_ = newUrl;
1351    String urlStr = Util.decodeURL(url_.toString());
1352    name_ =urlStr.substring( urlStr.lastIndexOf( '/' ) + 1 );
1353  }
1354
1355  /** Instantiates the JOrbisComment Object **/
1356  private void initVorbisComment()
1357  {
1358    if (jOrbisComment_ == null)
1359      try
1360      {
1361        vorbisInfo_ = null;
1362        //System.out.print("\nvorbisURL("+url_+") is "+(url_==null?"":"NOT ")+" null");
1363        URLConnection conn = url_.openConnection();
1364        if (url_!=null)
1365        {
1366          if (url_.getProtocol().equals("file"))
1367          {
1368            File f = new File(Util.decodeURL(url_.getFile()));
1369            if (f.canRead())
1370            {
1371              jOrbisComment_ = new JOrbisComment(f);
1372              //jOrbisComment_.read();
1373            }
1374            else
1375            {
1376              System.err.println("Cant Access File: "+Util.decodeURL(url_.getFile()));
1377              vorbisInfo_ = null;
1378              jOrbisComment_ = null;
1379             }
1380          }
1381          else
1382          {
1383              jOrbisComment_ = new JOrbisComment();
1384              jOrbisComment_.read(url_.openStream());
1385
1386          }
1387        }
1388      }
1389      catch (Exception ex)
1390      {
1391        System.err.println("vorbisURL is "+(url_==null?"":"NOT ")+" null");
1392        vorbisInfo_ = null;
1393        jOrbisComment_ = null;
1394        //ex.printStackTrace();
1395      }
1396  }
1397
1398  /**
1399   *  Gets the songSelected attribute of the OggFileRef object
1400   *
1401   * @return    The songSelected value
1402   */
1403  public boolean isSongSelected()
1404  {
1405    return selected_;
1406  }
1407
1408
1409  /**
1410   *  Gets the average bitrate for this ogg vorbis file.
1411   *
1412   * @return    the average bitrate
1413   */
1414  public long getBitrate()
1415  {
1416    long retVal = 0l;
1417    if ( vorbisInfo_ != null)
1418      retVal = vorbisInfo_.getBitrate();
1419    return retVal;
1420  }
1421
1422
1423  /**
1424   *  Gets the numer of Channels for this ogg vorbis file.
1425   *
1426   * @return    the average bitrate
1427   */
1428  public int getChannels()
1429  {
1430    int retVal = 0;
1431    if ( vorbisInfo_ != null)
1432      retVal = vorbisInfo_.getChannels();
1433    return retVal;
1434  }
1435
1436
1437  /**
1438   *  Sets the Artist Comment for this ogg vorbis file.
1439   *
1440   * @value String  holding the current track artist
1441   */
1442  public boolean setArtist(String value)
1443  {
1444    initVorbisComment();
1445    return (jOrbisComment_!=null?jOrbisComment_.setArtist(value):false);
1446  }
1447
1448
1449  /**
1450   *  Sets the Album Comment for this ogg vorbis file.
1451   *
1452   * @value String  holding the current track Album
1453   */
1454  public boolean setAlbum(String value)
1455  {
1456    initVorbisComment();
1457    return (jOrbisComment_!=null?jOrbisComment_.setAlbum(value):false);
1458  }
1459
1460
1461  /**
1462   *  Sets the Title Comment for this ogg vorbis file.
1463   *
1464   * @value String  holding the current track Title
1465   */
1466  public boolean setTitle(String value)
1467  {
1468    initVorbisComment();
1469    return (jOrbisComment_!=null?jOrbisComment_.setTitle(value):false);
1470  }
1471
1472
1473  /**
1474   *  Sets the Track num for this ogg vorbis file.
1475   *
1476   * @value String  holding the current track num
1477   */
1478  public boolean setTracknumber(String value)
1479  {
1480    initVorbisComment();
1481    return (jOrbisComment_!=null?jOrbisComment_.setTracknumber(value):false);
1482  }
1483
1484
1485  /**
1486   *  Sets the Track total for this ogg vorbis file.
1487   *
1488   * @value String  holding the current track total
1489   */
1490  public boolean setTrackTotal(String value)
1491  {
1492    initVorbisComment();
1493    return (jOrbisComment_!=null?jOrbisComment_.setTrackTotal(value):false);
1494  }
1495
1496
1497  /**
1498   *  Sets the genre  num for this ogg vorbis file.
1499   *
1500   * @value String  holding the current genre
1501   */
1502  public boolean setGenre(String value)
1503  {
1504    initVorbisComment();
1505    return (jOrbisComment_!=null?jOrbisComment_.setGenre(value):false);
1506  }
1507
1508
1509  /**
1510   *  Gets a concatenation of Artist Album and Track# Comment for this ogg vorbis file.
1511   *
1512   * @return    a concatenation of Artist Album and Track# Comment
1513   */
1514  public String getArtistAlbumTrackNum()
1515  {
1516    String retVal = "";
1517    initVorbisComment();
1518    retVal = (jOrbisComment_!=null?jOrbisComment_.getArtistAlbumTrackNum():"");
1519    //jOrbisComment_.flush();
1520    //jOrbisComment_ = null;
1521    return retVal;
1522  }
1523
1524
1525  /**
1526   *  Gets a concatenation of Artist Album and Track Title Comment for this ogg vorbis file.
1527   *
1528   * @return    a concatenation of Artist Album and Track# Comment
1529   */
1530  public String getArtistAlbumTrackTitle()
1531  {
1532    String retVal = "";
1533    initVorbisComment();
1534    retVal = (jOrbisComment_!=null?jOrbisComment_.getArtistAlbumTrackTitle():"");
1535    //jOrbisComment_.flush();
1536    //jOrbisComment_ = null;
1537    return retVal;
1538  }
1539
1540
1541  /**
1542   *  Gets the Artist Comment for this ogg vorbis file.
1543   *
1544   * @return    comment holding the current track artist
1545   */
1546  public String getArtist()
1547  {
1548    /*String retVal = "";
1549    if ( vorbisInfo_ != null)
1550    {
1551      Vector v = vorbisInfo_.getComments("ARTIST");
1552      for (int i = 0; v != null && i < v.size(); i++)`
1553      {
1554        retVal += (String) v.get(i);
1555        if (i+1 < v.size())
1556          retVal += Util.SYSTEM_LINE_SEPERATOR;
1557      }
1558    }
1559    return retVal; */
1560    initVorbisComment();
1561    return (jOrbisComment_!=null?jOrbisComment_.getArtist():"");
1562  }
1563
1564
1565  /**
1566   *  Gets the Song Title Comment for this ogg vorbis file.
1567   *
1568   * @return   comment holding the current track title
1569   */
1570  public String getTitle()
1571  {
1572    /*String retVal = "";
1573    if ( vorbisInfo_ != null)
1574    {
1575      Vector v = vorbisInfo_.getComments("TITLE");
1576      for (int i = 0; v != null && i < v.size(); i++)
1577      {
1578        retVal += (String) v.get(i);
1579        if (i+1 < v.size())
1580          retVal += Util.SYSTEM_LINE_SEPERATOR;
1581      }
1582    }
1583    return retVal;*/
1584    initVorbisComment();
1585    return (jOrbisComment_!=null?jOrbisComment_.getTitle():"");
1586  }
1587
1588
1589  /**
1590   *  Gets the ALBUM Comment for this ogg vorbis file.
1591   *
1592   * @return    comment holding the current track albumname
1593   */
1594  public String getAlbum()
1595  {
1596    /*String retVal = "";
1597    if ( vorbisInfo_ != null)
1598    {
1599      Vector v = vorbisInfo_.getComments("ALBUM");
1600      for (int i = 0; v != null && i < v.size(); i++)
1601      {
1602        retVal += (String) v.get(i);
1603        if (i+1 < v.size())
1604          retVal += Util.SYSTEM_LINE_SEPERATOR;
1605      }
1606    }
1607    return retVal;*/
1608    initVorbisComment();
1609    return (jOrbisComment_!=null?jOrbisComment_.getAlbum():"");
1610  }
1611
1612
1613  /**
1614   *  Gets the TRACKNUMBER Comment for this ogg vorbis file.
1615   *
1616   * @return    the number or -1 if not spec'd
1617   */
1618  public int getTrackNumber()
1619  {
1620    /*int retVal = -1;
1621    if ( vorbisInfo_ != null)
1622    {
1623      Vector v = vorbisInfo_.getComments("TRACKNUMBER");
1624      if ( v!=null && v.size()>0 )
1625        retVal = Integer.parseInt((String) v.get(v.size()-1));
1626    }
1627    return retVal;*/
1628    int retVal = -1;
1629    initVorbisComment();
1630    String trNum = jOrbisComment_.getTracknumber();
1631
1632    return (jOrbisComment_!=null&&!jOrbisComment_.getTracknumber().equals("")
1633            ?Integer.parseInt(jOrbisComment_.getTracknumber())
1634            :-1);
1635  }
1636
1637
1638  /**
1639   *  Sets the selected attribute of the OggFileRef object
1640   *
1641   * @param  s  The new selected value
1642   */
1643  public void setSelected( boolean s )
1644  {
1645    selected_ = s;
1646  }
1647
1648
1649  /**
1650   * Prints out the information from an Ogg Vorbis stream in a
1651   * nice, humanly-readable format.
1652   */
1653  public String toString() {
1654
1655    String retVal = url_+"\n";
1656
1657    if ( vorbisInfo_ != null)
1658      retVal += vorbisInfo_.toString();
1659
1660    return retVal;
1661  }
1662
1663
1664}
1665/*
1666 *  Here is the revision log
1667 *  ------------------------
1668 *  $Log: PlayList.java,v $
1669 *  Revision 1.8  2004/11/14 04:46:46  tgutwin
1670 *  Changed the getSongNames method to getSongFileNames to be more accurate.
1671 *  Added the sortSongs methods.
1672 *
1673 *  Revision 1.6  2002/04/23 22:22:34  tgutwin
1674 *  Added the ability to add the songs from a playlist if passed the name of the playlist.
1675 *
1676 *  Revision 1.5  2002/04/11 23:15:37  anonymous
1677 *  Added a couple methods for a jCheckboxDropdown bug fix.
1678 *
1679 *  Revision 1.4  2002/04/06 06:03:07  anonymous
1680 *  small change to loading of a playlist file URL
1681 *
1682 *  Revision 1.3  2002/04/05 23:05:53  anonymous
1683 *  Bug Fixes.
1684 *
1685 *  Revision 1.2  2001/09/02 03:24:23  tgutwin
1686 *  Initial Rev of my custom DropDown Boxes.
1687 *  Revision 1.1  2001/08/12 06:00:01  tgutwin
1688 *  Intial Revision. Includes OGG files Only.
1689 */
1690