package controller;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.BoundedRangeModel;
import model.Library;
import model.Track;
import controller.interfaces.JukeboxStateListener;
import controller.soundEngine.PlayerAbstractionLayer;
/**
* Gedacht als eine Art Queue, die die lieder verarbeitet. sie hat die macht
* über den player, der spielen muss, was die jukebox sagt
*
* @author Artur Dawtjan
*
*/
public class Jukebox{
public static final int NO_REPEAT_MODE = 0;
public static final int REPEAT_MODE = 1;
public static final int REPEAT_ALL_MODE = 2;
public static final int SHUFFLE_MODE = 3;
private boolean hasFinished = true;
private boolean isPlaying = false;
private int playMode = 0;
private PhoenixCore core;
List<JukeboxStateListener> stateListener = new ArrayList<JukeboxStateListener>();
/**
* spielt die lieder ab sollte am besten in einem eigenen thread geschehen.
*/
private PlayerAbstractionLayer player;
/**
* zu spielende Tracks befinden sich in der Lib
*/
private Library tracks;
/**
* gibt an, an welcher position sich die wiedergabe befindet (z.B. das 5.
* lied der liste)
*/
private int playCursor;
/**
* für den shuffle-modus
*/
Random r = new Random(System.currentTimeMillis());
public Jukebox(PhoenixCore core) {
player = new PlayerAbstractionLayer(this, core);
stateListener.add(core);
this.core = core;
}
/**
* benachrichtigt die listener über geänderten status
*/
public void stateChanged(int state) {
for (JukeboxStateListener l : stateListener) {
l.jukeboxStateChanged(state);
}
}
public void addStateListener(JukeboxStateListener l) {
stateListener.add(l);
}
/**
* Setzt die Trackliste und beginnt bei beginIndex an abzuspielen.
*
* @param tracks
* @param beginIndex
*/
public void play(Library lib, int beginIndex) {
playCursor = beginIndex;
this.tracks = lib;
if (playTrack(tracks.getTrackAt(beginIndex), core.getVolume(), true)) {
isPlaying = true;
hasFinished=false;
stateChanged(JukeboxStateListener.PLAYING);
} else {
next();
}
}
/**
* übergebene Liste vom ersten lied ab spielen
*
* @param library
*/
public void play(Library library) {
this.tracks = library;
hasFinished = false;
playTrack(this.tracks.getTrackAt(0), core.getVolume(), true);
isPlaying = true;
stateChanged(JukeboxStateListener.PLAYING);
}
public void pause() {
player.pause();
isPlaying = false;
stateChanged(JukeboxStateListener.PAUSED);
}
public boolean hasFinnished() {
return hasFinished;
}
public boolean isPlaying() {
return isPlaying;
}
public void play() {
player.play();
isPlaying = true;
hasFinished = false;
stateChanged(JukeboxStateListener.PLAYING);
}
public void next() {
if (playMode == Jukebox.NO_REPEAT_MODE) { // normalmodus, also
Track t = core.getQueueLib().pullTrack(0);//ist was in der warteschlange?
if (null!=t){//wenn ja,
playTrack(t, core.getVolume(), true);//abspielen
isPlaying=true;
hasFinished=false;
core.updateQueue();
return;
}//sonst
playCursor++;
if (playCursor >= tracks.size()) { // gibt es ein nächstes lied?
playCursor = 0;
hasFinished = true; // liste ist durch, stop
isPlaying = false;
player.stop();
stateChanged(JukeboxStateListener.PAUSED);
} else {
if (!tracks.getTrackAt(playCursor).isChecked()) {
next();
return;
}
playTrack(tracks.getTrackAt(playCursor), core.getVolume(), true);
isPlaying = true; // liste ist nicht durch, nächstes lied
hasFinished = false;
}
} else if (playMode == Jukebox.SHUFFLE_MODE) {
Library l = core.getQueueLib();//ist was in der warteschlange?
if (l.getTrackCount()>0){//wenn ja,
playTrack(l.pullTrack(r.nextInt(l.getTrackCount()-1)), core.getVolume(), true);//abspielen
isPlaying=true;
hasFinished=false;
core.updateQueue();
return;
}//sonst
int rand = r.nextInt(tracks.size());
if (!tracks.getTrackAt(rand).isChecked()) {
next();
return;
}
playCursor= rand;
playTrack(tracks.getTrackAt(rand), core.getVolume(), true);
hasFinished = false; // random lied abspielen
isPlaying = true;
} else if (playMode == Jukebox.REPEAT_ALL_MODE) {
Track t = core.getQueueLib().pullTrack(0);//ist was in der warteschlange?
if (null!=t){//wenn ja,
playTrack(t, core.getVolume(), true);//abspielen
isPlaying=true;
hasFinished=false;
core.updateQueue();
return;
}//sonst
playCursor++;
if (playCursor >= tracks.size()) {
playCursor = 0; // wenn liste durch, einfach oben wieder
// anfangen
}
if (!tracks.getTrackAt(playCursor).isChecked()) {
next();
return;
}
playTrack(tracks.getTrackAt(playCursor), core.getVolume(), true);
isPlaying = true;
hasFinished = false;
} else if (playMode == Jukebox.REPEAT_MODE) {
//playCursor nicht hochzaehlen
playTrack(tracks.getTrackAt(playCursor), core.getVolume(), true);// lied wiederholen
//player.seek(0);
isPlaying = true;
hasFinished = false;
}
}
public void finnishedPlayingTrack() {
isPlaying = false;
next();
}
public void setVolume(int percent) {
player.setVolume(percent);
}
public void prev() {
if (playMode == Jukebox.NO_REPEAT_MODE || playMode == Jukebox.REPEAT_ALL_MODE) { // normalmodus oder alle wiederholen, also
playCursor--;
if (playCursor < 0) { //wenn beim obersten lied: unten wieder anfangen.
playCursor = tracks.size() - 1;
}
if (!tracks.getTrackAt(playCursor).isChecked()) {
prev();
return;
}
playTrack(tracks.getTrackAt(playCursor), core.getVolume(), false);
isPlaying = true;
hasFinished = false;
} else if (playMode == Jukebox.SHUFFLE_MODE) {
int rand = r.nextInt(tracks.size());
if (!tracks.getTrackAt(rand).isChecked()) {
prev();
return;
}
playCursor=rand;
playTrack(tracks.getTrackAt(rand), core.getVolume(), false);
hasFinished = false; // random lied abspielen
isPlaying = true;
} else if (playMode == Jukebox.REPEAT_MODE) {
player.seek(0);
isPlaying = true; // lied wiederholen
hasFinished = false;
}
}
private boolean playTrack(Track t, int volume, boolean isNext) {
if (!t.getPath().toFile().exists()) {//existiert die datei?
System.out.println("Datei "+t.getPath().toString()+" existiert nicht, ueberspringe lied.");
if (isNext) {
next();
}else {
prev();
}
return false;
} else {
player.playTrack(t, volume);
return true;
}
}
public boolean isEmpty() {
return tracks==null|| 1>tracks.size();
}
public void setPlayMode(int newMode) {
playMode = newMode;
}
public BoundedRangeModel getRangeModel() {
return player;
}
}