1/*
2 * Copyright (C) 2015 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
17package com.example.android.supportv4.media.utils;
18
19import java.util.Arrays;
20
21/**
22 * Utility class to help on queue related tasks.
23 */
24public class MediaIDHelper {
25
26    private static final String TAG = "MediaIDHelper";
27
28    // Media IDs used on browseable items of MediaBrowser
29    public static final String MEDIA_ID_ROOT = "__ROOT__";
30    public static final String MEDIA_ID_MUSICS_BY_GENRE = "__BY_GENRE__";
31    public static final String MEDIA_ID_MUSICS_BY_SEARCH = "__BY_SEARCH__";
32
33    private static final char CATEGORY_SEPARATOR = '/';
34    private static final char LEAF_SEPARATOR = '|';
35
36    public static String createMediaID(String musicID, String... categories) {
37        // MediaIDs are of the form <categoryType>/<categoryValue>|<musicUniqueId>, to make it easy
38        // to find the category (like genre) that a music was selected from, so we
39        // can correctly build the playing queue. This is specially useful when
40        // one music can appear in more than one list, like "by genre -> genre_1"
41        // and "by artist -> artist_1".
42        StringBuilder sb = new StringBuilder();
43        if (categories != null && categories.length > 0) {
44            sb.append(categories[0]);
45            for (int i=1; i < categories.length; i++) {
46                sb.append(CATEGORY_SEPARATOR).append(categories[i]);
47            }
48        }
49        if (musicID != null) {
50            sb.append(LEAF_SEPARATOR).append(musicID);
51        }
52        return sb.toString();
53    }
54
55    public static String createBrowseCategoryMediaID(String categoryType, String categoryValue) {
56        return categoryType + CATEGORY_SEPARATOR + categoryValue;
57    }
58
59    /**
60     * Extracts unique musicID from the mediaID. mediaID is, by this sample's convention, a
61     * concatenation of category (eg "by_genre"), categoryValue (eg "Classical") and unique
62     * musicID. This is necessary so we know where the user selected the music from, when the music
63     * exists in more than one music list, and thus we are able to correctly build the playing queue.
64     *
65     * @param mediaID that contains the musicID
66     * @return musicID
67     */
68    public static String extractMusicIDFromMediaID(String mediaID) {
69        int pos = mediaID.indexOf(LEAF_SEPARATOR);
70        if (pos >= 0) {
71            return mediaID.substring(pos+1);
72        }
73        return null;
74    }
75
76    /**
77     * Extracts category and categoryValue from the mediaID. mediaID is, by this sample's
78     * convention, a concatenation of category (eg "by_genre"), categoryValue (eg "Classical") and
79     * mediaID. This is necessary so we know where the user selected the music from, when the music
80     * exists in more than one music list, and thus we are able to correctly build the playing queue.
81     *
82     * @param mediaID that contains a category and categoryValue.
83     */
84    public static String[] getHierarchy(String mediaID) {
85        int pos = mediaID.indexOf(LEAF_SEPARATOR);
86        if (pos >= 0) {
87            mediaID = mediaID.substring(0, pos);
88        }
89        return mediaID.split(String.valueOf(CATEGORY_SEPARATOR));
90    }
91
92    public static String extractBrowseCategoryValueFromMediaID(String mediaID) {
93        String[] hierarchy = getHierarchy(mediaID);
94        if (hierarchy != null && hierarchy.length == 2) {
95            return hierarchy[1];
96        }
97        return null;
98    }
99
100    private static boolean isBrowseable(String mediaID) {
101        return mediaID.indexOf(LEAF_SEPARATOR) < 0;
102    }
103
104    public static String getParentMediaID(String mediaID) {
105        String[] hierarchy = getHierarchy(mediaID);
106        if (!isBrowseable(mediaID)) {
107            return createMediaID(null, hierarchy);
108        }
109        if (hierarchy == null || hierarchy.length <= 1) {
110            return MEDIA_ID_ROOT;
111        }
112        String[] parentHierarchy = Arrays.copyOf(hierarchy, hierarchy.length-1);
113        return createMediaID(null, parentHierarchy);
114    }
115}
116