3 import interfaces
.collection
.AbstractCollection
;
4 import interfaces
.collection
.Collection
;
5 import interfaces
.collection
.Source
;
7 import java
.util
.ArrayList
;
8 import java
.util
.HashSet
;
9 import java
.util
.Iterator
;
10 import java
.util
.LinkedList
;
11 import java
.util
.List
;
14 import notification
.AbstractEventGenerator
;
15 import notification
.QueueListener
;
17 class PlaybackQueue
extends AbstractEventGenerator
<QueueListener
>
18 implements interfaces
.PlaybackQueue
, Source
.Listener
{
20 public static final int RECENT
= 5;
21 public static final int QUEUED
= 10;
23 private Source
<?
extends Track
> source
;
25 private volatile Track current
;
26 private volatile int position
;
27 private LinkedList
<Track
> queued
;
28 private LinkedList
<Track
> recent
;
30 public PlaybackQueue(Source
<?
extends Track
> source
) {
31 queued
= new LinkedList
<Track
>();
32 recent
= new LinkedList
<Track
>();
35 source
.registerListener(this);
38 public synchronized void next() {
40 System
.out
.println("queue: next");
42 if (current
!= null) {
43 recent
.addLast(current
);
44 while (recent
.size() > RECENT
) {
49 while (queued
.size() < QUEUED
&& source
.hasNext()) {
50 queued
.addLast(source
.next());
53 if (!queued
.isEmpty()) {
54 current
= queued
.removeFirst();
63 public synchronized void prev() {
65 System
.out
.println("queue: prev");
67 if (!recent
.isEmpty()) {
69 if (current
!= null) {
70 queued
.addFirst(current
);
74 current
= recent
.removeLast();
80 public synchronized void clear() {
83 System
.out
.println("queue cleared");
88 public synchronized void enqueue(List
<?
extends Track
> tracks
) {
89 queued
.addAll(tracks
);
94 public synchronized boolean hasSongs() {
95 return !queued
.isEmpty();
98 public synchronized void added(Iterable
<?
extends Track
> tracks
) {
100 System
.out
.println("songs added: updating queue");
102 boolean empty
= queued
.isEmpty() && current
== null;
104 while (queued
.size() < QUEUED
&& source
.hasNext()) {
105 queued
.addLast(source
.next());
106 System
.out
.println("added " + queued
.getLast());
109 if (!queued
.isEmpty() && empty
) {
110 if (empty
) notifyTracksAvailable();
111 else notifyQueueChanged();
115 public synchronized void removed(Set
<?
extends Track
> tracks
) {
117 boolean changed
= false;
119 for (Iterator
<Track
> it
= recent
.iterator(); it
.hasNext();) {
120 if (tracks
.contains(it
.next())) {
125 if (current
!= null && tracks
.contains(current
)) {
129 for (Iterator
<Track
> it
= queued
.iterator(); it
.hasNext();) {
130 if (tracks
.contains(it
.next())) {
136 if (!changed
) return;
138 if (current
== null) {
142 if (current
== null) {
146 notifyQueueChanged();
150 protected synchronized void remove(Track t
) {
152 if (current
== t
) current
= null;
156 public synchronized Track
current() {
160 public synchronized int position() {
164 public synchronized Collection
<?
extends Track
> playlist() {
166 //TODO create collection
167 List
<Track
> tracks
= new ArrayList
<Track
>();
168 tracks
.addAll(recent
);
169 if (current
!= null) tracks
.add(current
);
170 tracks
.addAll(queued
);
172 return new PlaybackQueueCollection(tracks
);
175 public synchronized void setSource(Source
<?
extends Track
> source
) {
177 this.source
.removeListener(this);
179 Set
<Track
> removed
= new HashSet
<Track
>();
180 for (Track t
: this.source
.tracks()) {
184 this.source
.registerListener(this);
185 this.source
= source
;
187 for (Track t
: this.source
.tracks()) {
194 protected void notifyQueueEmpty() {
195 System
.out
.println("queue empty");
196 for (QueueListener l
: super.listeners()) {
201 protected void notifyTracksAvailable() {
202 System
.out
.println("tracks available");
203 for (QueueListener l
: super.listeners()) {
208 protected void notifyQueueChanged() {
209 System
.out
.println("queue changed");
210 for (QueueListener l
: super.listeners()) {
215 private class PlaybackQueueCollection
extends AbstractCollection
<Track
> {
217 private final List
<Track
> tracks
;
218 private final Iterator
<Track
> trackIt
;
220 public PlaybackQueueCollection(List
<Track
> tracks
) {
221 super(Collection
.QUEUE_ID
, Collection
.QUEUE_PERSISTENT_ID
);
222 this.tracks
= tracks
;
223 this.trackIt
= tracks
.iterator();
226 public boolean hasNext() {
227 return trackIt
.hasNext();
230 public Track
next() {
231 return trackIt
.next();
234 public int editStatus() {
238 public Iterable
<?
extends Track
> tracks() {
242 public Iterator
<Track
> iterator() {
243 return tracks
.iterator();
250 public long persistentId() {
251 return source
.persistentId();
254 public boolean isRoot() {
255 // TODO Auto-generated method stub
259 public String
name() {
260 return source
.name();
263 public Collection
<Track
> parent() {
268 return tracks
.size();