1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project
3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License.
6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at
7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software
11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and
14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License.
15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */
16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.data;
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.Context;
20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.res.Resources;
21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
222b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.R;
232b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin
24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.ArrayList;
25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class SizeClustering extends Clustering {
2728cb4161da5fc3756933ca67d509b8af1c6275f1Owen Lin    @SuppressWarnings("unused")
28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "SizeClustering";
29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private Context mContext;
31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private ArrayList<Path>[] mClusters;
32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private String[] mNames;
33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private long mMinSizes[];
34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final long MEGA_BYTES = 1024L*1024;
36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final long GIGA_BYTES = 1024L*1024*1024;
37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final long[] SIZE_LEVELS = {
39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        0,
40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        1 * MEGA_BYTES,
41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        10 * MEGA_BYTES,
42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        100 * MEGA_BYTES,
43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        1 * GIGA_BYTES,
44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        2 * GIGA_BYTES,
45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        4 * GIGA_BYTES,
46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    };
47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public SizeClustering(Context context) {
49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mContext = context;
50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
5228cb4161da5fc3756933ca67d509b8af1c6275f1Owen Lin    @SuppressWarnings("unchecked")
53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void run(MediaSet baseSet) {
5528cb4161da5fc3756933ca67d509b8af1c6275f1Owen Lin        @SuppressWarnings("unchecked")
5628cb4161da5fc3756933ca67d509b8af1c6275f1Owen Lin        final ArrayList<Path>[] group = new ArrayList[SIZE_LEVELS.length];
57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        baseSet.enumerateTotalMediaItems(new MediaSet.ItemConsumer() {
587817979db0c52ffeacb951625b1e821eba303285Ahbong Chang            @Override
59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            public void consume(int index, MediaItem item) {
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                // Find the cluster this item belongs to.
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                long size = item.getSize();
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                int i;
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                for (i = 0; i < SIZE_LEVELS.length - 1; i++) {
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    if (size < SIZE_LEVELS[i + 1]) {
65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        break;
66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    }
67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                ArrayList<Path> list = group[i];
70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                if (list == null) {
71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    list = new ArrayList<Path>();
72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    group[i] = list;
73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                }
74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                list.add(item.getPath());
75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        });
77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int count = 0;
79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        for (int i = 0; i < group.length; i++) {
80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (group[i] != null) {
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                count++;
82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
8528cb4161da5fc3756933ca67d509b8af1c6275f1Owen Lin        mClusters = new ArrayList[count];
86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mNames = new String[count];
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mMinSizes = new long[count];
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Resources res = mContext.getResources();
90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int k = 0;
91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // Go through group in the reverse order, so the group with the largest
92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // size will show first.
93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        for (int i = group.length - 1; i >= 0; i--) {
94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (group[i] == null) continue;
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mClusters[k] = group[i];
97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            if (i == 0) {
98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mNames[k] = String.format(
99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        res.getString(R.string.size_below), getSizeString(i + 1));
100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else if (i == group.length - 1) {
101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mNames[k] = String.format(
102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        res.getString(R.string.size_above), getSizeString(i));
103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            } else {
104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                String minSize = getSizeString(i);
105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                String maxSize = getSizeString(i + 1);
106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                mNames[k] = String.format(
107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                        res.getString(R.string.size_between), minSize, maxSize);
108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mMinSizes[k] = SIZE_LEVELS[i];
110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            k++;
111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private String getSizeString(int index) {
115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        long bytes = SIZE_LEVELS[index];
116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (bytes >= GIGA_BYTES) {
117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return (bytes / GIGA_BYTES) + "GB";
118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else {
119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return (bytes / MEGA_BYTES) + "MB";
120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public int getNumberOfClusters() {
125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return mClusters.length;
126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public ArrayList<Path> getCluster(int index) {
130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return mClusters[index];
131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public String getClusterName(int index) {
135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return mNames[index];
136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public long getMinSize(int index) {
139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return mMinSizes[index];
140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
142