/*
 * Copyright (C) 2008 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.phone;

import android.app.Notification;
import android.content.ContentUris;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.provider.ContactsContract.Contacts;
import android.util.Log;

import com.android.internal.telephony.CallerInfo;
import com.android.internal.telephony.Connection;

import java.io.InputStream;

/**
 * Helper class for loading contacts photo asynchronously.
 */
public class ContactsAsyncHelper {

    private static final boolean DBG = false;
    private static final String LOG_TAG = "ContactsAsyncHelper";

    /**
     * Interface for a WorkerHandler result return.
     */
    public interface OnImageLoadCompleteListener {
        /**
         * Called when the image load is complete.
         *
         * @param token Integer passed in {@link ContactsAsyncHelper#startObtainPhotoAsync(int,
         * Context, Uri, OnImageLoadCompleteListener, Object)}.
         * @param photo Drawable object obtained by the async load.
         * @param photoIcon Bitmap object obtained by the async load.
         * @param cookie Object passed in {@link ContactsAsyncHelper#startObtainPhotoAsync(int,
         * Context, Uri, OnImageLoadCompleteListener, Object)}. Can be null iff. the original
         * cookie is null.
         */
        public void onImageLoadComplete(int token, Drawable photo, Bitmap photoIcon,
                Object cookie);
    }

    // constants
    private static final int EVENT_LOAD_IMAGE = 1;

    private final Handler mResultHandler = new Handler() {
        /** Called when loading is done. */
        @Override
        public void handleMessage(Message msg) {
            WorkerArgs args = (WorkerArgs) msg.obj;
            switch (msg.arg1) {
                case EVENT_LOAD_IMAGE:
                    if (args.listener != null) {
                        if (DBG) {
                            Log.d(LOG_TAG, "Notifying listener: " + args.listener.toString() +
                                    " image: " + args.uri + " completed");
                        }
                        args.listener.onImageLoadComplete(msg.what, args.photo, args.photoIcon,
                                args.cookie);
                    }
                    break;
                default:
            }
        }
    };

    /** Handler run on a worker thread to load photo asynchronously. */
    private static Handler sThreadHandler;

    /** For forcing the system to call its constructor */
    @SuppressWarnings("unused")
    private static ContactsAsyncHelper sInstance;

    static {
        sInstance = new ContactsAsyncHelper();
    }

    private static final class WorkerArgs {
        public Context context;
        public Uri uri;
        public Drawable photo;
        public Bitmap photoIcon;
        public Object cookie;
        public OnImageLoadCompleteListener listener;
    }

    /**
     * public inner class to help out the ContactsAsyncHelper callers
     * with tracking the state of the CallerInfo Queries and image
     * loading.
     *
     * Logic contained herein is used to remove the race conditions
     * that exist as the CallerInfo queries run and mix with the image
     * loads, which then mix with the Phone state changes.
     */
    public static class ImageTracker {

        // Image display states
        public static final int DISPLAY_UNDEFINED = 0;
        public static final int DISPLAY_IMAGE = -1;
        public static final int DISPLAY_DEFAULT = -2;

        // State of the image on the imageview.
        private CallerInfo mCurrentCallerInfo;
        private int displayMode;

        public ImageTracker() {
            mCurrentCallerInfo = null;
            displayMode = DISPLAY_UNDEFINED;
        }

        /**
         * Used to see if the requested call / connection has a
         * different caller attached to it than the one we currently
         * have in the CallCard.
         */
        public boolean isDifferentImageRequest(CallerInfo ci) {
            // note, since the connections are around for the lifetime of the
            // call, and the CallerInfo-related items as well, we can
            // definitely use a simple != comparison.
            return (mCurrentCallerInfo != ci);
        }

        public boolean isDifferentImageRequest(Connection connection) {
            // if the connection does not exist, see if the
            // mCurrentCallerInfo is also null to match.
            if (connection == null) {
                if (DBG) Log.d(LOG_TAG, "isDifferentImageRequest: connection is null");
                return (mCurrentCallerInfo != null);
            }
            Object o = connection.getUserData();

            // if the call does NOT have a callerInfo attached
            // then it is ok to query.
            boolean runQuery = true;
            if (o instanceof CallerInfo) {
                runQuery = isDifferentImageRequest((CallerInfo) o);
            }
            return runQuery;
        }

        /**
         * Simple setter for the CallerInfo object.
         */
        public void setPhotoRequest(CallerInfo ci) {
            mCurrentCallerInfo = ci;
        }

        /**
         * Convenience method used to retrieve the URI
         * representing the Photo file recorded in the attached
         * CallerInfo Object.
         */
        public Uri getPhotoUri() {
            if (mCurrentCallerInfo != null) {
                return ContentUris.withAppendedId(Contacts.CONTENT_URI,
                        mCurrentCallerInfo.person_id);
            }
            return null;
        }

        /**
         * Simple setter for the Photo state.
         */
        public void setPhotoState(int state) {
            displayMode = state;
        }

        /**
         * Simple getter for the Photo state.
         */
        public int getPhotoState() {
            return displayMode;
        }
    }

    /**
     * Thread worker class that handles the task of opening the stream and loading
     * the images.
     */
    private class WorkerHandler extends Handler {
        public WorkerHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            WorkerArgs args = (WorkerArgs) msg.obj;

            switch (msg.arg1) {
                case EVENT_LOAD_IMAGE:
                    InputStream inputStream = null;
                    try {
                        inputStream = Contacts.openContactPhotoInputStream(
                                args.context.getContentResolver(), args.uri, true);
                    } catch (Exception e) {
                        Log.e(LOG_TAG, "Error opening photo input stream", e);
                    }

                    if (inputStream != null) {
                        args.photo = Drawable.createFromStream(inputStream, args.uri.toString());

                        // This assumes Drawable coming from contact database is usually
                        // BitmapDrawable and thus we can have (down)scaled version of it.
                        args.photoIcon = getPhotoIconWhenAppropriate(args.context, args.photo);

                        if (DBG) Log.d(LOG_TAG, "Loading image: " + msg.arg1 +
                                " token: " + msg.what + " image URI: " + args.uri);
                    } else {
                        args.photo = null;
                        args.photoIcon = null;
                        if (DBG) Log.d(LOG_TAG, "Problem with image: " + msg.arg1 +
                                " token: " + msg.what + " image URI: " + args.uri +
                                ", using default image.");
                    }
                    break;
                default:
            }

            // send the reply to the enclosing class.
            Message reply = ContactsAsyncHelper.this.mResultHandler.obtainMessage(msg.what);
            reply.arg1 = msg.arg1;
            reply.obj = msg.obj;
            reply.sendToTarget();
        }

        /**
         * Returns a Bitmap object suitable for {@link Notification}'s large icon. This might
         * return null when the given Drawable isn't BitmapDrawable, or if the system fails to
         * create a scaled Bitmap for the Drawable.
         */
        private Bitmap getPhotoIconWhenAppropriate(Context context, Drawable photo) {
            if (!(photo instanceof BitmapDrawable)) {
                return null;
            }
            int iconSize = context.getResources()
                    .getDimensionPixelSize(R.dimen.notification_icon_size);
            Bitmap orgBitmap = ((BitmapDrawable) photo).getBitmap();
            int orgWidth = orgBitmap.getWidth();
            int orgHeight = orgBitmap.getHeight();
            int longerEdge = orgWidth > orgHeight ? orgWidth : orgHeight;
            // We want downscaled one only when the original icon is too big.
            if (longerEdge > iconSize) {
                float ratio = ((float) longerEdge) / iconSize;
                int newWidth = (int) (orgWidth / ratio);
                int newHeight = (int) (orgHeight / ratio);
                // If the longer edge is much longer than the shorter edge, the latter may
                // become 0 which will cause a crash.
                if (newWidth <= 0 || newHeight <= 0) {
                    Log.w(LOG_TAG, "Photo icon's width or height become 0.");
                    return null;
                }

                // It is sure ratio >= 1.0f in any case and thus the newly created Bitmap
                // should be smaller than the original.
                return Bitmap.createScaledBitmap(orgBitmap, newWidth, newHeight, true);
            } else {
                return orgBitmap;
            }
        }
    }

    /**
     * Private constructor for static class
     */
    private ContactsAsyncHelper() {
        HandlerThread thread = new HandlerThread("ContactsAsyncWorker");
        thread.start();
        sThreadHandler = new WorkerHandler(thread.getLooper());
    }

    /**
     * Starts an asynchronous image load. After finishing the load,
     * {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable, Bitmap, Object)}
     * will be called.
     *
     * @param token Arbitrary integer which will be returned as the first argument of
     * {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable, Bitmap, Object)}
     * @param context Context object used to do the time-consuming operation.
     * @param personUri Uri to be used to fetch the photo
     * @param listener Callback object which will be used when the asynchronous load is done.
     * Can be null, which means only the asynchronous load is done while there's no way to
     * obtain the loaded photos.
     * @param cookie Arbitrary object the caller wants to remember, which will become the
     * fourth argument of {@link OnImageLoadCompleteListener#onImageLoadComplete(int, Drawable,
     * Bitmap, Object)}. Can be null, at which the callback will also has null for the argument.
     */
    public static final void startObtainPhotoAsync(int token, Context context, Uri personUri,
            OnImageLoadCompleteListener listener, Object cookie) {
        // in case the source caller info is null, the URI will be null as well.
        // just update using the placeholder image in this case.
        if (personUri == null) {
            Log.wtf(LOG_TAG, "Uri is missing");
            return;
        }

        // Added additional Cookie field in the callee to handle arguments
        // sent to the callback function.

        // setup arguments
        WorkerArgs args = new WorkerArgs();
        args.cookie = cookie;
        args.context = context;
        args.uri = personUri;
        args.listener = listener;

        // setup message arguments
        Message msg = sThreadHandler.obtainMessage(token);
        msg.arg1 = EVENT_LOAD_IMAGE;
        msg.obj = args;

        if (DBG) Log.d(LOG_TAG, "Begin loading image: " + args.uri +
                ", displaying default image for now.");

        // notify the thread to begin working
        sThreadHandler.sendMessage(msg);
    }


}
