/*
 * 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.mail.photo.fragments;

import android.app.Activity;
import android.app.DownloadManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.android.mail.R;
import com.android.mail.photo.BaseFragmentActivity;
import com.android.mail.photo.Intents;
import com.android.mail.photo.MultiChoiceActionModeStub;
import com.android.mail.photo.PhotoViewActivity.OnMenuItemListener;
import com.android.mail.photo.PhotoViewActivity.OnScreenListener;
import com.android.mail.photo.loaders.PhotoBitmapLoader;
import com.android.mail.photo.util.ImageUtils;
import com.android.mail.photo.views.PhotoView;

import java.io.File;

/**
 * Displays photo, comments and tags for a picasa photo id.
 */
public class PhotoViewFragment extends BaseFragment implements
        LoaderCallbacks<Bitmap>, OnClickListener, OnScreenListener, OnMenuItemListener {

    /**
     * Interface that activities must implement in order to use this fragment.
     */
    public static interface PhotoViewCallbacks {
        /**
         * Returns true of the given fragment is the currently active fragment.
         */
        public boolean isFragmentActive(Fragment fragment);

        /**
         * Called when the given fragment becomes visible.
         */
        public void onFragmentVisible(Fragment fragment);

        /**
         * Toggles full screen mode.
         */
        public void toggleFullScreen();

        /**
         * Returns {@code true} if full screen mode is enabled for the given fragment.
         * Otherwise, {@code false}.
         */
        public boolean isFragmentFullScreen(Fragment fragment);

        /**
         * Returns {@code true} if only the photo should be displayed. All ancillary
         * information [eg album name, photo owner, comment counts, etc...] will be hidden.
         */
        public boolean isShowPhotoOnly();

        /**
         * Adds a full screen listener.
         */
        public void addScreenListener(OnScreenListener listener);

        /**
         * Removes a full screen listener.
         */
        public void removeScreenListener(OnScreenListener listener);

        /**
         * Adds a title bar listener.
         */
        public void addMenuItemListener(OnMenuItemListener listener);

        /**
         * Removes a title bar listener.
         */
        public void removeMenuItemListener(OnMenuItemListener listener);

        /**
         * A photo has been deleted.
         */
        public void onPhotoRemoved(long photoId);

        /**
         * Get the action bar height.
         */
        public int getActionBarHeight();

        /**
         * Updates the title bar menu.
         */
        public void updateMenuItems();
    }

    /**
     * Interface for components that are internally scrollable left-to-right.
     */
    public static interface HorizontallyScrollable {
        /**
         * Return {@code true} if the component needs to receive right-to-left
         * touch movements.
         *
         * @param origX the raw x coordinate of the initial touch
         * @param origY the raw y coordinate of the initial touch
         */

        public boolean interceptMoveLeft(float origX, float origY);

        /**
         * Return {@code true} if the component needs to receive left-to-right
         * touch movements.
         *
         * @param origX the raw x coordinate of the initial touch
         * @param origY the raw y coordinate of the initial touch
         */
        public boolean interceptMoveRight(float origX, float origY);
    }

    private final static String STATE_INTENT_KEY =
            "com.android.mail.photo.fragments.PhotoViewFragment.INTENT";
    private final static String STATE_FRAGMENT_ID_KEY =
            "com.android.mail.photo.fragments.PhotoViewFragment.FRAGMENT_ID";
    private final static String STATE_FORCE_LOAD_KEY =
            "com.android.mail.photo.fragments.PhotoViewFragment.FORCE_LOAD";
    private final static String STATE_DOWNLOADABLE_KEY =
            "com.android.mail.photo.fragments.PhotoViewFragment.DOWNLOADABLE";

    private final static String TAG = "PhotoViewFragment";

    /** An invalid ID */
    private final static long INVALID_ID = 0L;

    // Loader IDs
    private final static int LOADER_ID_PHOTO = R.id.photo_view_photo_loader_id;

    /** The size of the photo */
    public static Integer sPhotoSize;

    /** The ID of this photo */
    private long mPhotoId;
    /** The gaia ID of the photo owner */
    private String mOwnerId;
    /** The URL of a photo to display */
    private String mPhotoUrl;
    /** Name of the photo */
    private String mDisplayName;
    /** Album name used if the photo doesn't have one. See b/5678229. */
    private String mDefaultAlbumName;
    /** Whether or not this photo can be downloaded */
    private Boolean mDownloadable;
    /** The intent we were launched with */
    private Intent mIntent;
    private PhotoViewCallbacks mCallback;
    private ProgressBar mProgressBarView;
    /** If {@code true}, we will load photo data from the network instead of the database */
    private Long mForceLoadId;
    /** The ID of this fragment. {@code -1} is a special value meaning no ID. */
    private int mFragmentId = -1;
    private MultiChoiceActionModeStub mActionMode;
    /** Whether or not the photo is a place holder */
    private boolean mIsPlaceHolder = true;

    private PhotoView mPhotoView;

    /** The height of the action bar; may be {@code 0} if there is no action bar available */
    private int mActionBarHeight;
    /** When {@code true}, don't use a spacer */
    private boolean mDisableSpacer = Build.VERSION.SDK_INT < 11;
    /** Whether or not the fragment should make the photo full-screen */
    private boolean mFullScreen;

    public PhotoViewFragment() {
    }

    public PhotoViewFragment(Intent intent, int fragmentId) {
        this();
        mIntent = intent;
        mFragmentId = fragmentId;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (activity instanceof PhotoViewCallbacks) {
            mCallback = (PhotoViewCallbacks) activity;
        } else {
            throw new IllegalArgumentException("Activity must implement PhotoViewCallbacks");
        }

        if (sPhotoSize == null) {
            final DisplayMetrics metrics = new DisplayMetrics();
            final WindowManager wm =
                    (WindowManager) getActivity().getSystemService(Context.WINDOW_SERVICE);
            final ImageUtils.ImageSize imageSize = ImageUtils.sUseImageSize;
            wm.getDefaultDisplay().getMetrics(metrics);
            switch (imageSize) {
                case EXTRA_SMALL: {
                    // Use a photo that's 80% of the "small" size
                    sPhotoSize = (Math.min(metrics.heightPixels, metrics.widthPixels) * 800) / 1000;
                    break;
                }

                case SMALL:
                case NORMAL:
                default: {
                    sPhotoSize = Math.min(metrics.heightPixels, metrics.widthPixels);
                    break;
                }
            }
        }
    }

    @Override
    public void onDetach() {
        mCallback = null;
        super.onDetach();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState != null) {
            mIntent = new Intent().putExtras(savedInstanceState.getBundle(STATE_INTENT_KEY));
            mFragmentId = savedInstanceState.getInt(STATE_FRAGMENT_ID_KEY);
            if (savedInstanceState.containsKey(STATE_FORCE_LOAD_KEY)) {
                mForceLoadId = savedInstanceState.getLong(STATE_FORCE_LOAD_KEY);
            }
            if (savedInstanceState.containsKey(STATE_DOWNLOADABLE_KEY)) {
                mDownloadable = savedInstanceState.getBoolean(STATE_DOWNLOADABLE_KEY);
            }
        } else {
            if (mIntent.hasExtra(Intents.EXTRA_REFRESH)) {
                mForceLoadId = mIntent.getLongExtra(Intents.EXTRA_REFRESH, 0L);
            }
        }

        mPhotoId = mIntent.getLongExtra(Intents.EXTRA_PHOTO_ID, INVALID_ID);
        mOwnerId = mIntent.getStringExtra(Intents.EXTRA_OWNER_ID);
        mPhotoUrl = mIntent.getStringExtra(Intents.EXTRA_PHOTO_URL);
        mDefaultAlbumName = mIntent.getStringExtra(Intents.EXTRA_ALBUM_NAME);

        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        final View view = super.onCreateView(inflater, container, savedInstanceState,
                R.layout.photo_fragment_view);

        mPhotoView = (PhotoView) view.findViewById(R.id.photo_view);

        mIsPlaceHolder = true;
        mPhotoView.setPhotoLoading(true);

        mPhotoView.setOnClickListener(this);
        mPhotoView.setFullScreen(mFullScreen, false);
//        mPhotoView.setVideoBlob(videoData);

        // Don't call until we've setup the entire view
        setViewVisibility();

        return view;
    }

    @Override
    public void onResume() {
        mCallback.addScreenListener(this);
        mCallback.addMenuItemListener(this);

        // the forceLoad call feels like a hack
        getLoaderManager().initLoader(LOADER_ID_PHOTO, null, this);

        super.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        // Remove listeners
        mCallback.removeScreenListener(this);
        mCallback.removeMenuItemListener(this);
        resetPhotoView();
    }

    @Override
    public void onDestroyView() {
        // Clean up views and other components
        mProgressBarView = null;
        mIsPlaceHolder = true;

        if (mPhotoView != null) {
            mPhotoView.clear();
            mPhotoView = null;
        }

        super.onDestroyView();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        if (mIntent != null) {
            outState.putParcelable(STATE_INTENT_KEY, mIntent.getExtras());
            outState.putInt(STATE_FRAGMENT_ID_KEY, mFragmentId);
            if (mForceLoadId != null) {
                outState.putLong(STATE_FORCE_LOAD_KEY, mForceLoadId);
            }
            if (mDownloadable != null) {
                outState.putBoolean(STATE_DOWNLOADABLE_KEY, mDownloadable);
            }
        }
    }

    @Override
    public Loader<Bitmap> onCreateLoader(int id, Bundle args) {
        if (id == LOADER_ID_PHOTO) {
            return new PhotoBitmapLoader(getActivity(), mPhotoUrl);
        } else {
            return null;
        }
    }

    @Override
    public void onLoadFinished(Loader<Bitmap> loader, Bitmap data) {
        // If we don't have a view, the fragment has been paused. We'll get the cursor again later.
        if (getView() == null) {
            return;
        }

        final int id = loader.getId();
        if (id == LOADER_ID_PHOTO) {
            if (data == null) {
                Toast.makeText(getActivity(), R.string.photo_view_load_error, Toast.LENGTH_SHORT)
                        .show();
                return;
            }
            final View view = getView();
            if (view != null) {
                bindPhoto(data);
                updateView(view);
            }
            mForceLoadId = null;
            //mAdapter.swapCursor(data);
            mIsPlaceHolder = false;
            if (Build.VERSION.SDK_INT >= 11 && mActionMode != null) {
                // Invalidate the action mode menu
                mActionMode.invalidate();
            }
            updateMenuItems();
            setViewVisibility();
        }
    }

    /**
     * Binds an image to the photo view.
     */
    private void bindPhoto(Bitmap bitmap) {
        if (mPhotoView != null) {
            mPhotoView.setPhotoLoading(false);
            mPhotoView.bindPhoto(bitmap);
        }
    }

    /**
     * Resets the photo view to it's default state w/ no bound photo.
     */
    private void resetPhotoView() {
        if (mPhotoView != null) {
            mPhotoView.setPhotoLoading(true);
            mPhotoView.bindPhoto(null);
        }
    }

    @Override
    public void onLoaderReset(Loader<Bitmap> loader) {
        // Do nothing
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            default: {
                if (!isPhotoBound()) {
                    // If there is no photo, don't allow any actions except to exit
                    // full-screen mode. We want to let the user view comments, etc...
                    if (mCallback.isFragmentFullScreen(this)) {
                        mCallback.toggleFullScreen();
                    }
                    break;
                }

                // TODO: enable video
                if (isVideo() && mCallback.isFragmentFullScreen(this)) {
                    if (isVideoReady()) {
//                        final Intent startIntent = Intents.getVideoViewActivityIntent(getActivity(),
//                                mAccount, mOwnerId, mPhotoId, mAdapter.getVideoData());
//                        startActivity(startIntent);
                    } else {
                        final String toastText = getString(R.string.photo_view_video_not_ready);
                        Toast.makeText(getActivity(), toastText, Toast.LENGTH_LONG).show();
                    }
                } else {
                    mCallback.toggleFullScreen();
                }
                break;
            }
        }
    }

    @Override
    public void onFullScreenChanged(boolean fullScreen, boolean animate) {
        setViewVisibility();
    }

    @Override
    public void onViewActivated() {
        if (!mCallback.isFragmentActive(this)) {
            // we're not in the foreground; reset our view
            resetViews();
        } else {
            mCallback.onFragmentVisible(this);
            // The action bar will already be updated for HC and later and updating them
            // here will corrupt the display.
            if (Build.VERSION.SDK_INT < 11) {
                updateMenuItems();
            }
        }
    }

    /**
     * Reset the views to their default states
     */
    public void resetViews() {
        if (mPhotoView != null) {
            mPhotoView.resetTransformations();
        }
    }

    @Override
    public boolean onInterceptMoveLeft(float origX, float origY) {
        if (!mCallback.isFragmentActive(this)) {
            // we're not in the foreground; don't intercept any touches
            return false;
        }

        return (mPhotoView != null && mPhotoView.interceptMoveLeft(origX, origY));
    }

    @Override
    public boolean onInterceptMoveRight(float origX, float origY) {
        if (!mCallback.isFragmentActive(this)) {
            // we're not in the foreground; don't intercept any touches
            return false;
        }

        return (mPhotoView != null && mPhotoView.interceptMoveRight(origX, origY));
    }

    @Override
    public void onActionBarHeightCalculated(int actionBarHeight) {
    }

    @Override
    protected boolean isEmpty() {
        final View view = getView();
        final boolean isViewAvailable =
                (view != null && (view.findViewById(android.R.id.empty) != null));

        return isViewAvailable && !isPhotoBound();
    }

    /**
     * Returns {@code true} if a photo has been bound. Otherwise, returns {@code false}.
     */
    public boolean isPhotoBound() {
        return (mPhotoView != null && mPhotoView.isPhotoBound());
    }

    /**
     * Returns {@code true} if a photo is loading. Otherwise, returns {@code false}.
     */
    public boolean isPhotoLoading() {
        return (mPhotoView != null && mPhotoView.isPhotoLoading());
    }

    /**
     * Returns {@code true} if the photo represents a video. Otherwise, returns {@code false}.
     */
    public boolean isVideo() {
        return (mPhotoView != null && mPhotoView.isVideo());
    }

    /**
     * Returns {@code true} if the video is ready to play. Otherwise, returns {@code false}.
     */
    public boolean isVideoReady() {
        return (mPhotoView != null && mPhotoView.isVideoReady());
    }

    /**
     * Returns video data for the photo. Otherwise, {@code null} if the photo is not a video.
     */
    public byte[] getVideoData() {
        return (mPhotoView == null ? null : mPhotoView.getVideoData());
    }

    /**
     * Returns {@code true} if the user is allowed to download the photo.
     * Otherwise, {@code false}.
     */
    private boolean canDownload() {
        return mDownloadable != null && mDownloadable;
    }

    /**
     * Sets the progress bar.
     */
    @Override
    public void onUpdateProgressView(ProgressBar progressBarView) {
        mProgressBarView = progressBarView;
        updateSpinner(mProgressBarView);

        final View myView = getView();
        if (myView != null) {
            updateView(myView);
        }
    }

    @Override
    public boolean onPrepareTitlebarButtons(Menu menu) {
        if (!mCallback.isFragmentActive(this)) {
            return false;
        }

//        final Uri photoUri = (mPhotoUrl != null) ? Uri.parse(mPhotoUrl) : null;
//        final boolean isRemotePhoto =
//                (mPhotoId != INVALID_ID) && !MediaStoreUtils.isMediaStoreUri(photoUri);
//        final boolean myPhoto = //(mAccount.isMyGaiaId(mOwnerId)) ||
//                (mOwnerId == null && MediaStoreUtils.isMediaStoreUri(photoUri));
//        final boolean onlyPhotoUrl = (mPhotoId == INVALID_ID) && photoUri != null;
//        final boolean allowDownload = onlyPhotoUrl || (isRemotePhoto && (myPhoto || canDownload()));

//        if (hasPlusOned()) {
//            setVisible(menu, R.id.remove_plus1, true);
//            setVisible(menu, R.id.plus1, false);
//        } else {
//            setVisible(menu, R.id.remove_plus1, false);
//            setVisible(menu, R.id.plus1, mAllowPlusOne && isRemotePhoto);
//        }
//        setVisible(menu, R.id.download_photo, allowDownload);

        return true;
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        if (!mCallback.isFragmentActive(this)) {
            return;
        }

        // some menu stuff in the action bar
//        inflater.inflate(R.menu.photo_view_menu, menu);
//        if (Build.VERSION.SDK_INT >= 11) {
//            // On SDK < 11, we cannot set the progress bar view here; the menu is only inflated
//            // after the user presses the menu button. Since we want to be able to show the
//            // progress bar at any time, we create it manually in onCreate().
//            final View barLayout =
//                    menu.findItem(R.id.action_bar_progress_spinner).getActionView();
//            final ProgressBar progressBarView =
//                    (ProgressBar) barLayout.findViewById(R.id.action_bar_progress_spinner_view);
//            onUpdateProgressView(progressBarView);
//        }
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        if (!mCallback.isFragmentActive(this)) {
            return;
        }

//        final Long shapeId = (mAdapter == null)
//                ? null : mAdapter.getMyApprovedShapeId();
//        final boolean taggedAsMe = (shapeId != null);
//        final Uri photoUri = (mPhotoUrl != null) ? Uri.parse(mPhotoUrl) : null;
//        final boolean isRemotePhoto =
//                (mPhotoId != INVALID_ID) && !MediaStoreUtils.isMediaStoreUri(photoUri);
//        final boolean onlyPhotoUrl = (mPhotoId == INVALID_ID) && photoUri != null;
//        final boolean myPhoto = (mAccount.isMyGaiaId(mOwnerId)) ||
//                (mOwnerId == null && MediaStoreUtils.isMediaStoreUri(photoUri));
//        final String photoStream = mIntent.getStringExtra(Intents.EXTRA_STREAM_ID);
//        final boolean isInstantUpload = ApiUtils.CAMERA_SYNC_STREAM_ID.equals(photoStream);
//        final boolean allowDownload = onlyPhotoUrl || (isRemotePhoto && (myPhoto || canDownload()));
//
//        if (Build.VERSION.SDK_INT < 11) {
//            setVisible(menu, R.id.remove_plus1, false);
//            setVisible(menu, R.id.plus1, false);
//        } else if (hasPlusOned()) {
//            setVisible(menu, R.id.remove_plus1, true);
//            setVisible(menu, R.id.plus1, false);
//        } else {
//            setVisible(menu, R.id.remove_plus1, false);
//            setVisible(menu, R.id.plus1, mAllowPlusOne && isRemotePhoto);
//        }
//
//        // For now, only allow sharing of a photo in the "Instant Upload" album
//        setVisible(menu, R.id.share_photo, isInstantUpload);
//
//        // Only allow deletion of your own photos & reporting of other's photos
//        setVisible(menu, R.id.set_profile_photo, myPhoto || taggedAsMe);
//        setVisible(menu, R.id.set_wallpaper_photo, myPhoto);
//        setVisible(menu, R.id.delete_photo, myPhoto);
//        setVisible(menu, R.id.download_photo, allowDownload);
//        setVisible(menu, R.id.report_photo, !myPhoto && isRemotePhoto);
//        setVisible(menu, R.id.refresh_photo, isRemotePhoto);
//        setVisible(menu, R.id.remove_tag, taggedAsMe);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (!mCallback.isFragmentActive(this)) {
            return false;
        }

        final Activity activity = getActivity();

        switch (item.getItemId()) {
            case android.R.id.home: {
                ((BaseFragmentActivity) activity).onTitlebarLabelClick();
                return true;
            }
        }

        return false;
//            case R.id.plus1: {
//                if (canTogglePlusOne()) {
//                    EsService.photoPlusOne(getActivity(), mAccount, mOwnerId, mAlbumId, mPhotoId,
//                            true);
//                }
//                return true;
//            }
//
//            case R.id.remove_plus1: {
//                if (canTogglePlusOne()) {
//                    EsService.photoPlusOne(getActivity(), mAccount, mOwnerId, mAlbumId, mPhotoId,
//                            false);
//                }
//                return true;
//            }
//
//            case R.id.share_photo: {
//                final Uri photoUri = (mPhotoUrl != null) ? Uri.parse(mPhotoUrl) : null;
//                final Uri localUri = MediaStoreUtils.isMediaStoreUri(photoUri) ? photoUri : null;
//                final String remoteUrl = (localUri != null) ? null : mPhotoUrl;
//                final MediaRef ref = new MediaRef(mOwnerId, mPhotoId, remoteUrl,
//                        localUri, MediaRef.MediaType.IMAGE);
//                final ArrayList<MediaRef> refList = new ArrayList<MediaRef>();
//                refList.add(ref);
//
//                final Context context = getActivity();
//                final Intent intent = Intents.getPostActivityIntent(context, mAccount, refList);
//                startActivity(intent);
//                return true;
//            }
//
//            case R.id.set_profile_photo: {
//                final Uri photoUri = (mPhotoUrl != null) ? Uri.parse(mPhotoUrl) : null;
//                final Uri localUri = MediaStoreUtils.isMediaStoreUri(photoUri) ? photoUri : null;
//                final String remoteUrl = (localUri != null) ? null : mPhotoUrl;
//                final MediaRef mediaRef = new MediaRef(mOwnerId, mPhotoId, remoteUrl,
//                        localUri, MediaRef.MediaType.IMAGE);
//                startActivityForResult(Intents.getPhotoPickerIntent(getActivity(), mAccount,
//                        mDisplayName, mediaRef, true, Intents.PICKER_DEST_PROFILE),
//                        REQUEST_PHOTO_PICKER);
//                return true;
//            }
//
//            case R.id.download_photo: {
//                downloadPhoto(activity, true);
//                return true;
//            }
//
//            case R.id.set_wallpaper_photo: {
//                showProgressDialog(OP_SET_WALLPAPER_PHOTO,
//                        getString(R.string.set_wallpaper_photo_pending));
//                new AsyncTask<Void, Void, Boolean>() {
//                    @Override
//                    protected void onPostExecute(Boolean result) {
//                        final Resources res = getResources();
//                        final String toastText;
//
//                        if (result) {
//                            toastText = res.getString(R.string.set_wallpaper_photo_success);
//                        } else {
//                            toastText = res.getString(R.string.set_wallpaper_photo_error);
//                        }
//                        Toast.makeText(activity, toastText, Toast.LENGTH_SHORT).show();
//
//                        hideProgressDialog();
//                    }
//
//                    @Override
//                    protected Boolean doInBackground(Void... params) {
//                        try {
//                            final Bitmap bitmap = mAdapter.getPhotoImage();
//                            if (bitmap != null) {
//                                final WallpaperManager manager =
//                                        WallpaperManager.getInstance(getActivity());
//                                manager.setBitmap(bitmap);
//
//                                return Boolean.TRUE;
//                            }
//                        } catch (IOException e) {
//                            Log.e(TAG, "Exception setting wallpaper", e);
//                        }
//                        return Boolean.FALSE;
//                    }
//                }.execute((Void) null);
//
//                return true;
//            }
//
//            case R.id.remove_tag: {
//                final AlertFragmentDialog dialog = AlertFragmentDialog.newInstance(
//                        getString(R.string.menu_remove_tag),
//                        getString(R.string.remove_tag_question),
//                        getString(R.string.ok),
//                        getString(R.string.cancel));
//                dialog.setTargetFragment(this, 0);
//                dialog.show(getFragmentManager(), DIALOG_TAG_REMOVE_TAG);
//                return true;
//            }
//
//            case R.id.refresh_photo: {
//                refresh();
//                return true;
//            }
//
//            case R.id.delete_photo: {
//                final Resources res = getResources();
//                final Uri photoUri = (mPhotoUrl != null) ? Uri.parse(mPhotoUrl) : null;
//                final Uri localUri =
//                        MediaStoreUtils.isMediaStoreUri(photoUri) ? photoUri : null;
//                final int messageId = localUri == null
//                        ? R.plurals.delete_remote_photo_dialog_message
//                        : R.plurals.delete_local_photo_dialog_message;
//                final AlertFragmentDialog dialog = AlertFragmentDialog.newInstance(
//                        res.getQuantityString(R.plurals.delete_photo_dialog_title, 1),
//                        res.getQuantityString(messageId, 1),
//                        res.getQuantityString(R.plurals.delete_photo, 1),
//                        getString(R.string.cancel));
//                dialog.setTargetFragment(this, 0);
//                dialog.show(getFragmentManager(), DIALOG_TAG_REMOVE_PHOTO);
//                return true;
//            }
//
//            case R.id.report_photo: {
//                final AlertFragmentDialog dialog = AlertFragmentDialog.newInstance(
//                        getString(R.string.menu_report_photo),
//                        getString(R.string.report_photo_question),
//                        getString(R.string.ok),
//                        getString(R.string.cancel));
//                dialog.setTargetFragment(this, 0);
//                dialog.show(getFragmentManager(), DIALOG_TAG_REPORT_PHOTO);
//                return true;
//            }
//
//            case R.id.settings: {
//                final Intent intent = Intents.getSettingsActivityIntent(activity, mAccount);
//                startActivity(intent);
//                return true;
//            }
//
//            case R.id.feedback: {
//                recordUserAction(Logging.Targets.Action.SETTINGS_FEEDBACK);
//                GoogleFeedback.launch(getActivity());
//                return true;
//            }
//
//            case R.id.help:
//                startExternalActivity(new Intent(Intent.ACTION_VIEW,
//                        HelpUrl.getHelpUrl(activity, HELP_LINK_PARAMETER)));
//                return true;
//
//            default: {
//                return false;
//            }
//        }
    }

    /**
     * Download the currently showing photo.
     *
     * @param context The context
     * @param fullRes If {@code true}, download the photo at max resolution. Otherwise, download
     *          the photo no larger than {@link DownloadPhotoTask#MAX_DOWNLOAD_SIZE}.
     */
    public void downloadPhoto(Context context, boolean fullRes) {
//        if (mAdapter == null) {
//            return;
//        }
//
//        final MediaRef mediaRef = mAdapter.getPhotoRef();
//        final String albumName = mAdapter.getAlbumName();
//
//        final String imageUrl;
//        if (mPhotoId == INVALID_ID) {
//            imageUrl = mPhotoUrl;
//        } else {
//            imageUrl = (mediaRef == null) ? null : mediaRef.getUrl();
//        }
//
//        // Modify the image URL to adjust the size parameters. If this is the first attempt,
//        // try to download the full image. If this is not the first attempt, cap the image
//        // size to {@link #MAX_DOWNLOAD_SIZE}.
//        final String downloadUrl;
//        if (FIFEUtil.isFifeHostedUrl(imageUrl)) {
//            if (fullRes) {
//                downloadUrl = FIFEUtil.setImageUrlOptions("d", imageUrl).toString();
//            } else {
//                downloadUrl = FIFEUtil.setImageUrlSize(REDUCED_DOWNLOAD_SIZE, imageUrl, false);
//            }
//        } else {
//            downloadUrl = ImageProxyUtil.setImageUrlSize(
//                    fullRes ? ImageProxyUtil.ORIGINAL_SIZE : REDUCED_DOWNLOAD_SIZE, imageUrl);
//        }
//
//        if (downloadUrl != null) {
//            if (EsLog.isLoggable(TAG, Log.DEBUG)) {
//                Log.d(TAG, "Downloading image from: " + downloadUrl);
//            }
//
//            mNewerReqId = EsService.savePhoto(context, mAccount, downloadUrl, fullRes, albumName);
//            showProgressDialog(OP_DOWNLOAD_PHOTO, getString(R.string.download_photo_pending));
//        } else {
//            final String toastText = getResources().getString(R.string.download_photo_error);
//            Toast.makeText(context, toastText, Toast.LENGTH_LONG).show();
//        }
    }

    /**
     * Adds the given file to the system. This makes it available through the Media Store
     * and, optionally, the Downloads application.
     *
     * @param context The context
     * @param file The file to add.
     * @param description A description of the photo.
     * @param mimeType The type of the image file.
     */
    private void addDownloadToSystem(Context context, File file,
            String description, String mimeType) {
        if (Build.VERSION.SDK_INT >= 12) {
            // Can't add a file to the Downloads application until SDK v12
            try {
                final DownloadManager dm =
                        (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
                dm.addCompletedDownload(file.getName(), description, true, mimeType,
                        file.getAbsolutePath(), file.length(), false);
            } catch (IllegalArgumentException e) {
                Log.w(TAG, "Could not add photo to the Downloads application", e);
            }
        }

        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(Uri.parse(file.toURI().toString()));
        context.sendBroadcast(intent);
    }

    /**
     * Sets view visibility depending upon whether or not we're in "full screen" mode.
     *
     * @param animate If {@code true}, animate views in/out. Otherwise, snap views.
     */
    private void setViewVisibility() {
        final boolean fullScreen = mCallback.isFragmentFullScreen(this);
        final boolean hide = fullScreen;

        setFullScreen(hide);
    }

    /**
     * Sets full-screen mode for the views.
     */
    public void setFullScreen(boolean fullScreen) {
        mFullScreen = fullScreen;
        mPhotoView.enableImageTransforms(mFullScreen);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        if (!mCallback.isFragmentActive(this)) {
            return false;
        }

        AdapterView.AdapterContextMenuInfo info;
        try {
            info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
        } catch (ClassCastException e) {
            return false;
        }

        // Ignore the header view long click
        if (info.position == 0) {
            return false;
        }

        return false;
    }

    /**
     * Helper function to set the visibility of a given menu item.
     */
    private void setVisible(Menu menu, int menuItemId, boolean visible) {
        MenuItem item;
        item = menu.findItem(menuItemId);
        if (item != null) {
            item.setVisible(visible);
        }
    }

    /** Updates the menu items */
    private void updateMenuItems() {
        if (mCallback != null) {
            mCallback.updateMenuItems();
        }
    }

    /**
     * Updates the view to show the correct content. If the view is null or does not contain
     * the special id {@link android.R.id#empty}, performs no action.
     */
    private void updateView(View view) {
        if (view == null || (view.findViewById(android.R.id.empty) == null)) {
            return;
        }

        final boolean hasImage = isPhotoBound();
        final boolean imageLoading = isPhotoLoading();

        if (imageLoading) {
            showEmptyViewProgress(view);
        } else {
            if (hasImage) {
                showContent(view);
            } else if (mIsPlaceHolder) {
                setupEmptyView(view, R.string.photo_view_placeholder_image);
                showEmptyView(view);
            } else {
                setupEmptyView(view, R.string.photo_network_error);
                showEmptyView(view);
            }
        }
        updateSpinner(mProgressBarView);
    }
}
