com.gmail.charleszq.picorner.ui.ImageDetailFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.gmail.charleszq.picorner.ui.ImageDetailFragment.java

Source

/*
 * Copyright (C) 2012 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.gmail.charleszq.picorner.ui;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import android.app.ActionBar;
import android.app.Activity;
import android.app.WallpaperManager;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.support.v4.app.ShareCompat;
import android.util.Log;
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.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.ShareActionProvider;
import android.widget.ShareActionProvider.OnShareTargetSelectedListener;
import android.widget.TextView;
import android.widget.Toast;

import com.gmail.charleszq.picorner.BuildConfig;
import com.gmail.charleszq.picorner.PicornerApplication;
import com.gmail.charleszq.picorner.R;
import com.gmail.charleszq.picorner.SPUtil;
import com.gmail.charleszq.picorner.dp.IPhotosProvider;
import com.gmail.charleszq.picorner.model.Author;
import com.gmail.charleszq.picorner.model.MediaObject;
import com.gmail.charleszq.picorner.model.MediaSourceType;
import com.gmail.charleszq.picorner.msg.Message;
import com.gmail.charleszq.picorner.msg.MessageBus;
import com.gmail.charleszq.picorner.offline.OfflineControlFileUtil;
import com.gmail.charleszq.picorner.task.IGeneralTaskDoneListener;
import com.gmail.charleszq.picorner.task.flickr.CheckUserLikePhotoTask;
import com.gmail.charleszq.picorner.task.flickr.FlickrLikeTask;
import com.gmail.charleszq.picorner.task.ig.InstagramLikePhotoTask;
import com.gmail.charleszq.picorner.task.px500.PxLikePhotoTask;
import com.gmail.charleszq.picorner.task.px500.PxVotePhotoTask;
import com.gmail.charleszq.picorner.ui.ImageDetailActivity.IActionBarVisibleListener;
import com.gmail.charleszq.picorner.utils.IConstants;
import com.gmail.charleszq.picorner.utils.ImageUtils;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageLoadingListener;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;

/**
 * This fragment will populate the children of the ViewPager from
 * {@link ImageDetailActivity}.
 */
public class ImageDetailFragment extends Fragment implements OnShareTargetSelectedListener {

    private static final String IMAGE_DATA_EXTRA = "extra_image_data"; //$NON-NLS-1$
    private static final String MEDIA_OBJ_POS = "media_object"; //$NON-NLS-1$
    private static final String TAG = ImageDetailFragment.class.getSimpleName();

    // ui controls.
    private String mImageUrl;
    private MediaObject mPhoto;
    private ImageView mImageView;
    private ImageLoader mImageFetcher;
    private View mUserInfoContainer;
    private TextView mPhotoTitle;
    private TextView mUserName;

    /**
     * The current pos of the image in the photo list.
     */
    private int mCurrentPos;

    /**
     * The image display options
     */
    private DisplayImageOptions mImageDisplayOptions;

    /**
     * The loaded bitmap
     */
    private Bitmap mLoadedBitmap = null;

    /**
     * The current file name to store image so the share action can get the
     * image from it.
     */
    private String mCurrentShareIntentFileName = null;

    /**
     * The image laoder listener.
     */
    private ImageLoadingListener mImageLoaderListener = new ImageLoadingListener() {

        @Override
        public void onLoadingStarted() {
            mLoadedBitmap = null;
        }

        @Override
        public void onLoadingFailed(FailReason failReason) {
            mLoadedBitmap = null;
        }

        @Override
        public void onLoadingComplete(Bitmap loadedImage) {
            mLoadedBitmap = loadedImage;
            if (mIsOfflineEnabled) {
                OfflineViewSavePhotoTask task = new OfflineViewSavePhotoTask(getActivity(), loadedImage, mPhoto);
                task.execute();
            }
        }

        @Override
        public void onLoadingCancelled() {
            mLoadedBitmap = null;
        }
    };

    private static class OfflineViewSavePhotoTask extends AsyncTask<Void, Integer, Void> {

        private Context mContext;
        private Bitmap mBitmap;
        private MediaObject mPhoto;

        OfflineViewSavePhotoTask(Context context, Bitmap bitmap, MediaObject photo) {
            this.mContext = context;
            this.mBitmap = bitmap;
            this.mPhoto = photo;
        }

        @Override
        protected Void doInBackground(Void... params) {
            if (mContext != null) {
                String filename = OfflineControlFileUtil.getOfflinePhotoFileName(mPhoto);
                File file = mContext.getFileStreamPath(filename);
                if (file.exists())
                    return null;
                OfflineControlFileUtil.saveBitmapForOfflineView(mContext, mBitmap, mPhoto);
                if (BuildConfig.DEBUG) {
                    Log.d(ImageDetailFragment.class.getSimpleName(), "Photo saved for offline view."); //$NON-NLS-1$
                }
            }
            return null;
        }

    }

    private IActionBarVisibleListener mActionBarListener = new IActionBarVisibleListener() {

        @Override
        public void onActionBarShown(boolean show) {
            ImageDetailFragment.this.onActionBarShown(show);

        }
    };

    /**
     * If user likes this photo or not.
     */
    private boolean mUserLikeThePhoto = false;

    /**
     * offline enable?
     */
    private boolean mIsOfflineEnabled = false;

    /**
     * Factory method to generate a new instance of the fragment given an image
     * number.
     * 
     * @param imageUrl
     *            The image url to load
     * @return A new instance of ImageDetailFragment with imageNum extras
     */
    public static ImageDetailFragment newInstance(String imageUrl, IPhotosProvider dp, int pos,
            boolean offlineEnabled) {
        final ImageDetailFragment f = new ImageDetailFragment();

        final Bundle args = new Bundle();
        args.putString(IMAGE_DATA_EXTRA, imageUrl);
        args.putInt(MEDIA_OBJ_POS, pos);
        args.putSerializable(ImageDetailActivity.DP_KEY, dp);
        args.putBoolean(ImageDetailActivity.OFFLINE_COMMAND_KEY, offlineEnabled);
        f.setArguments(args);

        return f;
    }

    private void onActionBarShown(boolean show) {
        if (mUserInfoContainer != null) {
            mUserInfoContainer.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
        }
    }

    /**
     * Empty constructor as per the Fragment documentation
     */
    public ImageDetailFragment() {
        mLoadedBitmap = null;
    }

    /**
     * Populate image using a url from extras, use the convenience factory
     * method {@link ImageDetailFragment#newInstance(String)} to create this
     * fragment.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mImageDisplayOptions = new DisplayImageOptions.Builder().showStubImage(R.drawable.empty_photo).cacheOnDisc()
                .imageScaleType(ImageScaleType.IN_SAMPLE_INT).bitmapConfig(Bitmap.Config.RGB_565).build();

        mIsOfflineEnabled = getArguments() != null
                ? (getArguments().getBoolean(ImageDetailActivity.OFFLINE_COMMAND_KEY, false))
                : false;
        mImageUrl = getArguments() != null ? getArguments().getString(IMAGE_DATA_EXTRA) : null;
        int pos = (getArguments() != null ? getArguments().getInt(MEDIA_OBJ_POS) : -1);
        IPhotosProvider dp = (IPhotosProvider) (getArguments() != null
                ? getArguments().getSerializable(ImageDetailActivity.DP_KEY)
                : null);
        mCurrentPos = pos;
        ImageDetailActivity act = (ImageDetailActivity) getActivity();
        mPhoto = dp.getMediaObject(pos);
        if (BuildConfig.DEBUG)
            Log.d(TAG, "large url: " + mPhoto.getLargeUrl()); //$NON-NLS-1$

        setHasOptionsMenu(true);
        act.addActionBarListener(mActionBarListener);
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.support.v4.app.Fragment#onResume()
     */
    @Override
    public void onResume() {
        super.onResume();
        checkUserLikeOrNot();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        // Inflate and locate the main ImageView
        final View v = inflater.inflate(R.layout.image_detail_fragment, container, false);
        mImageView = (ImageView) v.findViewById(R.id.imageView);

        // photo title and author name
        mUserInfoContainer = v.findViewById(R.id.photo_detail_user_info);
        ActionBar bar = getActivity().getActionBar();
        mUserInfoContainer.setVisibility(bar.isShowing() ? View.VISIBLE : View.INVISIBLE);
        mPhotoTitle = (TextView) v.findViewById(R.id.photo_detail_photo_title);
        String photoTitle = mPhoto.getTitle();
        if (photoTitle == null) {
            photoTitle = ""; //$NON-NLS-1$
        } else {
            if (photoTitle.length() > IConstants.MAX_PHOTO_TITLE_LEN) {
                photoTitle = photoTitle.substring(0, IConstants.MAX_PHOTO_TITLE_LEN) + "..."; //$NON-NLS-1$
            }
        }
        StringBuilder pt = new StringBuilder();
        if (mPhoto.getMediaSource() == MediaSourceType.PX500) {
            pt.append(getString(R.string.px500_rating)).append(" ").append(mPhoto.getRating()).append("\n"); //$NON-NLS-1$//$NON-NLS-2$
        }
        pt.append(photoTitle);
        mPhotoTitle.setText(pt.toString());
        mUserName = (TextView) v.findViewById(R.id.photo_detail_author_name);
        StringBuilder sb = new StringBuilder();
        sb.append(getString(R.string.msg_by_author_name));
        sb.append(" "); //$NON-NLS-1$
        Author a = mPhoto.getAuthor();
        if (a != null) {
            sb.append(mPhoto.getAuthor().getUserName() == null ? mPhoto.getAuthor().getUserId()
                    : mPhoto.getAuthor().getUserName());
            mUserName.setText(sb.toString());
        }

        return v;
    }

    /*
     * (non-Javadoc)
     * 
     * @see android.support.v4.app.Fragment#onStart()
     */
    @Override
    public void onStart() {
        super.onStart();
        Activity act = getActivity();
        // set the actionbar title.
        StringBuilder sb = new StringBuilder();
        switch (mPhoto.getMediaSource()) {
        case FLICKR:
            sb.append(getString(R.string.menu_header_flickr));
            break;
        case INSTAGRAM:
            sb.append(getString(R.string.menu_header_ig));
            break;
        case PX500:
            sb.append(getString(R.string.menu_header_px500));
            break;
        }
        sb.append(" ").append(getString(R.string.msg_photo)); //$NON-NLS-1$
        act.getActionBar().setSubtitle(sb.toString().toLowerCase());
    }

    private boolean likePhoto(final MenuItem item) {

        // prepare the animator
        ProgressBar pb = new ProgressBar(getActivity());
        item.setActionView(pb);

        switch (mPhoto.getMediaSource()) {
        case PX500:
            if (SPUtil.getPx500OauthTokenSecret(getActivity()) == null) {
                Toast.makeText(getActivity(), getString(R.string.pls_sing_in_first), Toast.LENGTH_SHORT).show();
                return false;
            }
            break;
        case FLICKR:
            if (!SPUtil.isFlickrAuthed(getActivity())) {
                Toast.makeText(getActivity(), getString(R.string.pls_sing_in_first), Toast.LENGTH_SHORT).show();
                return false;
            }
            break;
        case INSTAGRAM:
            if (SPUtil.getInstagramUserId(getActivity()) == null) {
                Toast.makeText(getActivity(), getString(R.string.pls_sing_in_first), Toast.LENGTH_SHORT).show();
                return false;
            }
            break;
        }

        if (mLoadedBitmap == null) {
            return false; // image not loaded yet.
        }

        IGeneralTaskDoneListener<Boolean> lis = new IGeneralTaskDoneListener<Boolean>() {
            @Override
            public void onTaskDone(Boolean result) {
                item.setActionView(null);
                if (result) {
                    mUserLikeThePhoto = !mUserLikeThePhoto;
                    mPhoto.setUserLiked(mUserLikeThePhoto);
                    Activity act = ImageDetailFragment.this.getActivity();
                    if (act != null) {
                        act.invalidateOptionsMenu();
                    }
                    // broadcast messages
                    Message msg = new Message(Message.LIKE_PHOTO, mPhoto.getMediaSource(), mPhoto.getId(),
                            mUserLikeThePhoto);
                    MessageBus.broadcastMessage(msg);
                } else {
                    if (getActivity() != null)
                        Toast.makeText(getActivity(), getString(R.string.msg_like_photo_fail), Toast.LENGTH_SHORT)
                                .show();
                }
            }
        };
        String likeActionString = Boolean.toString(!mUserLikeThePhoto);
        switch (this.mPhoto.getMediaSource()) {
        case FLICKR:
            FlickrLikeTask ftask = new FlickrLikeTask(getActivity(), lis);
            ftask.execute(mPhoto.getId(), likeActionString);
            break;
        case INSTAGRAM:
            InstagramLikePhotoTask igtask = new InstagramLikePhotoTask(getActivity(), lis);
            igtask.execute(mPhoto.getId(), likeActionString);
            break;
        case PX500:
            PxLikePhotoTask pxTask = new PxLikePhotoTask(getActivity());
            pxTask.addTaskDoneListener(lis);
            pxTask.execute(mPhoto.getId(), likeActionString);
            break;
        }
        return true;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mImageFetcher = ((ImageDetailActivity) getActivity()).getImageFetcher();
        // show the image either from offline cache or from network.
        String filename = OfflineControlFileUtil.getOfflinePhotoFileName(mPhoto);
        if (OfflineControlFileUtil.isFileExist(getActivity(), filename)) {
            File f = getActivity().getFileStreamPath(filename);
            Uri uri = Uri.fromFile(f);
            mImageFetcher.displayImage(uri.toString(), mImageView, mImageDisplayOptions, mImageLoaderListener);
            if (BuildConfig.DEBUG)
                Log.d(TAG, "Load thumb image from offline cache."); //$NON-NLS-1$
        } else {
            mImageFetcher.displayImage(mImageUrl, mImageView, mImageDisplayOptions, mImageLoaderListener);
        }

        // Pass clicks on the ImageView to the parent activity to handle
        if (OnClickListener.class.isInstance(getActivity())) {
            mImageView.setOnClickListener((OnClickListener) getActivity());
            mUserInfoContainer.setOnClickListener((OnClickListener) getActivity());
            this.mPhotoTitle.setOnClickListener((OnClickListener) getActivity());
            this.mUserName.setOnClickListener((OnClickListener) getActivity());
        }
    }

    @Override
    public void onDestroy() {
        if (mImageView != null) {
            mImageFetcher.cancelDisplayTask(mImageView);
            mImageView.setImageDrawable(null);
        }
        ImageDetailActivity act = (ImageDetailActivity) getActivity();
        if (act != null)
            act.removeActionBarListener(mActionBarListener);
        super.onDestroy();
    }

    @Override
    public void onDetach() {
        mLoadedBitmap = null;
        ImageDetailActivity act = (ImageDetailActivity) getActivity();
        act.removeActionBarListener(mActionBarListener);
        super.onDetach();
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu_photo_detail, menu);
        inflater.inflate(R.menu.my_flickr_photo_menus, menu);
        inflater.inflate(R.menu.photo_detail_common, menu);
    }

    private void checkUserLikeOrNot() {

        switch (mPhoto.getMediaSource()) {
        case INSTAGRAM:
        case PX500:
            Log.d(TAG, "Do I like this photo? " + mPhoto.isUserLiked()); //$NON-NLS-1$
            mUserLikeThePhoto = mPhoto.isUserLiked();
            getActivity().invalidateOptionsMenu();
            break;
        case FLICKR:
            if (mPhoto.isUserLiked()) {
                // if it's true, it means we've already checked again the
                // server, so we don't need to check again.
                mUserLikeThePhoto = true;
                getActivity().invalidateOptionsMenu();
            } else {
                CheckUserLikePhotoTask task = new CheckUserLikePhotoTask(getActivity());
                task.addTaskDoneListener(new IGeneralTaskDoneListener<Boolean>() {

                    @Override
                    public void onTaskDone(Boolean result) {
                        mPhoto.setUserLiked(result);
                        Log.d(TAG, "Do I like this photo? " + result.toString()); //$NON-NLS-1$
                        mUserLikeThePhoto = mPhoto.isUserLiked();
                        Activity act = ImageDetailFragment.this.getActivity();
                        if (act != null) {
                            act.invalidateOptionsMenu();
                        }
                    }
                });
                task.execute(mPhoto.getId(), mPhoto.getSecret());
            }
            break;
        }
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        MenuItem likeItem = menu.findItem(R.id.menu_item_like);
        MenuItem ownerPhotoItem = menu.findItem(R.id.menu_item_see_owner_photos);
        MenuItem commentItem = menu.findItem(R.id.menu_item_comment);
        MenuItem mapItem = menu.findItem(R.id.menu_item_view_on_map);
        MenuItem exifItem = menu.findItem(R.id.menu_item_view_exif);
        MenuItem detailItem = menu.findItem(R.id.menu_item_detail);

        PicornerApplication app = (PicornerApplication) getActivity().getApplication();

        boolean ismyphoto = app.isMyOwnPhoto(mPhoto);
        ownerPhotoItem.setVisible(!ismyphoto);
        switch (mPhoto.getMediaSource()) {
        case FLICKR:
            menu.setGroupVisible(R.id.group_my_flickr_photo, ismyphoto);
            likeItem.setVisible(!ismyphoto);
            break;
        case PX500:
            menu.setGroupVisible(R.id.group_my_flickr_photo, false);
            likeItem.setVisible(!ismyphoto);
            break;
        case INSTAGRAM:
            commentItem.setVisible(false);
            exifItem.setVisible(false);
            menu.setGroupVisible(R.id.group_my_flickr_photo, false);
            break;
        case RSS:
            menu.setGroupVisible(R.id.group_my_flickr_photo, false);
            likeItem.setVisible(false);
            exifItem.setVisible(false);
            commentItem.setVisible(false);
            ownerPhotoItem.setVisible(false);
            detailItem.setVisible(false);
            break;
        }

        mapItem.setVisible(mPhoto.getLocation() != null);

        if (mUserLikeThePhoto) {
            likeItem.setIcon(R.drawable.star_big_on);
        } else {
            likeItem.setIcon(R.drawable.ic_menu_star);
        }

        // 500px menu group
        MenuItem voteItem = menu.findItem(R.id.menu_item_vote);
        if (mPhoto.getMediaSource() != MediaSourceType.PX500) {
            voteItem.setVisible(false);
        } else {
            voteItem.setVisible(SPUtil.getPx500OauthToken(getActivity()) != null && !app.isMyOwnPhoto(mPhoto)
                    && !mPhoto.isUserVoted());
        }
    }

    private boolean waitForImageLoaded() {
        if (mLoadedBitmap == null) {
            Toast.makeText(getActivity(), R.string.wait_for_image_loading, Toast.LENGTH_SHORT).show();
            return false;
        }
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (mLoadedBitmap != null) {
            saveBitmapToShare(mLoadedBitmap, null);
        }

        switch (item.getItemId()) {
        case android.R.id.home:
            getActivity().finish();
            return true;
        case R.id.menu_item_share_action_provider_action_bar:
            boolean ready = waitForImageLoaded();
            if (ready) {
                sharePhoto();
            }
            return ready;
        case R.id.menu_item_slide_show:
            ImageDetailActivity act = (ImageDetailActivity) getActivity();
            if (act != null) {
                act.startSlideShow(0);
            }
            return true;
        case R.id.menu_item_see_owner_photos:
            Intent i = new Intent(getActivity(), UserPhotoListActivity.class);
            i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            i.putExtra(UserPhotoListActivity.MD_TYPE_KEY, mPhoto.getMediaSource().ordinal());
            i.putExtra(UserPhotoListActivity.USER_KEY, mPhoto.getAuthor());
            startActivity(i);
            return true;
        case R.id.menu_item_like:
            ready = waitForImageLoaded();
            if (ready)
                likePhoto(item);
            return ready;
        case R.id.menu_item_vote:
            ready = waitForImageLoaded();
            if (ready)
                votePhoto();
            return ready;
        case R.id.menu_item_save:
            ready = waitForImageLoaded();
            if (ready)
                savePhotoLocally();
            return ready;
        case R.id.menu_item_set_wallpaper:
            ready = waitForImageLoaded();
            if (!ready)
                return false;

            WallpaperManager wm = WallpaperManager.getInstance(getActivity());
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(getShareImageFile(null));
                wm.setStream(fis);
                Toast.makeText(getActivity(), getResources().getString(R.string.msg_wallpaper_changed),
                        Toast.LENGTH_SHORT).show();
            } catch (IOException e) {
            } finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                    }
                }
            }
            return true;
        case R.id.menu_item_detail:
            showPhotoDetailWithPage(null);
            return true;
        case R.id.menu_item_comment:
            showPhotoDetailWithPage(PhotoDetailActivity.COMMENT_PAGE);
            return true;
        case R.id.menu_item_photo_set:
            showPhotoDetailWithPage(PhotoDetailActivity.MY_F_ORG_PHOTO_SET_PAGE);
            return true;
        case R.id.menu_item_add_to_group:
            showPhotoDetailWithPage(PhotoDetailActivity.MY_F_ORG_GROUP_PAGE);
            return true;
        case R.id.menu_item_view_exif:
            showPhotoDetailWithPage(PhotoDetailActivity.EXIF_PAGE);
            return true;
        case R.id.menu_item_view_on_map:
            showPhotoDetailWithPage(PhotoDetailActivity.MAP_PAGE);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    private void showPhotoDetailWithPage(String pageIndex) {
        Intent detailIntent = new Intent(getActivity(), PhotoDetailActivity.class);
        IPhotosProvider dp = ((ImageDetailActivity) getActivity()).mPhotosProvider;
        detailIntent.putExtra(ImageDetailActivity.DP_KEY, dp);
        detailIntent.putExtra(ImageDetailActivity.LARGE_IMAGE_POSITION, mCurrentPos);
        if (pageIndex != null)
            detailIntent.putExtra(PhotoDetailActivity.DETAIL_PAGE_KEY, pageIndex);
        startActivity(detailIntent);
    }

    /**
     * Votes a 500px photo.
     */
    private void votePhoto() {
        PxVotePhotoTask task = new PxVotePhotoTask(getActivity());
        task.addTaskDoneListener(new IGeneralTaskDoneListener<Boolean>() {

            @Override
            public void onTaskDone(Boolean result) {
                if (result) {
                    Toast.makeText(getActivity(), getString(R.string.msg_500px_photo_voted), Toast.LENGTH_SHORT)
                            .show();
                    mPhoto.setUserVoted(true);
                    getActivity().invalidateOptionsMenu();

                    // broadcast messages
                    Message msg = new Message(Message.VOTE_PHOTO, mPhoto.getMediaSource(), mPhoto.getId(), true);
                    MessageBus.broadcastMessage(msg);
                } else {
                    Toast.makeText(getActivity(), getString(R.string.msg_500px_photo_vote_failed),
                            Toast.LENGTH_SHORT).show();
                }
            }
        });
        task.execute(mPhoto.getId());
    }

    private void sharePhoto() {
        // delete previous share files
        File root = new File(Environment.getExternalStorageDirectory(), IConstants.SD_CARD_FOLDER_NAME);
        if (root.exists())
            for (File f : root.listFiles()) {
                if (f.getName().startsWith(IConstants.SHARE_INTENT_TMP_FILE_PREFIX)) {
                    if (f.delete()) {
                        Log.d(TAG, "file deleted: " + f.getName()); //$NON-NLS-1$
                    }
                }
            }

        // share this one
        StringBuilder sb = new StringBuilder();
        sb.append(IConstants.SHARE_INTENT_TMP_FILE_PREFIX);
        sb.append(String.valueOf(Math.random()));
        sb.append(".png"); //$NON-NLS-1$
        mCurrentShareIntentFileName = sb.toString();
        saveBitmapToShare(mLoadedBitmap, mCurrentShareIntentFileName);
        Intent shareIntent = createShareIntent(mCurrentShareIntentFileName);
        getActivity().startActivity(shareIntent);
    }

    /**
     * Saves the photo locally.
     */
    private void savePhotoLocally() {
        File root = new File(Environment.getExternalStorageDirectory(), IConstants.SD_CARD_FOLDER_NAME);
        StringBuilder sb = new StringBuilder();
        sb.append(mPhoto.getMediaSource().toString());
        sb.append("_").append(mPhoto.getId()); //$NON-NLS-1$
        sb.append(".png"); //$NON-NLS-1$
        File saveFile = new File(root, sb.toString());
        if (!saveFile.exists()) {
            ImageUtils.saveImageToFile(saveFile, mLoadedBitmap);
            String msg = getString(R.string.msg_photo_saved_locally);
            msg = String.format(msg, IConstants.SD_CARD_FOLDER_NAME + File.separator + sb.toString());
            Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getActivity(), getString(R.string.msg_photo_save_exists), Toast.LENGTH_SHORT).show();
        }
    }

    private File getShareImageFile(String fileName) {
        File root = new File(Environment.getExternalStorageDirectory(), IConstants.SD_CARD_FOLDER_NAME);
        if (fileName == null) {
            fileName = IConstants.SHARE_TEMP_FILE_NAME;
        }
        File saveFile = new File(root, fileName);
        return saveFile;
    }

    private Intent createShareIntent(String filename) {
        File shareFile = getShareImageFile(filename);
        Uri uri = Uri.fromFile(shareFile);

        StringBuilder sb = new StringBuilder();
        sb.append(ImageUtils.getPhotoShareLink(mPhoto));
        sb.append(" ").append(getString(R.string.share_via)).append(" "); //$NON-NLS-1$//$NON-NLS-2$
        sb.append(getString(R.string.app_name));
        sb.append(" ").append(IConstants.APP_GL_STORE_URL); //$NON-NLS-1$
        saveToClipboard(sb.toString());

        Intent shareIntent = ShareCompat.IntentBuilder.from(getActivity()).setText(sb.toString()).setType("image/*") //$NON-NLS-1$
                .setStream(uri).createChooserIntent();
        shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
        return shareIntent;
    }

    private void saveToClipboard(String s) {
        ClipboardManager cm = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData data = ClipData.newPlainText(getString(R.string.app_name), s);
        cm.setPrimaryClip(data);
    }

    @Override
    public boolean onShareTargetSelected(ShareActionProvider source, Intent intent) {
        if (mLoadedBitmap != null) {
            saveBitmapToShare(mLoadedBitmap, null);
            return true;
        }
        return false;
    }

    private void saveBitmapToShare(Bitmap bitmap, String filename) {
        File bsRoot = new File(Environment.getExternalStorageDirectory(), IConstants.SD_CARD_FOLDER_NAME);
        if (!bsRoot.exists() && !bsRoot.mkdir()) {
            return;
        }
        if (filename == null) {
            filename = IConstants.SHARE_TEMP_FILE_NAME;
        }
        File shareFile = new File(bsRoot, filename);
        if (shareFile.exists()) {
            shareFile.delete();
        }

        ImageUtils.saveImageToFile(shareFile, bitmap);
    }
}