1 package org.musicontroller.gui.edit;
2
3 import org.musicontroller.core.Contract_PS;
4 import org.musicontroller.core.Playlist;
5 import org.varienaja.util.DenseSet;
6
7 /**
8 * Helper class to construct a track listing of track index
9 * numbers satisfying some condition. For example, the tracks
10 * on which some artist plays guitar.
11 * Tracks can be "added" using the add() method. Adding a
12 * track increases the track counter. The track counter can be
13 * queried using getTrackCount().
14 * The same track index number may be added more than once. Each
15 * addition will increase the track counter, but the track list will
16 * contain each added track index number exactly once.
17 * @author Hans Drexler
18 * @version $Id: TrackList.java,v 1.1 2010/03/16 18:55:42 varienaja Exp $
19 */
20 public class TrackList {
21
22 /**
23 * Keeps a count of the added tracks.
24 */
25 private int _trackcount;
26
27 /**
28 * Set of track numbers of the tracks in the list.
29 */
30 private DenseSet _tracks;
31
32 /**
33 * Stores the index of the last track of a playlist.
34 */
35 private int _highestIndexNr;
36
37 /**
38 * Default constructor.
39 *
40 */
41 public TrackList() {
42 _trackcount = 0;
43 _tracks = new DenseSet();
44 _highestIndexNr = -100;
45 }
46
47 /**
48 * Getter for the track counter.
49 * @return The track counter.
50 */
51 public int getTrackCount() {
52 return _trackcount;
53 }
54
55 /**
56 * Adds a track to the listing, increasing the
57 * track counter. Track 0 may be added multiple time, increasing
58 * the track count at every addition. Other track numbers will
59 * only be counted once. Negative track numbers are ignored.
60 * @param trackno The track index number.
61 */
62 public void add(int trackno) {
63 if (trackno<0) {
64 return;
65 } else if (trackno==0) {
66 _trackcount++;
67 _tracks.add(trackno);
68 } else if(!contains(trackno)) {
69 _trackcount++;
70 _tracks.add(trackno);
71 }
72 }
73
74 /**
75 * Returns a string containing the numerically sorted
76 * track numbers of the added tracks separated by commas.
77 * @return The track listing.
78 */
79 public String getTrackListing() {
80 return _tracks.prettyPrint();
81 }
82
83 /**
84 * Two TrackLists are equal if they contain the same tracks.
85 */
86 public boolean equals(Object other) {
87 if(other==null) {
88 return false;
89 }
90 if (other instanceof TrackList) {
91 TrackList otherList = (TrackList) other;
92 return this.getTrackCount()==otherList.getTrackCount() && this._tracks.equals(otherList._tracks);
93 } else {
94 return false;
95 }
96 }
97
98 public int hashCode() {
99 return 17 * getTrackCount() + _tracks.hashCode();
100 }
101
102 /**
103 * Factory method for constructing TrackLists from strings representing
104 * track numbers separated by commas.
105 * @param tracks The string representing the track numbers.
106 * @return A tracklist object reflecting the track numbers in the string.
107 */
108 public static TrackList createInstance(String tracks) {
109 TrackList result = new TrackList();
110 if(tracks==null) {
111 return result;
112 }
113 result.setTracks(tracks);
114 return result;
115 }
116
117 /**
118 * Factory method creates a tracklist containing all tracks in the playlist.
119 * @param playlist The playlist. If the playlist is null, the result is an empty tracklist.
120 * @return A Track list with all tracks in the play list.
121 */
122 public static TrackList createInstance(Playlist playlist) {
123 TrackList result = new TrackList();
124 if(playlist!=null) {
125 for(Contract_PS contract: playlist.getSongs()) {
126 result.add(contract.getRowno());
127 }
128 }
129 return result;
130 }
131
132 /**
133 * Tests if the track number is contained in the Tracklist.
134 * @param trackno The track number to test.
135 * @return true if the track number is included in the track list, false otherwise.
136 */
137 public boolean contains(int trackno) {
138 return _tracks.contains(trackno);
139 }
140
141 /**
142 * Sets the index number of the last song in the tracklist.
143 * TrackList uses this number to determine if the entered
144 * tracks are equal to all tracks in the playlist.
145 * @param highestTrackNo the index of the last song in the tracklist
146 */
147 public void setHighestIndexNr(int highestTrackNo) {
148 this._highestIndexNr = highestTrackNo;
149 }
150
151 /**
152 * Getter for the highest track number.
153 * @return The highest track number.
154 */
155 public int getHighestIndexNr() {
156 return this._highestIndexNr;
157 }
158
159 /**
160 * Returns true if the number of added songs is greater or equal
161 * than the highestIndexNo. Return false in all other cases.
162 * @return True if getHighestIndexNr() <= getTrackCount() or else false.
163 */
164 public boolean containsAllSongs() {
165 return getHighestIndexNr() <= getTrackCount();
166 }
167
168 /**
169 * Adds all tracks in the tracks String to the list
170 * of tracks indexes. Track indexes are positive integers
171 * separated by commas. range indications are also allowed, like "7-9".
172 * @param tracks A String containing the tracks to add.
173 */
174 public void setTracks(String tracks) {
175 String[] tracknos = tracks.split("\\s*,\\s*");
176 for(String range: tracknos) {
177 range = range.trim();
178 String[] rangebounds = range.split("\\s*-\\s*");
179 if(rangebounds.length>1) {
180 String lwb = rangebounds[0];
181 String upb = rangebounds[1];
182 int lwbno = -1;
183 int upbno = -1;
184 try {
185 lwbno = Integer.parseInt(lwb);
186 upbno = Integer.parseInt(upb);
187 } catch(NumberFormatException nfe) {
188 // Not a valid integer --> ignore.
189 }
190 for (int trackindex=lwbno; trackindex<=upbno;trackindex++) {
191 add(trackindex);
192 }
193 } else {
194 try {
195 int inttrackno = Integer.parseInt(range);
196 add(inttrackno);
197 } catch(NumberFormatException nfe) {
198 // Not a valid integer --> ignore.
199 }
200 }
201 }
202 }
203
204 /**
205 * Returns a short human readable representation of the track list.
206 */
207 public String toString() {
208 return _tracks.prettyPrint();
209 }
210 }