/*
 * 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.content.ContentProviderClient;
import android.content.ContentUris;
import android.content.UriMatcher;
import android.net.Uri;
import android.provider.MediaStore;

import com.android.gallery3d.app.Gallery;
import com.android.gallery3d.app.GalleryApp;
import com.android.gallery3d.data.MediaSet.ItemConsumer;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

class LocalSource extends MediaSource {

    public static final String KEY_BUCKET_ID = "bucketId";

    private GalleryApp mApplication;
    private PathMatcher mMatcher;
    private static final int NO_MATCH = -1;
    private final UriMatcher mUriMatcher = new UriMatcher(NO_MATCH);
    public static final Comparator<PathId> sIdComparator = new IdComparator();

    private static final int LOCAL_IMAGE_ALBUMSET = 0;
    private static final int LOCAL_VIDEO_ALBUMSET = 1;
    private static final int LOCAL_IMAGE_ALBUM = 2;
    private static final int LOCAL_VIDEO_ALBUM = 3;
    private static final int LOCAL_IMAGE_ITEM = 4;
    private static final int LOCAL_VIDEO_ITEM = 5;
    private static final int LOCAL_ALL_ALBUMSET = 6;
    private static final int LOCAL_ALL_ALBUM = 7;

    private static final String TAG = "LocalSource";

    private ContentProviderClient mClient;

    public LocalSource(GalleryApp context) {
        super("local");
        mApplication = context;
        mMatcher = new PathMatcher();
        mMatcher.add("/local/image", LOCAL_IMAGE_ALBUMSET);
        mMatcher.add("/local/video", LOCAL_VIDEO_ALBUMSET);
        mMatcher.add("/local/all", LOCAL_ALL_ALBUMSET);

        mMatcher.add("/local/image/*", LOCAL_IMAGE_ALBUM);
        mMatcher.add("/local/video/*", LOCAL_VIDEO_ALBUM);
        mMatcher.add("/local/all/*", LOCAL_ALL_ALBUM);
        mMatcher.add("/local/image/item/*", LOCAL_IMAGE_ITEM);
        mMatcher.add("/local/video/item/*", LOCAL_VIDEO_ITEM);

        mUriMatcher.addURI(MediaStore.AUTHORITY,
                "external/images/media/#", LOCAL_IMAGE_ITEM);
        mUriMatcher.addURI(MediaStore.AUTHORITY,
                "external/video/media/#", LOCAL_VIDEO_ITEM);
        mUriMatcher.addURI(MediaStore.AUTHORITY,
                "external/images/media", LOCAL_IMAGE_ALBUM);
        mUriMatcher.addURI(MediaStore.AUTHORITY,
                "external/video/media", LOCAL_VIDEO_ALBUM);
        mUriMatcher.addURI(MediaStore.AUTHORITY,
                "external/file", LOCAL_ALL_ALBUM);
    }

    @Override
    public MediaObject createMediaObject(Path path) {
        GalleryApp app = mApplication;
        switch (mMatcher.match(path)) {
            case LOCAL_ALL_ALBUMSET:
            case LOCAL_IMAGE_ALBUMSET:
            case LOCAL_VIDEO_ALBUMSET:
                return new LocalAlbumSet(path, mApplication);
            case LOCAL_IMAGE_ALBUM:
                return new LocalAlbum(path, app, mMatcher.getIntVar(0), true);
            case LOCAL_VIDEO_ALBUM:
                return new LocalAlbum(path, app, mMatcher.getIntVar(0), false);
            case LOCAL_ALL_ALBUM: {
                int bucketId = mMatcher.getIntVar(0);
                DataManager dataManager = app.getDataManager();
                MediaSet imageSet = (MediaSet) dataManager.getMediaObject(
                        LocalAlbumSet.PATH_IMAGE.getChild(bucketId));
                MediaSet videoSet = (MediaSet) dataManager.getMediaObject(
                        LocalAlbumSet.PATH_VIDEO.getChild(bucketId));
                Comparator<MediaItem> comp = DataManager.sDateTakenComparator;
                return new LocalMergeAlbum(
                        path, comp, new MediaSet[] {imageSet, videoSet}, bucketId);
            }
            case LOCAL_IMAGE_ITEM:
                return new LocalImage(path, mApplication, mMatcher.getIntVar(0));
            case LOCAL_VIDEO_ITEM:
                return new LocalVideo(path, mApplication, mMatcher.getIntVar(0));
            default:
                throw new RuntimeException("bad path: " + path);
        }
    }

    private static int getMediaType(String type, int defaultType) {
        if (type == null) return defaultType;
        try {
            int value = Integer.parseInt(type);
            if ((value & (MEDIA_TYPE_IMAGE
                    | MEDIA_TYPE_VIDEO)) != 0) return value;
        } catch (NumberFormatException e) {
            Log.w(TAG, "invalid type: " + type, e);
        }
        return defaultType;
    }

    // The media type bit passed by the intent
    private static final int MEDIA_TYPE_ALL = 0;
    private static final int MEDIA_TYPE_IMAGE = 1;
    private static final int MEDIA_TYPE_VIDEO = 4;

    private Path getAlbumPath(Uri uri, int defaultType) {
        int mediaType = getMediaType(
                uri.getQueryParameter(Gallery.KEY_MEDIA_TYPES),
                defaultType);
        String bucketId = uri.getQueryParameter(KEY_BUCKET_ID);
        int id = 0;
        try {
            id = Integer.parseInt(bucketId);
        } catch (NumberFormatException e) {
            Log.w(TAG, "invalid bucket id: " + bucketId, e);
            return null;
        }
        switch (mediaType) {
            case MEDIA_TYPE_IMAGE:
                return Path.fromString("/local/image").getChild(id);
            case MEDIA_TYPE_VIDEO:
                return Path.fromString("/local/video").getChild(id);
            default:
                return Path.fromString("/local/all").getChild(id);
        }
    }

    @Override
    public Path findPathByUri(Uri uri, String type) {
        try {
            switch (mUriMatcher.match(uri)) {
                case LOCAL_IMAGE_ITEM: {
                    long id = ContentUris.parseId(uri);
                    return id >= 0 ? LocalImage.ITEM_PATH.getChild(id) : null;
                }
                case LOCAL_VIDEO_ITEM: {
                    long id = ContentUris.parseId(uri);
                    return id >= 0 ? LocalVideo.ITEM_PATH.getChild(id) : null;
                }
                case LOCAL_IMAGE_ALBUM: {
                    return getAlbumPath(uri, MEDIA_TYPE_IMAGE);
                }
                case LOCAL_VIDEO_ALBUM: {
                    return getAlbumPath(uri, MEDIA_TYPE_VIDEO);
                }
                case LOCAL_ALL_ALBUM: {
                    return getAlbumPath(uri, MEDIA_TYPE_ALL);
                }
            }
        } catch (NumberFormatException e) {
            Log.w(TAG, "uri: " + uri.toString(), e);
        }
        return null;
    }

    @Override
    public Path getDefaultSetOf(Path item) {
        MediaObject object = mApplication.getDataManager().getMediaObject(item);
        if (object instanceof LocalMediaItem) {
            return Path.fromString("/local/all").getChild(
                    String.valueOf(((LocalMediaItem) object).getBucketId()));
        }
        return null;
    }

    @Override
    public void mapMediaItems(ArrayList<PathId> list, ItemConsumer consumer) {
        ArrayList<PathId> imageList = new ArrayList<PathId>();
        ArrayList<PathId> videoList = new ArrayList<PathId>();
        int n = list.size();
        for (int i = 0; i < n; i++) {
            PathId pid = list.get(i);
            // We assume the form is: "/local/{image,video}/item/#"
            // We don't use mMatcher for efficiency's reason.
            Path parent = pid.path.getParent();
            if (parent == LocalImage.ITEM_PATH) {
                imageList.add(pid);
            } else if (parent == LocalVideo.ITEM_PATH) {
                videoList.add(pid);
            }
        }
        // TODO: use "files" table so we can merge the two cases.
        processMapMediaItems(imageList, consumer, true);
        processMapMediaItems(videoList, consumer, false);
    }

    private void processMapMediaItems(ArrayList<PathId> list,
            ItemConsumer consumer, boolean isImage) {
        // Sort path by path id
        Collections.sort(list, sIdComparator);
        int n = list.size();
        for (int i = 0; i < n; ) {
            PathId pid = list.get(i);

            // Find a range of items.
            ArrayList<Integer> ids = new ArrayList<Integer>();
            int startId = Integer.parseInt(pid.path.getSuffix());
            ids.add(startId);

            int j;
            for (j = i + 1; j < n; j++) {
                PathId pid2 = list.get(j);
                int curId = Integer.parseInt(pid2.path.getSuffix());
                if (curId - startId >= MediaSet.MEDIAITEM_BATCH_FETCH_COUNT) {
                    break;
                }
                ids.add(curId);
            }

            MediaItem[] items = LocalAlbum.getMediaItemById(
                    mApplication, isImage, ids);
            for(int k = i ; k < j; k++) {
                PathId pid2 = list.get(k);
                consumer.consume(pid2.id, items[k - i]);
            }

            i = j;
        }
    }

    // This is a comparator which compares the suffix number in two Paths.
    private static class IdComparator implements Comparator<PathId> {
        @Override
        public int compare(PathId p1, PathId p2) {
            String s1 = p1.path.getSuffix();
            String s2 = p2.path.getSuffix();
            int len1 = s1.length();
            int len2 = s2.length();
            if (len1 < len2) {
                return -1;
            } else if (len1 > len2) {
                return 1;
            } else {
                return s1.compareTo(s2);
            }
        }
    }

    @Override
    public void resume() {
        mClient = mApplication.getContentResolver()
                .acquireContentProviderClient(MediaStore.AUTHORITY);
    }

    @Override
    public void pause() {
        mClient.release();
        mClient = null;
    }
}
