import java.util.ArrayList;
/**
* A class to hold details of audio files.
*
* @author David J. Barnes and Michael Kölling
* @version 2016.02.29
*/
public class MusicOrganizer
{
// An ArrayList for storing the file names of music files.
private ArrayList<String> files;
// A player for the music files.
private MusicPlayer player;
/**
* Create a MusicOrganizer
*/
public MusicOrganizer()
{
files = new ArrayList<>();
player = new MusicPlayer();
}
public int countLoveSongs() {
int num = 0;
for(String file : files) {
if(file.toLowerCase().contains("love")) {
num++;
}
}
return num;
}
public boolean hasChristmasSong() {
for(String file : files) {
if(file.toLowerCase().contains("christmas")) {
return true;
}
}
return false;
}
public boolean hasChristmasSong2() {
boolean foundChristmasSong = false;
for(String file : files) {
if(file.toLowerCase().contains("christmas")) {
foundChristmasSong = true;
}
}
return foundChristmasSong;
}
/**
* @return the index of the first song with "christmas" in the filename,
* case-insensitive, or -1 if there is no such song.
*/
public int firstChristmasSong() {
for(int i=0;i<files.size();i++) {
String file = files.get(i);
if(file.toLowerCase().contains("christmas")) {
return i;
}
}
return -1;
}
/**
* @return true if any of the songs contain partOfTitle in the filename,
* and false otherwise.
* (Tyler's version)
*/
public boolean hasSongMatching(String partOfTitle){
for(String file : files){
if(file.toLowerCase().contains(partOfTitle.toLowerCase())){
return true;
}
}
return false;
}
/**
* @return the index of the first song that contains partOfTitle as part of the filename,
* and -1 if no such song exists.
* (Tyler's version)
*/
public int firstMatchingSong(String partOfTitle){
for(int i=0;i<files.size();i++) {
String file = files.get(i);
if(file.toLowerCase().contains(partOfTitle.toLowerCase())){
return i;
}
}
return -1;
}
/**
* Removes all Christmas songs.
*
* This version is wrong--you cannot call remove in the middle of
* a for-each loop in Java.
*/
public void bahHumbug1_Wrong() {
for(String file : files) {
if(file.toLowerCase().contains("christmas")) {
files.remove(file);
}
}
}
/**
* Removes all Christmas songs.
*
* Regular for-loop, but we need to take into account that when we remove
* an element, all of the elements shifted down, so we need to decrement i
* to compsensate for that fact that the increment is going to increment
* past the next element.
*/
public void bahHumbug() {
for(int i=0;i<files.size();i++) {
String file = files.get(i);
if(file.toLowerCase().contains("christmas")) {
files.remove(i);
i--; // Subtle important line!
}
}
}
/**
* The while-loop version that only increments if an element is NOT removed.
* Because if one is removed, one got shifted to the current spot and we
* need to check it again.
*/
public void bahHumbug2() {
int i=0;
while(i<files.size()) {
String file = files.get(i);
if(file.toLowerCase().contains("christmas")) {
files.remove(i);
} else {
i++; // Only increment if you did not remove one.
}
}
}
/**
* Process the list backwards. Then any shifting that takes place does
* not affect what happens since the next element you will look at is earlier
* in the list and unmoved.
* Be careful to get the starting and ending indices correct, and don't forget
* to decrement instead of increment.
*/
public void bahHumbug3() {
for(int i=files.size()-1;i>=0;i--) {
String file = files.get(i);
if(file.toLowerCase().contains("christmas")) {
files.remove(i);
}
}
}
/**
* Add a file to the collection.
* @param filename The file to be added.
*/
public void addFile(String filename)
{
files.add(filename);
}
/**
* Return the number of files in the collection.
* @return The number of files in the collection.
*/
public int getNumberOfFiles()
{
return files.size();
}
/**
* List a file from the collection.
* @param index The index of the file to be listed.
*/
public void listFile(int index)
{
if(validIndex(index)) {
String filename = files.get(index);
System.out.println(filename);
}
}
/**
* Show a list of all the files in the collection.
*/
public void listAllFiles()
{
for(String filename : files) {
System.out.println(filename);
}
}
/**
* Remove a file from the collection.
* @param index The index of the file to be removed.
*/
public void removeFile(int index)
{
if(validIndex(index)) {
files.remove(index);
}
}
/**
* Start playing a file in the collection.
* Use stopPlaying() to stop it playing.
* @param index The index of the file to be played.
*/
public void startPlaying(int index)
{
if(validIndex(index)) {
String filename = files.get(index);
player.startPlaying(filename);
}
}
/**
* Stop the player.
*/
public void stopPlaying()
{
player.stop();
}
/**
* Play a file in the collection. Only return once playing has finished.
* @param index The index of the file to be played.
*/
public void playAndWait(int index)
{
if(validIndex(index)) {
String filename = files.get(index);
player.playSample(filename);
}
}
/**
* Determine whether the given index is valid for the collection.
* Print an error message if it is not.
* @param index The index to be checked.
* @return true if the index is valid, false otherwise.
*/
private boolean validIndex(int index)
{
// The return value.
// Set according to whether the index is valid or not.
boolean valid;
if(index < 0) {
System.out.println("Index cannot be negative: " + index);
valid = false;
}
else if(index >= files.size()) {
System.out.println("Index is too large: " + index);
valid = false;
}
else {
valid = true;
}
return valid;
}
}