/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.gallery3d.data;

import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Video;
import android.provider.MediaStore.Images.ImageColumns;
import android.provider.MediaStore.Video.VideoColumns;

import com.android.gallery3d.app.GalleryContext;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class LocalAlbumSet extends DatabaseMediaSet {
    private static final String TAG = "LocalAlbumSet";

    private static final int BUCKET_ID_INDEX = 0;
    private static final int BUCKET_NAME_INDEX = 1;

    private static final String[] PROJECTION_IMAGE_BUCKETS = {
            ImageColumns.BUCKET_ID,
            ImageColumns.BUCKET_DISPLAY_NAME };

    private static final String[] PROJECTION_VIDEO_BUCKETS = {
            VideoColumns.BUCKET_ID,
            VideoColumns.BUCKET_DISPLAY_NAME };

    private final String[] mProjection;
    private final Uri mBaseUri;

    private boolean mIsImage;
    private long mUniqueId;
    private final ArrayList<LocalAlbum> mAlbums = new ArrayList<LocalAlbum>();
    private HashMap<Integer, String> mLoadBuffer;

    public LocalAlbumSet(GalleryContext context, boolean isImage) {
        super(context);
        mIsImage = isImage;
        if (isImage) {
            mProjection = PROJECTION_IMAGE_BUCKETS;
            mBaseUri = Images.Media.EXTERNAL_CONTENT_URI;
            mUniqueId = DataManager.makeId(DataManager.ID_LOCAL_IMAGE_ALBUM_SET, 0);
        } else {
            mProjection = PROJECTION_VIDEO_BUCKETS;
            mBaseUri = Video.Media.EXTERNAL_CONTENT_URI;
            mUniqueId = DataManager.makeId(DataManager.ID_LOCAL_VIDEO_ALBUM_SET, 0);
        }
    }

    public long getId() {
        return mUniqueId;
    }

    public synchronized MediaSet getSubMediaSet(int index) {
        return mAlbums.get(index);
    }

    public synchronized int getSubMediaSetCount() {
        return mAlbums.size();
    }

    public String getName() {
        return TAG;
    }

    public int getTotalMediaItemCount() {
        int total = 0;
        for (MediaSet album : mAlbums) {
            total += album.getTotalMediaItemCount();
        }
        return total;
    }

    @Override
    protected void onLoadFromDatabase() {
        HashMap<Integer, String> map = new HashMap<Integer, String>();
        mLoadBuffer = map;

        Uri uri = mBaseUri.buildUpon().
                appendQueryParameter("distinct", "true").build();
        Cursor cursor = mResolver.query(
                uri, mProjection, null, null, null);
        if (cursor == null) throw new NullPointerException();
        try {
            while (cursor.moveToNext()) {
                map.put(cursor.getInt(BUCKET_ID_INDEX),
                        cursor.getString(BUCKET_NAME_INDEX));
            }
        } finally {
            cursor.close();
        }
    }

    @Override
    protected void onUpdateContent() {
        HashMap<Integer, String> map = mLoadBuffer;
        if (map == null) throw new IllegalStateException();

        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            mAlbums.add(new LocalAlbum(
                    mContext, entry.getKey(), entry.getValue(), mIsImage));
        }
        mLoadBuffer = null;

        Collections.sort(mAlbums, LocalAlbum.sBucketNameComparator);
    }
}
