1 /***
2 * Ambient - A music player for the Android platform
3 Copyright (C) 2007 Martin Vysny
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 package sk.baka.ambient.playlist;
19
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.Map;
24
25 /***
26 * Random play.
27 *
28 * @author Martin Vysny
29 */
30 public enum Random {
31 /***
32 * No random play, tracks will be played as ordered by the playlist.
33 */
34 NONE(false),
35 /***
36 *
37 */
38 TRACK(false),
39 /***
40 * A random album is selected which is then played regularly (in album
41 * order).
42 */
43 ALBUM(true),
44 /***
45 * A random album is selected which is then played in the playlist order
46 * (order in which tracks appear in the playlist).
47 */
48 ALBUM_PLAYLIST(true),
49 /***
50 * A random album is selected and random tracks are played from it.
51 */
52 ALBUM_TRACK(true);
53 /***
54 * Randomizes given playlist as specified by the <code>Random</code>
55 * constant.
56 *
57 * @param random
58 * the random constant
59 * @param playlist
60 * the playlist to randomize, will not be changed.
61 * @param first
62 * place this track first if possible. May be <code>null</code>
63 * if it doesn't matter which track is the first one.
64 * @return a new, shuffled list.
65 */
66 public static List<PlaylistItem> randomize(final Random random,
67 final List<? extends PlaylistItem> playlist,
68 final PlaylistItem first) {
69
70
71 switch (random) {
72 case NONE:
73 return new ArrayList<PlaylistItem>(playlist);
74 case TRACK: {
75 final List<PlaylistItem> result = new ArrayList<PlaylistItem>(
76 playlist);
77 Collections.shuffle(result);
78 if (first != null) {
79 final int indexOfFirst = result.indexOf(first);
80 Collections.swap(result, 0, indexOfFirst);
81 }
82 return result;
83 }
84 case ALBUM:
85 case ALBUM_PLAYLIST:
86 case ALBUM_TRACK: {
87
88
89 final List<PlaylistItem> result = new ArrayList<PlaylistItem>(
90 playlist);
91 if (random == Random.ALBUM) {
92 Utils.sortPlaylistByAlbumOrder(result);
93 } else if (random == Random.ALBUM_TRACK) {
94 Collections.shuffle(result);
95 }
96
97
98 final Map<String, List<PlaylistItem>> albums = Utils
99 .getAlbumsFromPlaylist(result);
100
101 final List<String> albumNames = new ArrayList<String>(albums
102 .keySet());
103 Collections.shuffle(albumNames);
104
105 if (first != null) {
106 final int indexOfFirst = albumNames.indexOf(first.track
107 .getAlbum());
108 Collections.swap(albumNames, 0, indexOfFirst);
109 }
110
111 result.clear();
112 for (final String albumName : albumNames) {
113 result.addAll(albums.get(albumName));
114 }
115 return result;
116 }
117 }
118 throw new Error();
119 }
120
121 /***
122 * <code>true</code> if tracks are grouped by albums ({@link #ALBUM},
123 * {@link #ALBUM_PLAYLIST} and {@link #ALBUM_TRACK}) , <code>false</code>
124 * otherwise.
125 */
126 private final boolean groupsByAlbum;
127
128 private Random(final boolean groupsByAlbum) {
129 this.groupsByAlbum = groupsByAlbum;
130 }
131
132 /***
133 * Checks if this random mode groups tracks by albums.
134 *
135 * @return <code>true</code> if tracks are grouped by albums ({@link #ALBUM},
136 * {@link #ALBUM_PLAYLIST} and {@link #ALBUM_TRACK}) ,
137 * <code>false</code> otherwise.
138 */
139 public final boolean groupsByAlbum() {
140 return groupsByAlbum;
141 }
142 }