/*
 * Copyright (C) 2013 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.camera.data;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;

import com.android.camera.Storage;
import com.android.camera.ui.FilmStripView;
import com.android.camera.ui.FilmStripView.ImageData;

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

/**
 * A FilmStrip.DataProvider that provide data in the camera folder.
 *
 * The given view for camera preview won't be added until the preview info
 * has been set by setCameraPreviewInfo(int, int).
 */
public class CameraDataAdapter implements FilmStripView.DataAdapter {
    private static final String TAG = CameraDataAdapter.class.getSimpleName();

    private static final int DEFAULT_DECODE_SIZE = 3000;
    private static final String[] CAMERA_PATH = { Storage.DIRECTORY + "%" };

    private List<LocalData> mImages;

    private Listener mListener;
    private View mCameraPreviewView;
    private Drawable mPlaceHolder;

    private int mSuggestedWidth = DEFAULT_DECODE_SIZE;
    private int mSuggestedHeight = DEFAULT_DECODE_SIZE;

    public CameraDataAdapter(Drawable placeHolder) {
        mPlaceHolder = placeHolder;
    }

    public void setCameraPreviewInfo(View cameraPreview, int width, int height) {
        mCameraPreviewView = cameraPreview;
        addOrReplaceCameraData(buildCameraImageData(width, height));
    }

    public void requestLoad(ContentResolver resolver) {
        QueryTask qtask = new QueryTask();
        qtask.execute(resolver);
    }

    @Override
    public int getTotalNumber() {
        if (mImages == null) {
            return 0;
        }
        return mImages.size();
    }

    @Override
    public ImageData getImageData(int id) {
        if (mImages == null || id >= mImages.size() || id < 0) {
            return null;
        }
        return mImages.get(id);
    }

    @Override
    public void suggestDecodeSize(int w, int h) {
        if (w <= 0 || h <= 0) {
            mSuggestedWidth  = mSuggestedHeight = DEFAULT_DECODE_SIZE;
        } else {
            mSuggestedWidth = (w < DEFAULT_DECODE_SIZE ? w : DEFAULT_DECODE_SIZE);
            mSuggestedHeight = (h < DEFAULT_DECODE_SIZE ? h : DEFAULT_DECODE_SIZE);
        }
    }

    @Override
    public View getView(Context c, int dataID) {
        if (mImages == null) {
            return null;
        }
        if (dataID >= mImages.size() || dataID < 0) {
            return null;
        }

        return mImages.get(dataID).getView(
                c, mSuggestedWidth, mSuggestedHeight,
                mPlaceHolder.getConstantState().newDrawable());
    }

    @Override
    public void setListener(Listener listener) {
        mListener = listener;
        if (mImages != null) {
            mListener.onDataLoaded();
        }
    }

    public void removeData(int dataID) {
        if (dataID >= mImages.size()) return;
        LocalData d = mImages.remove(dataID);
        mListener.onDataRemoved(dataID, d);
    }

    private void insertData(LocalData data) {
        if (mImages == null) {
            mImages = new ArrayList<LocalData>();
        }

        // Since this function is mostly for adding the newest data,
        // a simple linear search should yield the best performance over a
        // binary search.
        int pos = 0;
        Comparator<LocalData> comp = new LocalData.NewestFirstComparator();
        for (; pos < mImages.size()
                && comp.compare(data, mImages.get(pos)) > 0; pos++);
        mImages.add(pos, data);
        if (mListener != null) {
            mListener.onDataInserted(pos, data);
        }
    }

    public void addNewVideo(ContentResolver cr, Uri uri) {
        Cursor c = cr.query(uri,
                LocalData.Video.QUERY_PROJECTION,
                MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
                LocalData.Video.QUERY_ORDER);
        if (c != null && c.moveToFirst()) {
            insertData(LocalData.Video.buildFromCursor(c));
        }
    }

    public void addNewPhoto(ContentResolver cr, Uri uri) {
        Cursor c = cr.query(uri,
                LocalData.Photo.QUERY_PROJECTION,
                MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
                LocalData.Photo.QUERY_ORDER);
        if (c != null && c.moveToFirst()) {
            insertData(LocalData.Photo.buildFromCursor(c));
        }
    }

    // Update all the data but keep the camera data if already set.
    private void replaceData(List<LocalData> list) {
        boolean changed = (list != mImages);
        LocalData cameraData = null;
        if (mImages != null && mImages.size() > 0) {
            cameraData = mImages.get(0);
            if (cameraData.getType() != ImageData.TYPE_CAMERA_PREVIEW) {
                cameraData = null;
            }
        }

        mImages = list;
        if (cameraData != null) {
            // camera view exists, so we make sure at least 1 data is in the list.
            if (mImages == null) {
                mImages = new ArrayList<LocalData>();
            }
            mImages.add(0, cameraData);
            if (mListener != null) {
                // Only the camera data is not changed, everything else is changed.
                mListener.onDataUpdated(new UpdateReporter() {
                    @Override
                    public boolean isDataRemoved(int id) {
                        return false;
                    }

                    @Override
                    public boolean isDataUpdated(int id) {
                        if (id == 0) return false;
                        return true;
                    }
                });
            }
        } else {
            // both might be null.
            if (changed) {
                mListener.onDataLoaded();
            }
        }
    }

    public void flush() {
        replaceData(null);
    }

    public void addLocalData(LocalData data) {
        insertData(data);
    }

    private LocalData buildCameraImageData(int width, int height) {
        LocalData d = new CameraPreviewData(width, height);
        return d;
    }

    private void addOrReplaceCameraData(LocalData data) {
        if (mImages == null) {
            mImages = new ArrayList<LocalData>();
        }
        if (mImages.size() == 0) {
            // No data at all.
            mImages.add(0, data);
            if (mListener != null) {
                mListener.onDataLoaded();
            }
            return;
        }

        LocalData first = mImages.get(0);
        if (first.getType() == ImageData.TYPE_CAMERA_PREVIEW) {
            // Replace the old camera data.
            mImages.set(0, data);
            if (mListener != null) {
                mListener.onDataUpdated(new UpdateReporter() {
                    @Override
                    public boolean isDataRemoved(int id) {
                        return false;
                    }

                    @Override
                    public boolean isDataUpdated(int id) {
                        if (id == 0) {
                            return true;
                        }
                        return false;
                    }
                });
            }
        } else {
            // Add a new camera data.
            mImages.add(0, data);
            if (mListener != null) {
                mListener.onDataLoaded();
            }
        }
    }

    private class QueryTask extends AsyncTask<ContentResolver, Void, List<LocalData>> {
        @Override
        protected List<LocalData> doInBackground(ContentResolver... resolver) {
            List<LocalData> l = new ArrayList<LocalData>();
            // Photos
            Cursor c = resolver[0].query(
                    LocalData.Photo.CONTENT_URI,
                    LocalData.Photo.QUERY_PROJECTION,
                    MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
                    LocalData.Photo.QUERY_ORDER);
            if (c != null && c.moveToFirst()) {
                // build up the list.
                while (true) {
                    LocalData data = LocalData.Photo.buildFromCursor(c);
                    if (data != null) {
                        l.add(data);
                    } else {
                        Log.e(TAG, "Error loading data:"
                                + c.getString(LocalData.Photo.COL_DATA));
                    }
                    if (c.isLast()) {
                        break;
                    }
                    c.moveToNext();
                }
            }
            if (c != null) {
                c.close();
            }

            c = resolver[0].query(
                    LocalData.Video.CONTENT_URI,
                    LocalData.Video.QUERY_PROJECTION,
                    MediaStore.Video.Media.DATA + " like ? ", CAMERA_PATH,
                    LocalData.Video.QUERY_ORDER);
            if (c != null && c.moveToFirst()) {
                // build up the list.
                c.moveToFirst();
                while (true) {
                    LocalData data = LocalData.Video.buildFromCursor(c);
                    if (data != null) {
                        l.add(data);
                        Log.v(TAG, "video data added:" + data);
                    } else {
                        Log.e(TAG, "Error loading data:"
                                + c.getString(LocalData.Video.COL_DATA));
                    }
                    if (!c.isLast()) {
                        c.moveToNext();
                    } else {
                        break;
                    }
                }
            }
            if (c != null) {
                c.close();
            }

            if (l.size() == 0) return null;

            Collections.sort(l, new LocalData.NewestFirstComparator());
            return l;
        }

        @Override
        protected void onPostExecute(List<LocalData> l) {
            replaceData(l);
        }
    }

    private class CameraPreviewData implements LocalData {
        private int width;
        private int height;

        CameraPreviewData(int w, int h) {
            width = w;
            height = h;
        }

        @Override
        public long getDateTaken() {
            // This value is used for sorting.
            return -1;
        }

        @Override
        public long getDateModified() {
            // This value might be used for sorting.
            return -1;
        }

        @Override
        public String getTitle() {
            return "";
        }

        @Override
        public int getWidth() {
            return width;
        }

        @Override
        public int getHeight() {
            return height;
        }

        @Override
        public int getType() {
            return ImageData.TYPE_CAMERA_PREVIEW;
        }

        @Override
        public boolean isActionSupported(int action) {
            return false;
        }

        @Override
        public View getView(Context c, int width, int height, Drawable placeHolder) {
            return mCameraPreviewView;
        }

        @Override
        public void prepare() {
            // do nothing.
        }

        @Override
        public void recycle() {
            // do nothing.
        }
    }
}
