Home | History | Annotate | Download | only in media
      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).
     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).
     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 
     70     public ArrayList<MediaBucket> get() {
     71         return mBuckets;
     72     }
     73 
     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 
    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.mediaSet != null && mediaSetToAdd != null && bucketCompare.mediaSet.mId == mediaSetToAdd.mId) {
    134                 // We found the MediaSet.
    135                 if (!hasExpandedMediaSet) {
    136                     // Remove this bucket from the list since this bucket was
    137                     // already selected.
    138                     if (removeIfAlreadyAdded) {
    139                         selectedBuckets.remove(bucketCompare);
    140                     }
    141                     return;
    142                 } else {
    143                     bucket = bucketCompare;
    144                     break;
    145                 }
    146             }
    147         }
    148         if (bucket == null) {
    149             // Did not find the media bucket.
    150             bucket = new MediaBucket();
    151             bucket.mediaSet = mediaSetToAdd;
    152             bucket.mediaItems = selectedItems;
    153             selectedBuckets.add(bucket);
    154         }
    155         if (hasExpandedMediaSet) {
    156             int numSlots = feed.getNumSlots();
    157             if (slotId < numSlots) {
    158                 MediaSet set = feed.getSetForSlot(slotId);
    159                 if (set != null) {
    160                     ArrayList<MediaItem> items = set.getItems();
    161                     int numItems = set.getNumItems();
    162                     selectedItems = bucket.mediaItems;
    163                     if (selectedItems == null) {
    164                         selectedItems = new ArrayList<MediaItem>(numItems);
    165                         bucket.mediaItems = selectedItems;
    166                     }
    167                     for (int i = 0; i < numItems; ++i) {
    168                         MediaItem item = items.get(i);
    169                         // We see if this item has already been added.
    170                         int numPresentItems = selectedItems.size();
    171                         boolean foundIndex = false;
    172                         for (int j = 0; j < numPresentItems; ++j) {
    173                             final MediaItem selectedItem = selectedItems.get(j);
    174                             if (selectedItem != null && item != null && selectedItem.mId == item.mId) {
    175                                 // This index was already present, we need to
    176                                 // remove it.
    177                                 foundIndex = true;
    178                                 if (removeIfAlreadyAdded) {
    179                                     selectedItems.remove(j);
    180                                 }
    181                                 break;
    182                             }
    183                         }
    184                         if (foundIndex == false) {
    185                             selectedItems.add(item);
    186                         }
    187                     }
    188                 }
    189             }
    190         }
    191         setDirty();
    192     }
    193 
    194     public boolean find(MediaItem item) {
    195         HashMap<MediaItem, Boolean> cachedItems = mCachedItems;
    196         if (mDirtyAcceleratedLookup) {
    197             cachedItems.clear();
    198             mDirtyAcceleratedLookup = false;
    199         }
    200         Boolean itemAdded = cachedItems.get(item);
    201         if (itemAdded == null) {
    202             ArrayList<MediaBucket> selectedBuckets = mBuckets;
    203             int numSelectedBuckets = selectedBuckets.size();
    204             for (int i = 0; i < numSelectedBuckets; ++i) {
    205                 MediaBucket bucket = selectedBuckets.get(i);
    206                 ArrayList<MediaItem> mediaItems = bucket.mediaItems;
    207                 if (mediaItems == null) {
    208                     MediaSet parentMediaSet = item.mParentMediaSet;
    209                     if (parentMediaSet != null && parentMediaSet.equals(bucket.mediaSet)) {
    210                         cachedItems.put(item, TRUE);
    211                         return true;
    212                     }
    213                 } else {
    214                     int numMediaItems = mediaItems.size();
    215                     for (int j = 0; j < numMediaItems; ++j) {
    216                         MediaItem itemCompare = mediaItems.get(j);
    217                         if (itemCompare == item) {
    218                             cachedItems.put(item, TRUE);
    219                             return true;
    220                         }
    221                     }
    222                 }
    223             }
    224             cachedItems.put(item, FALSE);
    225             return false;
    226         } else {
    227             return itemAdded.booleanValue();
    228         }
    229     }
    230 
    231     public void clear() {
    232         mBuckets.clear();
    233         setDirty();
    234     }
    235 
    236     private void setDirty() {
    237         mDirtyCount = true;
    238         mDirtyAcceleratedLookup = true;
    239     }
    240 
    241     // Assumption: No item and set selection combinations.
    242     protected static boolean isSetSelection(ArrayList<MediaBucket> buckets) {
    243         if (buckets != null) {
    244             int numBuckets = buckets.size();
    245             if (numBuckets == 0) {
    246                 return false;
    247             } else if (numBuckets == 1) {
    248                 return isSetSelection(buckets.get(0));
    249             } else {
    250                 // If there are multiple sets, must be a set selection.
    251                 return true;
    252             }
    253         }
    254         return false;
    255     }
    256 
    257     protected static boolean isSetSelection(MediaBucket bucket) {
    258         return (bucket.mediaSet != null && bucket.mediaItems == null) ? true : false;
    259     }
    260 
    261     // Assumption: If multiple items are selected, they must all be in the first
    262     // bucket.
    263     protected static boolean isMultipleItemSelection(ArrayList<MediaBucket> buckets) {
    264         if (buckets != null) {
    265             int numBuckets = buckets.size();
    266             if (numBuckets == 0) {
    267                 return false;
    268             } else {
    269                 return isMultipleSetSelection(buckets.get(0));
    270             }
    271         }
    272         return false;
    273     }
    274 
    275     protected static boolean isMultipleSetSelection(MediaBucket bucket) {
    276         return (bucket.mediaItems != null && bucket.mediaItems.size() > 1) ? true : false;
    277     }
    278 }
    279