/*
 * Copyright (C) 2011 Google Inc.
 * Licensed to 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.ex.photo.loaders;

import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import android.support.v4.content.AsyncTaskLoader;
import android.util.DisplayMetrics;

import com.android.ex.photo.fragments.PhotoViewFragment;
import com.android.ex.photo.loaders.PhotoBitmapLoader.BitmapResult;
import com.android.ex.photo.util.ImageUtils;

/**
 * Loader for the bitmap of a photo.
 */
public class PhotoBitmapLoader extends AsyncTaskLoader<BitmapResult> {
    private String mPhotoUri;
    private Bitmap mBitmap;

    public PhotoBitmapLoader(Context context, String photoUri) {
        super(context);
        mPhotoUri = photoUri;
    }

    public void setPhotoUri(String photoUri) {
        mPhotoUri = photoUri;
    }

    @Override
    public BitmapResult loadInBackground() {
        BitmapResult result = new BitmapResult();
        Context context = getContext();
        if (context != null && mPhotoUri != null) {
            final ContentResolver resolver = context.getContentResolver();
            try {
                Bitmap bitmap = ImageUtils.createLocalBitmap(resolver, Uri.parse(mPhotoUri),
                        PhotoViewFragment.sPhotoSize);
                if (bitmap != null) {
                    bitmap.setDensity(DisplayMetrics.DENSITY_MEDIUM);
                }
                result.status = BitmapResult.STATUS_SUCCESS;
                result.bitmap = bitmap;
            } catch (UnsupportedOperationException ex) {
                // We got image bytes, but unable to decode to a Bitmap
                result.status = BitmapResult.STATUS_EXCEPTION;
            }
        }

        return result;
    }

    /**
     * Called when there is new data to deliver to the client.  The
     * super class will take care of delivering it; the implementation
     * here just adds a little more logic.
     */
    @Override
    public void deliverResult(BitmapResult result) {
        Bitmap bitmap = result != null ? result.bitmap : null;
        if (isReset()) {
            // An async query came in while the loader is stopped.  We
            // don't need the result.
            if (bitmap != null) {
                onReleaseResources(bitmap);
            }
        }
        Bitmap oldBitmap = mBitmap;
        mBitmap = bitmap;

        if (isStarted()) {
            // If the Loader is currently started, we can immediately
            // deliver its results.
            super.deliverResult(result);
        }

        // At this point we can release the resources associated with
        // 'oldBitmap' if needed; now that the new result is delivered we
        // know that it is no longer in use.
        if (oldBitmap != null && oldBitmap != bitmap && !oldBitmap.isRecycled()) {
            onReleaseResources(oldBitmap);
        }
    }

    /**
     * Handles a request to start the Loader.
     */
    @Override
    protected void onStartLoading() {
        if (mBitmap != null) {
            // If we currently have a result available, deliver it
            // immediately.
            BitmapResult result = new BitmapResult();
            result.status = BitmapResult.STATUS_SUCCESS;
            result.bitmap = mBitmap;
            deliverResult(result);
        }

        if (takeContentChanged() || mBitmap == null) {
            // If the data has changed since the last time it was loaded
            // or is not currently available, start a load.
            forceLoad();
        }
    }

    /**
     * Handles a request to stop the Loader.
     */
    @Override protected void onStopLoading() {
        // Attempt to cancel the current load task if possible.
        cancelLoad();
    }

    /**
     * Handles a request to cancel a load.
     */
    @Override
    public void onCanceled(BitmapResult result) {
        super.onCanceled(result);

        // At this point we can release the resources associated with 'bitmap'
        // if needed.
        if (result != null) {
            onReleaseResources(result.bitmap);
        }
    }

    /**
     * Handles a request to completely reset the Loader.
     */
    @Override
    protected void onReset() {
        super.onReset();

        // Ensure the loader is stopped
        onStopLoading();

        // At this point we can release the resources associated with 'bitmap'
        // if needed.
        if (mBitmap != null) {
            onReleaseResources(mBitmap);
            mBitmap = null;
        }
    }

    /**
     * Helper function to take care of releasing resources associated
     * with an actively loaded data set.
     */
    protected void onReleaseResources(Bitmap bitmap) {
        if (bitmap != null && !bitmap.isRecycled()) {
            bitmap.recycle();
        }
    }

    public class BitmapResult {
        public static final int STATUS_SUCCESS = 0;
        public static final int STATUS_EXCEPTION = 1;

        public Bitmap bitmap;
        public int status;
    }
}
