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
19 package sk.baka.ambient.collection;
20
21 import java.util.Collections;
22 import java.util.Comparator;
23 import java.util.List;
24
25 import android.provider.MediaStore.Audio;
26
27 import sk.baka.ambient.commons.MiscUtils;
28
29 /***
30 * Various collection utility methods.
31 *
32 * @author Martin Vysny
33 */
34 public final class CollectionUtils {
35 private CollectionUtils() {
36 throw new Error();
37 }
38
39 /***
40 * Sorts given category item list by {@link CategoryItem#name}.
41 *
42 * @param items
43 * the items to sort.
44 */
45 public static void sortByKey(final List<CategoryItem> items) {
46 Collections.sort(items, CATEGORY_KEY_COMPARATOR);
47 }
48
49 private final static Comparator<CategoryItem> CATEGORY_KEY_COMPARATOR = new Comparator<CategoryItem>() {
50 public int compare(CategoryItem object1, CategoryItem object2) {
51 return MiscUtils.nullCompare(object1.sortKey, object2.sortKey, true);
52 }
53 };
54
55 /***
56 * Sorts given category item list by {@link CategoryItem#sortKey}.
57 *
58 * @param items
59 * the items to sort.
60 */
61 public static void sortByYearKey(final List<CategoryItem> items) {
62 Collections.sort(items, CATEGORY_YEAR_KEY_COMPARATOR);
63 }
64
65 private final static Comparator<CategoryItem> CATEGORY_YEAR_KEY_COMPARATOR = new Comparator<CategoryItem>() {
66 public int compare(CategoryItem object1, CategoryItem object2) {
67 final int result = MiscUtils.nullCompare(object1.year,
68 object2.year, true);
69 if (result != 0) {
70 return result;
71 }
72 return MiscUtils.nullCompare(object1.sortKey, object2.sortKey, true);
73 }
74 };
75
76 /***
77 * Sorts given track list by {@link TrackMetadataBean#getDisplayableName()}.
78 *
79 * @param tracks
80 * the tracks to sort.
81 */
82 public static void sortByTitle(final List<TrackMetadataBean> tracks) {
83 Collections.sort(tracks, TRACK_NAME_COMPARATOR);
84 }
85
86 private static final Comparator<TrackMetadataBean> TRACK_NAME_COMPARATOR = new Comparator<TrackMetadataBean>() {
87 public int compare(TrackMetadataBean object1, TrackMetadataBean object2) {
88 return object1.getDisplayableName().compareToIgnoreCase(
89 object2.getDisplayableName());
90 }
91 };
92
93 /***
94 * Orders the tracks by albums, track number and finally by displayable
95 * name.
96 *
97 * @author Martin Vysny
98 */
99 protected static final class AlbumOrderComparator implements
100 Comparator<TrackMetadataBean> {
101 public int compare(TrackMetadataBean object1, TrackMetadataBean object2) {
102
103 int result = MiscUtils.nullCompare(object1.getAlbum(), object2
104 .getAlbum(), true);
105 if (result != 0) {
106 return result;
107 }
108
109 final Object tn1 = parseInt(object1.getTrackNumber());
110 final Object tn2 = parseInt(object2.getTrackNumber());
111 result = tn1 == null ? (tn2 == null ? 0 : -1) : (tn2 == null ? 1
112 : compareTrackNumber(tn1, tn2));
113 if (result != 0)
114 return result;
115
116 return object1.getDisplayableName().compareToIgnoreCase(
117 object2.getDisplayableName());
118 }
119 }
120
121 private static Object parseInt(final String str) {
122 if (str == null)
123 return null;
124 try {
125 return Integer.valueOf(str);
126 } catch (NumberFormatException e) {
127 return str;
128 }
129 }
130
131 private static int compareTrackNumber(final Object tn1, final Object tn2) {
132 return (tn1 instanceof Integer) ? (tn2 instanceof Integer ? ((Integer) tn1)
133 .compareTo((Integer) tn2)
134 : -1)
135 : (tn2 instanceof Integer ? 1 : ((String) tn1)
136 .compareTo((String) tn2));
137 }
138
139 /***
140 * Orders the tracks by albums, track number and finally by filenames.
141 */
142 public static final Comparator<TrackMetadataBean> ALBUM_ORDER_COMPARATOR = new AlbumOrderComparator();
143
144 /***
145 * Sorts the tracks by albums, track number and finally by filenames.
146 *
147 * @param playlist
148 * the playlist to sort.
149 */
150 public static void sortByAlbumOrder(final List<TrackMetadataBean> playlist) {
151 Collections.sort(playlist, ALBUM_ORDER_COMPARATOR);
152 }
153
154 /***
155 * Similar to {@link Audio#keyFor(String)} with a bit relaxed rules: remove
156 * leading/trailing spaces, convert everything to lowercase, remove leading
157 * "the "
158 *
159 * @param name
160 * the name
161 * @return key for given name, may be <code>null</code> if the name was
162 * <code>null</code>
163 */
164 public static String keyFor(final String name) {
165 if (name == null) {
166 return null;
167 }
168 String result = name.trim().toLowerCase();
169 if (result.startsWith("the")
170 && Character.isWhitespace(result.charAt(3))) {
171 result = result.substring(4);
172 }
173 return result;
174 }
175 }