• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.cooliris.media;
18 
19 import java.util.ArrayList;
20 import java.util.HashMap;
21 
22 public final class MediaBucketList {
23     private static final Boolean TRUE = new Boolean(true);
24     private static final Boolean FALSE = new Boolean(false);
25 
26     private ArrayList<MediaBucket> mBuckets = new ArrayList<MediaBucket>(1024);
27     private boolean mDirtyCount;
28     private boolean mDirtyAcceleratedLookup;
29     private int mCount;
30     private HashMap<MediaItem, Boolean> mCachedItems = new HashMap<MediaItem, Boolean>(1024);
31 
32     // If only albums are selected, a bucket contains mediaSets.
33     // If items are selected, a bucket contains mediaSets and mediaItems.
34 
35     // Returns the first item selection (ignoring items within set selections).
getFirstItemSelection(ArrayList<MediaBucket> buckets)36     public static MediaItem getFirstItemSelection(ArrayList<MediaBucket> buckets) {
37         MediaItem item = null;
38         if (buckets != null) {
39             int numBuckets = buckets.size();
40             for (int i = 0; i < numBuckets; i++) {
41                 MediaBucket bucket = buckets.get(0);
42                 if (bucket != null && !isSetSelection(bucket)) {
43                     ArrayList<MediaItem> items = bucket.mediaItems;
44                     if (items != null && items.size() > 0) {
45                         item = items.get(0);
46                         break;
47                     }
48                 }
49             }
50         }
51         return item;
52     }
53 
54     // Returns the first set selection (ignoring sets corresponding to item
55     // selections).
getFirstSetSelection(ArrayList<MediaBucket> buckets)56     public static MediaSet getFirstSetSelection(ArrayList<MediaBucket> buckets) {
57         MediaSet set = null;
58         if (buckets != null) {
59             int numBuckets = buckets.size();
60             for (int i = 0; i < numBuckets; i++) {
61                 MediaBucket bucket = buckets.get(0);
62                 if (bucket != null && isSetSelection(bucket)) {
63                     set = bucket.mediaSet;
64                 }
65             }
66         }
67         return set;
68     }
69 
get()70     public ArrayList<MediaBucket> get() {
71         return mBuckets;
72     }
73 
size()74     public int size() {
75         if (mDirtyCount) {
76             ArrayList<MediaBucket> buckets = mBuckets;
77             int numBuckets = buckets.size();
78             int count = 0;
79             for (int i = 0; i < numBuckets; ++i) {
80                 MediaBucket bucket = buckets.get(i);
81                 int numItems = 0;
82                 if (bucket.mediaItems == null && bucket.mediaSet != null) {
83                     numItems = bucket.mediaSet.getNumItems();
84                     // This selection reflects the bucket itself, and not the
85                     // items inside the bucket (which is 0).
86                     if (numItems == 0) {
87                         numItems = 1;
88                     }
89                 } else if (bucket.mediaItems != null && bucket.mediaItems != null) {
90                     numItems = bucket.mediaItems.size();
91                 }
92                 count += numItems;
93             }
94             mCount = count;
95             mDirtyCount = false;
96         }
97         return mCount;
98     }
99 
add(int slotId, MediaFeed feed, boolean removeIfAlreadyAdded)100     public void add(int slotId, MediaFeed feed, boolean removeIfAlreadyAdded) {
101         if (slotId == Shared.INVALID) {
102             return;
103         }
104         setDirty();
105         final ArrayList<MediaBucket> selectedBuckets = mBuckets;
106         final int numSelectedBuckets = selectedBuckets.size();
107         MediaSet mediaSetToAdd = null;
108         ArrayList<MediaItem> selectedItems = null;
109         MediaBucket bucket = null;
110         final boolean hasExpandedMediaSet = feed.hasExpandedMediaSet();
111         if (!hasExpandedMediaSet) {
112             ArrayList<MediaSet> mediaSets = feed.getMediaSets();
113             if (slotId >= mediaSets.size()) {
114                 return;
115             }
116             mediaSetToAdd = mediaSets.get(slotId);
117         } else {
118             int numSlots = feed.getNumSlots();
119             if (slotId < numSlots) {
120                 MediaSet set = feed.getSetForSlot(slotId);
121                 if (set != null) {
122                     ArrayList<MediaItem> items = set.getItems();
123                     if (set.getNumItems() > 0) {
124                         mediaSetToAdd = items.get(0).mParentMediaSet;
125                     }
126                 }
127             }
128         }
129 
130         // Search for the bucket for this media set
131         for (int i = 0; i < numSelectedBuckets; ++i) {
132             final MediaBucket bucketCompare = selectedBuckets.get(i);
133             if (bucketCompare != null && bucketCompare.mediaSet != null
134                 && mediaSetToAdd != null && bucketCompare.mediaSet == mediaSetToAdd) {
135                 // We found the MediaSet.
136                 if (!hasExpandedMediaSet) {
137                     // Remove this bucket from the list since this bucket was
138                     // already selected.
139                     if (removeIfAlreadyAdded) {
140                         selectedBuckets.remove(bucketCompare);
141                     }
142                     return;
143                 } else {
144                     bucket = bucketCompare;
145                     break;
146                 }
147             }
148         }
149         if (bucket == null) {
150             // Did not find the media bucket.
151             bucket = new MediaBucket();
152             bucket.mediaSet = mediaSetToAdd;
153             bucket.mediaItems = selectedItems;
154             selectedBuckets.add(bucket);
155         }
156         if (hasExpandedMediaSet) {
157             int numSlots = feed.getNumSlots();
158             if (slotId < numSlots) {
159                 MediaSet set = feed.getSetForSlot(slotId);
160                 if (set != null) {
161                     ArrayList<MediaItem> items = set.getItems();
162                     int numItems = set.getNumItems();
163                     selectedItems = bucket.mediaItems;
164                     if (selectedItems == null) {
165                         selectedItems = new ArrayList<MediaItem>(numItems);
166                         bucket.mediaItems = selectedItems;
167                     }
168                     for (int i = 0; i < numItems; ++i) {
169                         MediaItem item = items.get(i);
170                         // We see if this item has already been added.
171                         int numPresentItems = selectedItems.size();
172                         boolean foundIndex = false;
173                         for (int j = 0; j < numPresentItems; ++j) {
174                             final MediaItem selectedItem = selectedItems.get(j);
175                             if (selectedItem != null && item != null && selectedItem == item) {
176                                 // This index was already present, we need to
177                                 // remove it.
178                                 foundIndex = true;
179                                 if (removeIfAlreadyAdded) {
180                                     selectedItems.remove(j);
181                                 }
182                                 break;
183                             }
184                         }
185                         if (foundIndex == false) {
186                             selectedItems.add(item);
187                         }
188                     }
189                 }
190             }
191         }
192         setDirty();
193     }
194 
find(MediaItem item)195     public boolean find(MediaItem item) {
196         HashMap<MediaItem, Boolean> cachedItems = mCachedItems;
197         if (mDirtyAcceleratedLookup) {
198             cachedItems.clear();
199             mDirtyAcceleratedLookup = false;
200         }
201         Boolean itemAdded = cachedItems.get(item);
202         if (itemAdded == null) {
203             ArrayList<MediaBucket> selectedBuckets = mBuckets;
204             int numSelectedBuckets = selectedBuckets.size();
205             for (int i = 0; i < numSelectedBuckets; ++i) {
206                 MediaBucket bucket = selectedBuckets.get(i);
207                 ArrayList<MediaItem> mediaItems = bucket.mediaItems;
208                 if (mediaItems == null) {
209                     MediaSet parentMediaSet = item.mParentMediaSet;
210                     if (parentMediaSet != null && parentMediaSet.equals(bucket.mediaSet)) {
211                         cachedItems.put(item, TRUE);
212                         return true;
213                     }
214                 } else {
215                     int numMediaItems = mediaItems.size();
216                     for (int j = 0; j < numMediaItems; ++j) {
217                         MediaItem itemCompare = mediaItems.get(j);
218                         if (itemCompare == item) {
219                             cachedItems.put(item, TRUE);
220                             return true;
221                         }
222                     }
223                 }
224             }
225             cachedItems.put(item, FALSE);
226             return false;
227         } else {
228             return itemAdded.booleanValue();
229         }
230     }
231 
clear()232     public void clear() {
233         mBuckets.clear();
234         setDirty();
235     }
236 
setDirty()237     private void setDirty() {
238         mDirtyCount = true;
239         mDirtyAcceleratedLookup = true;
240     }
241 
242     // Assumption: No item and set selection combinations.
isSetSelection(ArrayList<MediaBucket> buckets)243     protected static boolean isSetSelection(ArrayList<MediaBucket> buckets) {
244         if (buckets != null) {
245             int numBuckets = buckets.size();
246             if (numBuckets == 0) {
247                 return false;
248             } else if (numBuckets == 1) {
249                 return isSetSelection(buckets.get(0));
250             } else {
251                 // If there are multiple sets, must be a set selection.
252                 return true;
253             }
254         }
255         return false;
256     }
257 
isSetSelection(MediaBucket bucket)258     protected static boolean isSetSelection(MediaBucket bucket) {
259         return (bucket.mediaSet != null && bucket.mediaItems == null) ? true : false;
260     }
261 
262     // Assumption: If multiple items are selected, they must all be in the first
263     // bucket.
isMultipleItemSelection(ArrayList<MediaBucket> buckets)264     protected static boolean isMultipleItemSelection(ArrayList<MediaBucket> buckets) {
265         if (buckets != null) {
266             int numBuckets = buckets.size();
267             if (numBuckets == 0) {
268                 return false;
269             } else {
270                 return isMultipleSetSelection(buckets.get(0));
271             }
272         }
273         return false;
274     }
275 
isMultipleSetSelection(MediaBucket bucket)276     protected static boolean isMultipleSetSelection(MediaBucket bucket) {
277         return (bucket.mediaItems != null && bucket.mediaItems.size() > 1) ? true : false;
278     }
279 }
280