package com.sound.ampache.utility; /* Copyright (c) 2010 Jacob Alexander < haata@users.sf.net > * * +------------------------------------------------------------------------+ * | This program is free software; you can redistribute it and/or | * | modify it under the terms of the GNU General Public License | * | as published by the Free Software Foundation; either version 2 | * | of the License, or (at your option) any later version. | * | | * | This program is distributed in the hope that it will be useful, | * | but WITHOUT ANY WARRANTY; without even the implied warranty of | * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | * | GNU General Public License for more details. | * | | * | You should have received a copy of the GNU General Public License | * | along with this program; if not, write to the Free Software | * | Foundation, Inc., 59 Temple Place - Suite 330, | * | Boston, MA 02111-1307, USA. | * +------------------------------------------------------------------------+ */ import android.util.Log; import com.sound.ampache.objects.Media; import java.util.ArrayList; import java.util.Random; public class Playlist extends ArrayList<Media> { private ArrayList<Integer> shuffleHistory = new ArrayList<Integer>(); private int currentIndex = 0; private boolean shuffleEnabled = false; private boolean repeatEnabled = false; private final static String LOG_TAG = "Amdroid_Playlist"; // Constructors ************************************************** public Playlist() { } public Playlist(int startingIndex) { setCurrentIndex(startingIndex); } public Playlist(int startingIndex, boolean shuffle, boolean repeat) { setCurrentIndex(startingIndex); setShufflePlay(shuffle); setRepeatPlay(repeat); } // Gets ********************************************************** public int getCurrentIndex() { return currentIndex; } public Media getCurrentMedia() { if (size() <= 0) { return null; } return super.get(currentIndex); } public boolean getShufflePlay() { return shuffleEnabled; } public boolean getRepeatPlay() { return repeatEnabled; } // Sets ********************************************************** // Checks bounds before setting, if invalid the index is set to 0; returns the Media at the index public Media setCurrentIndex(int index) { if (index >= super.size() || index < 0) currentIndex = 0; else currentIndex = index; return super.get(currentIndex); } public void setShufflePlay(boolean randomize) { clearShuffleHistory(); shuffleEnabled = randomize; } public void setRepeatPlay(boolean loop) { repeatEnabled = loop; } // Functions ***************************************************** public void clearShuffleHistory() { shuffleHistory.clear(); } public void clearPlaylist() { super.clear(); currentIndex = 0; } // Returns the next media to play, null if finished the playlist public Media next() { Log.d(LOG_TAG, "Next Media"); if (shuffleEnabled) { // So we don't play a media more than once if (!shuffleHistory.contains(currentIndex)) shuffleHistory.add(currentIndex); // Just played the last media, repeat if repeat is enabled, stop otherwise if (shuffleHistory.size() >= super.size() && repeatEnabled) shuffleHistory.clear(); else { currentIndex = 0; return null; } int next = 0; Random rand = new Random(); // Try random numbers until finding one that is not used do { next = rand.nextInt(super.size()); } while (shuffleHistory.contains(next)); // Set next playing index currentIndex = next; } else { // move to the next media if ((currentIndex + 1) >= super.size()) { if (repeatEnabled) { // cycle back to the start when in repeat mode currentIndex = 0; } else { // nowhere to go } } else { currentIndex++; } } // Index is within the list bounds if (currentIndex >= 0 && currentIndex < super.size()) return super.get(currentIndex); return null; } public Media prev() { if (shuffleEnabled) { int prevIndex = shuffleHistory.indexOf(currentIndex); // Call a random next media if this is the first media if (shuffleHistory.size() < 1) return next(); // Previous (Current item is not in the shuffle history) if (prevIndex == -1) { // Set previous media currentIndex = (Integer) shuffleHistory.get(shuffleHistory.size() - 1); // Remove item, I consider Previous like an undo shuffleHistory.remove(shuffleHistory.size() - 1); } // This shouldn't be possible, but... else if (prevIndex > 0) { currentIndex = (Integer) shuffleHistory.get(prevIndex - 1); shuffleHistory.remove(prevIndex); } } // Do not call previous if it is the first media else if (currentIndex > 0) { currentIndex--; } // Index is within the list bounds if (currentIndex >= 0 && currentIndex < super.size()) return super.get(currentIndex); return null; } }