com.orbar.pxdemo.ImageView.FivePXImageFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.orbar.pxdemo.ImageView.FivePXImageFragment.java

Source

package com.orbar.pxdemo.ImageView;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import uk.co.senab.photoview.PhotoViewAttacher;
import uk.co.senab.photoview.PhotoViewAttacher.OnPhotoTapListener;

import com.orbar.pxdemo.LoginActivity;
import com.orbar.pxdemo.LoginManager;
import com.orbar.pxdemo.MainActivity;
import com.orbar.pxdemo.R;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.orbar.pxdemo.APIHelper.Category;
import com.orbar.pxdemo.APIHelper.FiveZeroZeroImageAPIBuilder;
import com.orbar.pxdemo.APIHelper.License;
import com.orbar.pxdemo.Adapters.CommentsAdapter;
import com.orbar.pxdemo.AsyncTasks.FivePXBaseAsyncTask;
import com.orbar.pxdemo.AsyncTasks.FivePXBaseImageAsyncTask;
import com.orbar.pxdemo.MainActivity.BackPressedListener;
import com.orbar.pxdemo.Model.FiveZeroZeroCommentBean;
import com.orbar.pxdemo.Model.FiveZeroZeroImageBean;
import com.orbar.pxdemo.Model.FiveZeroZeroImageBean.IMAGE_SIZE;
import com.orbar.pxdemo.Model.FiveZeroZeroUserBean.USER_IMAGE_SIZE;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
import com.sothree.slidinguppanel.SlidingUpPanelLayout.PanelSlideListener;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.animation.AnimationUtils;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;
import android.widget.AbsListView.OnScrollListener;

public class FivePXImageFragment extends Fragment implements BackPressedListener {

    static final String TAG = "FivePXImageFragment";

    public static final String ARG_IMAGE_BEAN = "arg_image_bean";
    static final String ARG_IMAGE_PREVIEW = "arg_image_preview";

    View rootView;
    ActionBar actionBar;
    Bitmap actionBarUserImage;

    private PhotoViewAttacher mAttacher;

    RelativeLayout userAccountLayout;
    RelativeLayout imageControlsLayout;
    RelativeLayout imageDetailsLayout;

    ViewFlipper imageDetailFlipper;

    SlidingUpPanelLayout mSlidingPaneLayout;

    // View declerations 
    ListView commentsListView;

    ImageButton imageStats;
    Button imageComments;
    Button imageLikes;
    Button imageFavorites;
    ImageButton submitComment;

    EditText submitCommentBody;

    // AsyncTask for downloading the user image
    DownloadUserImage mDownloadUserImage;

    FiveZeroZeroImageBean mFiveZeroZeroImageBean;

    FiveZeroZeroImageAPIBuilder mFiveZeroZeroImageAPIBuilder;

    // inputs for the API calls
    AtomicInteger pageNumber = new AtomicInteger();

    // Booleans used for infinite scrolling
    AtomicBoolean loadingMore = new AtomicBoolean(true);
    AtomicBoolean stopLoadingData = new AtomicBoolean(false);

    // Images Adapter
    CommentsAdapter mCommentsAdapter;

    // AsyncTask for downloading the comments
    FivePXBaseAsyncTask mLoadCommentsList;

    // AsyncTask for downloading the image details
    FivePXBaseAsyncTask mLoadImageDetailsList;

    // AsyncTask for liking an image
    FivePXBaseAsyncTask mLikeImage;

    // AsyncTask for submitting Comment
    FivePXBaseAsyncTask mPostCommentImage;

    // AsyncTask for favoriting an image
    FivePXBaseAsyncTask mFavoriteImage;

    LoginManager mLoginManager;

    private GoogleMap map;

    /*
     *  These Are used to determine what the login was requested for.
     * 
     *    Basically if you click "Like" and you are not logged in, then after logging in, the like will be submitted
     */

    LOGGING_REASON reason;

    public enum LOGGING_REASON {
        LIKE, FAVORITE, COMMENT,
    }

    private void getReusableViews(View rootView) {

        this.rootView = rootView;

        // Get ActionBar
        actionBar = getActivity().getActionBar();

        // Get Sliding Panel Layouts
        mSlidingPaneLayout = (SlidingUpPanelLayout) rootView.findViewById(R.id.sliding_layout);
        imageControlsLayout = (RelativeLayout) rootView.findViewById(R.id.image_controls);

        // Get the comments ListView
        commentsListView = (ListView) rootView.findViewById(R.id.comments_list);

        // Get the sliding Panel, buttons, ViewFlipper, and child layouts
        imageControlsLayout = (RelativeLayout) rootView.findViewById(R.id.image_controls);

        imageDetailFlipper = (ViewFlipper) rootView.findViewById(R.id.image_details_flipper);
        imageDetailsLayout = (RelativeLayout) rootView.findViewById(R.id.image_details);

        imageStats = (ImageButton) rootView.findViewById(R.id.image_stats);
        imageComments = (Button) rootView.findViewById(R.id.image_comments);
        imageLikes = (Button) rootView.findViewById(R.id.image_likes);
        imageFavorites = (Button) rootView.findViewById(R.id.image_favorites);

        submitComment = (ImageButton) rootView.findViewById(R.id.submit_comment_btn);

        // Get The login manager
        mLoginManager = LoginManager.getInstance(getActivity());

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        Log.d(TAG, "onCreateView");

        final View rootView = inflater.inflate(R.layout.fragment_five_px_image, container, false);

        getReusableViews(rootView);

        // Set the attributes for the custom ActionBar
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setDisplayShowCustomEnabled(true);
        actionBar.setDisplayShowTitleEnabled(false);

        // Set the placeholder until download finishes.
        actionBar.setIcon(R.drawable.ic_launcher);

        // get the ImageBean that was clicked
        Bundle bundle = this.getArguments();
        mFiveZeroZeroImageBean = (FiveZeroZeroImageBean) bundle.getParcelable(ARG_IMAGE_BEAN);

        // Inflate the custom action bar layout
        LayoutInflater inflator = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View actionView = inflator.inflate(R.layout.actionbar_five_px_image, null);

        // set the title and user name in the action bar
        TextView imageTitle = (TextView) actionView.findViewById(R.id.image_title);
        TextView imageuserName = (TextView) actionView.findViewById(R.id.image_username);

        imageTitle.setText(mFiveZeroZeroImageBean.getName());
        imageuserName.setText(mFiveZeroZeroImageBean.getUserBean().getUserName());

        actionBar.setCustomView(actionView);

        // get reference to userAccountLayout in the action bar
        userAccountLayout = (RelativeLayout) actionView.findViewById(R.id.image_account_layout);

        // Download the user image in Extra Small size. No Picasso for this image.
        mDownloadUserImage = new DownloadUserImage();
        mDownloadUserImage.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
                mFiveZeroZeroImageBean.getUserBean().getUserpicURL(USER_IMAGE_SIZE.LARGE));

        // Setup the Sliding Panel layout 
        mSlidingPaneLayout.setShadowDrawable(getResources().getDrawable(R.drawable.above_shadow));
        mSlidingPaneLayout.setAnchorPoint(0.2f);
        mSlidingPaneLayout.setDragView(imageControlsLayout);
        mSlidingPaneLayout.setEnableDragViewTouchEvents(true);

        // Download the Image and put it into a zoom-able and pan-able imageview. 
        ImageView mImageView = (ImageView) rootView.findViewById(R.id.image);

        // The MAGIC happens here!
        mAttacher = new PhotoViewAttacher(mImageView);

        Picasso.with(getActivity()) //
                .load(mFiveZeroZeroImageBean.getImageUrl(IMAGE_SIZE.ORIGINAL))
                //.placeholder(image.getDrawable()) // Use the smaller image while downloading the higher resolution image 
                .error(android.R.drawable.stat_notify_error) // The error image
                .into(mImageView, new Callback() {
                    @Override
                    public void onError() {
                    }

                    // When finished loading, update the attacher
                    @Override
                    public void onSuccess() {
                        mAttacher.update();
                    }
                });

        //mAttacher.setOnPhotoTapListener(new PhotoTapListener());

        // Setup the comments ListView
        mCommentsAdapter = new CommentsAdapter(getActivity(), mFiveZeroZeroImageBean.getCommentBeans());
        commentsListView.setAdapter(mCommentsAdapter);

        // set the comment count
        imageComments.setText(Integer.toString(mFiveZeroZeroImageBean.getCommentsCount()));
        imageLikes.setText(Integer.toString(mFiveZeroZeroImageBean.getVotesCount()));
        imageFavorites.setText(Integer.toString(mFiveZeroZeroImageBean.getFavoritesCount()));

        // get the last page number (we want to add pages in reverse order (newest first)
        pageNumber.set((int) Math.ceil(mFiveZeroZeroImageBean.getCommentsCount() / 20.0));

        mFiveZeroZeroImageAPIBuilder = new FiveZeroZeroImageAPIBuilder().setPageNum(pageNumber.get());

        mLoadCommentsList = new LoadCommentsList(getActivity(), mFiveZeroZeroImageAPIBuilder, mLoginManager,
                mFiveZeroZeroImageBean, loadingMore, stopLoadingData, pageNumber);
        mLoadCommentsList.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

        mLoadImageDetailsList = new LoadImageDetailsList(getActivity(), mFiveZeroZeroImageAPIBuilder, mLoginManager,
                mFiveZeroZeroImageBean);
        mLoadImageDetailsList.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

        return rootView;
    }

    @Override
    public void onPause() {
        super.onPause();

        Log.d(TAG, "onPause");

        // Stop all background threads (if running)
        if (mDownloadUserImage != null) {
            mDownloadUserImage.cancel(true);
        }

        if (mLoadCommentsList != null) {
            mLoadCommentsList.cancel(true);
        }

        if (mLikeImage != null) {
            mLikeImage.cancel(true);
        }

        if (mFavoriteImage != null) {
            mFavoriteImage.cancel(true);
        }

        if (mPostCommentImage != null) {
            mPostCommentImage.cancel(true);
        }

        //Restore the original actionbar settings
        actionBar.setIcon(R.drawable.ic_launcher);
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setDisplayShowCustomEnabled(false);
        actionBar.setDisplayShowTitleEnabled(true);

        // Remove all weak refrences to listeners
        mSlidingPaneLayout.setPanelSlideListener(null);
        userAccountLayout.setOnClickListener(null);
        imageStats.setOnClickListener(null);
        imageComments.setOnClickListener(null);
        imageLikes.setOnClickListener(null);
        imageFavorites.setOnClickListener(null);
        imageControlsLayout.setOnClickListener(null);
        commentsListView.setOnScrollListener(null);
        submitComment.setOnClickListener(null);
        mAttacher.setOnPhotoTapListener(null);

    }

    @Override
    public void onResume() {
        Log.d(TAG, "onResume");
        super.onResume();

        //Restore the original actionbar settings
        actionBar.setIcon(R.drawable.ic_launcher);
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setDisplayShowCustomEnabled(true);
        actionBar.setDisplayShowTitleEnabled(false);

        BitmapDrawable icon = new BitmapDrawable(getResources(), actionBarUserImage);

        actionBar.setIcon(icon);

        // Remove Listeners
        mSlidingPaneLayout.setPanelSlideListener(new slideUpLayoutListener());
        userAccountLayout.setOnClickListener(new userAccountClickListener());
        imageStats.setOnClickListener(new ImageControlsListener());
        imageComments.setOnClickListener(new ImageControlsListener());
        imageLikes.setOnClickListener(new ImageControlsListener());
        imageFavorites.setOnClickListener(new ImageControlsListener());
        imageControlsLayout.setOnClickListener(new ImageControlsListener());
        commentsListView.setOnScrollListener(new commentScrollListener());
        submitComment.setOnClickListener(new submitCommentListener());
        mAttacher.setOnPhotoTapListener(new PhotoTapListener());

    }

    private void loadImageDetails(View rootView) {

        TextView ratingContent = (TextView) rootView.findViewById(R.id.rating);
        ratingContent.setText("" + (mFiveZeroZeroImageBean.getRating()));

        TextView highestRatingContent = (TextView) rootView.findViewById(R.id.highest_rating);
        highestRatingContent.setText("" + mFiveZeroZeroImageBean.getHighestRating());

        TextView viewsContent = (TextView) rootView.findViewById(R.id.views);
        viewsContent.setText(Integer.toString(mFiveZeroZeroImageBean.getTimesViewed()));

        TextView descriptionContent = (TextView) rootView.findViewById(R.id.description);
        descriptionContent.setText(mFiveZeroZeroImageBean.getDescription());

        TextView cameraContent = (TextView) rootView.findViewById(R.id.camera_content);
        cameraContent.setText(mFiveZeroZeroImageBean.getCamera());

        TextView focalLengthContent = (TextView) rootView.findViewById(R.id.focal_length_content);
        focalLengthContent.setText(mFiveZeroZeroImageBean.getFocalLength());

        TextView shutterSpeedContent = (TextView) rootView.findViewById(R.id.shutter_speed_content);
        shutterSpeedContent.setText(mFiveZeroZeroImageBean.getShutterSpeed());

        TextView isoContent = (TextView) rootView.findViewById(R.id.iso_content);
        isoContent.setText(mFiveZeroZeroImageBean.getIso());

        TextView categotyContent = (TextView) rootView.findViewById(R.id.category_content);
        categotyContent.setText(Category.forValue(mFiveZeroZeroImageBean.getCategory()).toString());

        TextView apertureContent = (TextView) rootView.findViewById(R.id.aperture_content);
        apertureContent.setText(mFiveZeroZeroImageBean.getAperture());

        TextView uploadedAtContent = (TextView) rootView.findViewById(R.id.uploaded_content);
        uploadedAtContent.setText(mFiveZeroZeroImageBean.getCreatedAt());

        TextView takenAtoContent = (TextView) rootView.findViewById(R.id.taken_content);
        takenAtoContent.setText(mFiveZeroZeroImageBean.getTakenAt());

        TextView licenseContent = (TextView) rootView.findViewById(R.id.license_content);
        licenseContent.setText(License.forValue(mFiveZeroZeroImageBean.getLicenseType()).toString());

        TextView locationContent = (TextView) rootView.findViewById(R.id.location_content);
        if (mFiveZeroZeroImageBean.getLocation() != null) {
            locationContent.setText(mFiveZeroZeroImageBean.getLocation());
        } else {
            locationContent.setText(null);
            locationContent.setVisibility(View.GONE);
        }

        if (mFiveZeroZeroImageBean.getLatitude() != null && mFiveZeroZeroImageBean.getLatitude() != null) {

            setupMap(mFiveZeroZeroImageBean.getLatitude(), mFiveZeroZeroImageBean.getLongitude(),
                    mFiveZeroZeroImageBean.getName(), mFiveZeroZeroImageBean.getDescription());
        } else {
            View mapView = rootView.findViewById(R.id.map);
            mapView.setVisibility(View.GONE);
        }

        // when logged in - highlight images that are "Liked" (voted)
        if (mFiveZeroZeroImageBean.isVoted()) {
            imageLikes.setBackgroundResource(R.drawable.ic_background_like);
        } else {
            imageLikes.setBackgroundResource(R.drawable.ic_background);
        }

        // when logged in - highlight images that are "favorited"
        if (mFiveZeroZeroImageBean.isFavorited()) {
            imageFavorites.setBackgroundResource(R.drawable.ic_background_fav);
        } else {
            imageFavorites.setBackgroundResource(R.drawable.ic_background);
        }

    }

    private void setupMap(String latitude, String longitude, String imageName, String imageDescription) {

        map = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

        // get references to transparent image and ScrollView
        final ScrollView mainScrollView = (ScrollView) rootView.findViewById(R.id.image_details_scrollView);
        ImageView transparentImageView = (ImageView) rootView.findViewById(R.id.transparent_image);

        // allows scrolling on the map independently of the scrollView
        transparentImageView.setOnTouchListener(new View.OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();

                switch (action) {
                case MotionEvent.ACTION_DOWN:
                    // Disallow ScrollView to intercept touch events.
                    mainScrollView.requestDisallowInterceptTouchEvent(true);
                    // Disable touch on transparent view
                    return false;

                case MotionEvent.ACTION_UP:
                    // Allow ScrollView to intercept touch events.
                    mainScrollView.requestDisallowInterceptTouchEvent(false);
                    return true;

                case MotionEvent.ACTION_MOVE:
                    mainScrollView.requestDisallowInterceptTouchEvent(true);
                    return false;

                default:
                    return true;
                }
            }

        });

        LatLng imageLocation = new LatLng(Double.valueOf(latitude), Double.valueOf(longitude));
        LatLng mapCenter = new LatLng(Double.valueOf(latitude) - 1, Double.valueOf(longitude));

        map.addMarker(new MarkerOptions().position(imageLocation).snippet(imageDescription).title(imageName));

        // Move the camera instantly to position with a zoom of 6.
        map.moveCamera(CameraUpdateFactory.newLatLngZoom(mapCenter, 6));

    }

    public class userAccountClickListener implements OnClickListener {
        @Override
        public void onClick(View v) {
            Toast.makeText(getActivity(),
                    "Opening User Account for user: " + mFiveZeroZeroImageBean.getUserBean().getUserName(),
                    Toast.LENGTH_SHORT).show();
        }

    }

    public class commentScrollListener implements OnScrollListener {

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

            int lastInScreen = firstVisibleItem + visibleItemCount;

            // start loading new items when there are only 3 rows left, and nothing is being loaded already
            if ((lastInScreen == (totalItemCount - 3)) && !(loadingMore.get())) {

                Log.d(TAG, "stopLoadingData = " + stopLoadingData.get());

                //this could be used for finite scroll. ie. a set number of pages/images
                if (stopLoadingData.get() == false) {

                    // Create the API call
                    mFiveZeroZeroImageAPIBuilder.setPageNum(pageNumber.get());

                    mLoadCommentsList = new LoadCommentsList(getActivity(), mFiveZeroZeroImageAPIBuilder,
                            mLoginManager, mFiveZeroZeroImageBean, loadingMore, stopLoadingData, pageNumber);
                    mLoadCommentsList.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                }
            }
        }

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        }

    }

    public class submitCommentListener implements OnClickListener {
        @Override
        public void onClick(View v) {
            submitComment();
        }
    }

    private void submitComment() {
        // TODO Auto-generated method stub

        submitCommentBody = (EditText) rootView.findViewById(R.id.submit_comment_body);

        String commentBody = submitCommentBody.getText().toString();

        if (mLoginManager.isLoggedIn()) {

            mPostCommentImage = new PostCommentImage(getActivity(), mFiveZeroZeroImageAPIBuilder, mLoginManager,
                    mFiveZeroZeroImageBean, mCommentsAdapter, commentBody, submitCommentBody);
            mPostCommentImage.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

        } else {
            reason = LOGGING_REASON.COMMENT;
            login();
        }

    }

    public class ImageControlsListener implements OnClickListener {
        @Override
        public void onClick(View v) {
            if (v == imageStats) {
                if (!mSlidingPaneLayout.isExpanded()) { // Closed, then set and open
                    imageDetailFlipper.setDisplayedChild(0);
                    mSlidingPaneLayout.expandPane();
                } else if (mSlidingPaneLayout.isExpanded() && imageDetailFlipper.getDisplayedChild() == 0) { // Open and already set, then close
                    mSlidingPaneLayout.collapsePane();
                } else { // open and not set, then set
                    imageDetailFlipper.setInAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in));
                    imageDetailFlipper
                            .setOutAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_out));
                    imageDetailFlipper.setDisplayedChild(0);
                }
            } else if (v == imageComments) {
                if (!mSlidingPaneLayout.isExpanded()) { // Closed, then set and open
                    imageDetailFlipper.setDisplayedChild(1);
                    mSlidingPaneLayout.expandPane();
                } else if (mSlidingPaneLayout.isExpanded() && imageDetailFlipper.getDisplayedChild() == 1) { // Open and already set, then close
                    mSlidingPaneLayout.collapsePane();
                } else { // open and not set, then set
                    imageDetailFlipper.setInAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_in));
                    imageDetailFlipper
                            .setOutAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.fade_out));
                    imageDetailFlipper.setDisplayedChild(1);
                }
            } else if (v == imageLikes) {
                // Like button
                if (mLoginManager.isLoggedIn()) {

                    processLike();
                } else {
                    reason = LOGGING_REASON.LIKE;
                    login();
                }
                // go to login activity()

            } else if (v == imageFavorites) {
                // Favorite button
                if (mLoginManager.isLoggedIn()) {

                    processFavorite();
                } else {
                    reason = LOGGING_REASON.FAVORITE;
                    login();
                }

            } else if (v == imageControlsLayout) {
                if (!mSlidingPaneLayout.isExpanded()) {
                    mSlidingPaneLayout.expandPane();
                } else {
                    mSlidingPaneLayout.collapsePane();
                }
            }
            imageDetailFlipper.setInAnimation(null);
            imageDetailFlipper.setOutAnimation(null);
        }

    }

    public class slideUpLayoutListener implements PanelSlideListener {

        @Override
        public void onPanelSlide(View panel, float slideOffset) {

            // Dyamically adjust alpha on the Sliding panel background (could do the same for the rest of panel in future
            int alpha = (int) (120 + (1 - slideOffset) * 100);
            int color = Color.argb(alpha, 0, 0, 0);
            imageControlsLayout.setBackgroundColor(color);

            imageDetailFlipper.setAlpha(0.5f + ((1 - slideOffset) * 0.5f));
        }

        @Override
        public void onPanelExpanded(View panel) {
        }

        @Override
        public void onPanelCollapsed(View panel) {
        }

        @Override
        public void onPanelAnchored(View panel) {
        }
    }

    public class PhotoTapListener implements OnPhotoTapListener {

        @Override
        public void onPhotoTap(View view, float x, float y) {
            showOrHideActionBar();
        }
    }

    private void showOrHideActionBar() {

        Log.d(TAG, "" + rootView.getSystemUiVisibility());

        if (rootView.getSystemUiVisibility() == View.SYSTEM_UI_FLAG_VISIBLE) {
            rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
        } else {
            rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
        }
    }

    @Override
    public boolean onBackPressed() {
        Log.d(TAG, "clicked back");

        if (mSlidingPaneLayout.isExpanded()) {
            mSlidingPaneLayout.collapsePane();
            return false;
        }

        if (!getActivity().getActionBar().isShowing()) {
            showOrHideActionBar();
            return false;
        }

        return true;
    }

    private void processLike() {
        mLikeImage = new LikeImage(getActivity(), mFiveZeroZeroImageAPIBuilder, mLoginManager,
                mFiveZeroZeroImageBean);
        mLikeImage.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    private void processFavorite() {
        mFavoriteImage = new FavoriteImage(getActivity(), mFiveZeroZeroImageAPIBuilder, mLoginManager,
                mFiveZeroZeroImageBean);
        mFavoriteImage.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

    }

    public class LoadImageDetailsList extends FivePXBaseImageAsyncTask {

        LoadImageDetailsList(Context mContext, FiveZeroZeroImageAPIBuilder mFiveZeroZeroImageAPIBuilder,
                LoginManager mLoginManager, FiveZeroZeroImageBean mFiveZeroZeroImageBean) {

            super(mContext, mFiveZeroZeroImageAPIBuilder, mLoginManager, mFiveZeroZeroImageBean);
        }

        @Override
        protected JSONObject callAPI() {

            return api.get(mFiveZeroZeroImageAPIBuilder.getImageDetailsCall(mFiveZeroZeroImageBean.getId()));
        }

        @Override
        protected void parseReturn(JSONObject resObj) throws JSONException {
            mFiveZeroZeroImageBean.parseJSONObject(resObj.getJSONObject("photo"));
        }

        @Override
        protected void updateView() {
            loadImageDetails(rootView);
        }

    }

    public class LikeImage extends FivePXBaseImageAsyncTask {

        LikeImage(Context mContext, FiveZeroZeroImageAPIBuilder mFiveZeroZeroImageAPIBuilder,
                LoginManager mLoginManager, FiveZeroZeroImageBean mFiveZeroZeroImageBean) {

            super(mContext, mFiveZeroZeroImageAPIBuilder, mLoginManager, mFiveZeroZeroImageBean);
        }

        @Override
        protected JSONObject callAPI() {

            // Set vote/like status to opposite it's current value
            mFiveZeroZeroImageAPIBuilder = mFiveZeroZeroImageAPIBuilder.setVote(!mFiveZeroZeroImageBean.isVoted());

            Log.d(TAG, mFiveZeroZeroImageAPIBuilder.postImageLike(mFiveZeroZeroImageBean.getId()));

            return api.get(mFiveZeroZeroImageAPIBuilder.getImageDetailsCall(mFiveZeroZeroImageBean.getId()));
        }

        @Override
        protected void parseReturn(JSONObject resObj) throws JSONException {
            mFiveZeroZeroImageBean.setVoted(!mFiveZeroZeroImageBean.isVoted());
        }

        @Override
        protected void updateView() {
            loadImageDetails(rootView);
        }

        @Override
        protected void ShowErrToast() {
            Toast.makeText(getActivity(),
                    "Unable to " + ((mFiveZeroZeroImageBean.isVoted()) ? "unlike" : "like") + ": "
                            + ((mFiveZeroZeroImageBean.isVoted()) ? "Have you completed your profile?"
                                    : "Is this your own image?"),
                    Toast.LENGTH_SHORT).show();
        }

        @Override
        protected boolean LoginRequired() {
            return true;
        }

        @Override
        protected boolean hasErrToast() {
            return true;
        }
    }

    public class FavoriteImage extends FivePXBaseImageAsyncTask {

        FavoriteImage(Context mContext, FiveZeroZeroImageAPIBuilder mFiveZeroZeroImageAPIBuilder,
                LoginManager mLoginManager, FiveZeroZeroImageBean mFiveZeroZeroImageBean) {

            super(mContext, mFiveZeroZeroImageAPIBuilder, mLoginManager, mFiveZeroZeroImageBean);
        }

        @Override
        protected JSONObject callAPI() {

            Log.d(TAG, mFiveZeroZeroImageAPIBuilder.postImageFavorite(mFiveZeroZeroImageBean.getId()));

            JSONObject resObj = null;

            if (!mFiveZeroZeroImageBean.isFavorited()) {
                //Post Favorite if not already in favorite list
                resObj = api.post(mFiveZeroZeroImageAPIBuilder.postImageFavorite(mFiveZeroZeroImageBean.getId()),
                        new ArrayList<NameValuePair>());
            } else {
                //Delete Favorite if already in favorite list
                resObj = api.delete(mFiveZeroZeroImageAPIBuilder.postImageFavorite(mFiveZeroZeroImageBean.getId()),
                        new ArrayList<NameValuePair>());
            }
            return resObj;
        }

        @Override
        protected void parseReturn(JSONObject resObj) throws JSONException {
            mFiveZeroZeroImageBean.setFavorited(!mFiveZeroZeroImageBean.isFavorited());
        }

        @Override
        protected void updateView() {
            loadImageDetails(rootView);
        }

        @Override
        protected void ShowErrToast() {
            Toast.makeText(getActivity(),
                    "Unable to " + ((mFiveZeroZeroImageBean.isVoted()) ? "unfavorite" : "favorite") + ": "
                            + ((mFiveZeroZeroImageBean.isVoted()) ? "Have you completed your profile?"
                                    : "Is this your own image?"),
                    Toast.LENGTH_SHORT).show();
        }

        @Override
        protected boolean LoginRequired() {
            return true;
        }

        @Override
        protected boolean hasErrToast() {
            return true;
        }
    }

    public class PostCommentImage extends FivePXBaseImageAsyncTask {

        CommentsAdapter mCommentsAdapter;
        String commentBody;

        EditText submitCommentBody;

        PostCommentImage(Context mContext, FiveZeroZeroImageAPIBuilder mFiveZeroZeroImageAPIBuilder,
                LoginManager mLoginManager, FiveZeroZeroImageBean mFiveZeroZeroImageBean,
                CommentsAdapter mCommentsAdapter, String commentBody, EditText submitCommentBody) {

            super(mContext, mFiveZeroZeroImageAPIBuilder, mLoginManager, mFiveZeroZeroImageBean);

            this.mCommentsAdapter = mCommentsAdapter;
            this.commentBody = commentBody;
            this.submitCommentBody = submitCommentBody;
        }

        @Override
        protected JSONObject callAPI() {
            //verify that commentBody exists
            if (commentBody != null && !commentBody.equalsIgnoreCase("")) {
                ArrayList<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
                nameValuePair.add(new BasicNameValuePair("body", commentBody));

                Log.d(TAG, mFiveZeroZeroImageAPIBuilder.postSubmitCommentCall(mFiveZeroZeroImageBean.getId()));

                return api.post(mFiveZeroZeroImageAPIBuilder.postSubmitCommentCall(mFiveZeroZeroImageBean.getId()),
                        nameValuePair);
            }
            // if comment Body is null or empty return null, this will cause onPostExecute to show error
            return null;
        }

        @Override
        protected void parseReturn(JSONObject resObj) throws JSONException {

            JSONObject comment = resObj.getJSONObject("comment");

            FiveZeroZeroCommentBean commentBean = new FiveZeroZeroCommentBean();

            commentBean.parseJSONObject(comment);

            mFiveZeroZeroImageBean.addCommentBean(commentBean, 0);
        }

        @Override
        protected void updateView() {
            mCommentsAdapter.notifyDataSetChanged();

            clearComments(submitCommentBody);
            hideKeybard(submitCommentBody);
        }

        @Override
        protected void ShowErrToast() {
            Toast.makeText(getActivity(), "Error while posting comment", Toast.LENGTH_SHORT).show();

            clearComments(submitCommentBody);
            hideKeybard(submitCommentBody);
        }

        @Override
        protected boolean LoginRequired() {
            return true;
        }

        @Override
        protected boolean hasErrToast() {
            return true;
        }

        private void clearComments(EditText mEditText) {
            // empty the edit text field
            mEditText.setText("");
        }

        private void hideKeybard(EditText mEditText) {
            // close the keyboard
            InputMethodManager imm = (InputMethodManager) getActivity()
                    .getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
        }
    }

    public class LoadCommentsList extends FivePXBaseImageAsyncTask {

        AtomicBoolean loadingMore;
        AtomicBoolean stopLoadingData;
        AtomicInteger pageNumber;

        /* Comments are downloaded at the same time (up to 20 at a time)
         * but need to be processed and loaded to the view 1 at a time
         * so we use publishProgress and onProgressUpdate instead of updateView 
         * to update the view.
         * 
         * We use comments JSONObject to store all the comments and allow 
         * updateView to make decisions based on the number of comments
         */

        private JSONArray comments;

        /*
         * totalPages and currentPage are used to determine the position of the current comment 
         * in the list of all comments
         */
        private int totalPages, currentPage;

        LoadCommentsList(Context mContext, FiveZeroZeroImageAPIBuilder mFiveZeroZeroImageAPIBuilder,
                LoginManager mLoginManager, FiveZeroZeroImageBean mFiveZeroZeroImageBean, AtomicBoolean loadingMore,
                AtomicBoolean stopLoadingData, AtomicInteger pageNumber) {

            super(mContext, mFiveZeroZeroImageAPIBuilder, mLoginManager, mFiveZeroZeroImageBean);

            this.loadingMore = loadingMore;
            this.stopLoadingData = stopLoadingData;
            this.pageNumber = pageNumber;
        }

        @Override
        protected void onPreExecute() {
            //Log.d(TAG, "This is running");
            loadingMore.set(true);
            super.onPreExecute();
        }

        @Override
        protected JSONObject callAPI() {

            Log.d(TAG, mFiveZeroZeroImageAPIBuilder.getCommentsCall(mFiveZeroZeroImageBean.getId()));

            return api.get(mFiveZeroZeroImageAPIBuilder.getCommentsCall(mFiveZeroZeroImageBean.getId()));
        }

        @Override
        protected void parseReturn(JSONObject resObj) throws JSONException {
            comments = resObj.getJSONArray("comments");

            totalPages = resObj.getInt("total_pages");
            currentPage = resObj.getInt("current_page");

            for (int i = comments.length() - 1; i >= 0; i--) {
                FiveZeroZeroCommentBean commentBean = new FiveZeroZeroCommentBean();

                commentBean.parseJSONObject(comments.getJSONObject(i));

                mFiveZeroZeroImageBean.addCommentBean(commentBean);

                publishProgress();
            }
        }

        protected void onProgressUpdate(Void... progress) {
            mCommentsAdapter.notifyDataSetChanged();
        }

        @Override
        protected void updateView() {
            // We use publishProgress and onProgressUpdate to update the UI so no need for updateView here
        }

        @Override
        protected void postProcess() {
            Log.d(TAG, "Running postProcess");

            loadingMore.set(false);

            pageNumber.decrementAndGet();

            if (pageNumber.get() == 0) {
                // stop loading if last item in page
                stopLoadingData.set(true);
            }

            // If there is more than 1 page, and the number in this current page is small (under 10), and we are on the last page (aka, first run) then load another page
            // For example, if there are a total of 43 comments: if we load the 3 from the last page, the onScrollListener will never be called,
            // so we load another page with 20 more comments
            if (totalPages > 1 && comments.length() < 10 && currentPage >= totalPages) {

                mFiveZeroZeroImageAPIBuilder.setPageNum(pageNumber.get());

                mLoadCommentsList = new LoadCommentsList(getActivity(), mFiveZeroZeroImageAPIBuilder, mLoginManager,
                        mFiveZeroZeroImageBean, loadingMore, stopLoadingData, pageNumber);
                mLoadCommentsList.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
            }
        }

        @Override
        protected boolean hasPostProcessing() {
            return true;
        }

    }

    public class DownloadUserImage extends AsyncTask<String, Void, Bitmap> {

        @Override
        protected Bitmap doInBackground(String... urls) {
            return download_Image(urls[0]);
        }

        @Override
        protected void onPostExecute(Bitmap result) {

            if (result != null) {
                Log.d(TAG, "image downloaded successfully");
                actionBarUserImage = result;

                Resources res = getResources();
                BitmapDrawable icon = new BitmapDrawable(res, result);

                actionBar.setIcon(icon);
            } else {
                actionBar.setIcon(R.drawable.ic_launcher);
                Log.e(TAG, "failed to download image for user");

            }
        }

        private Bitmap download_Image(String url) {
            //---------------------------------------------------
            Bitmap bm = null;
            try {
                URL aURL = new URL(url);
                URLConnection conn = aURL.openConnection();
                conn.connect();
                InputStream is = conn.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
                bm = BitmapFactory.decodeStream(bis);
                bis.close();
                is.close();
            } catch (IOException e) {
                Log.e("Hub", "Error getting the image from server : " + e.getMessage().toString());
            }
            return bm;

        }
    }

    public void login() {
        Intent i = new Intent(getActivity(), LoginActivity.class);
        startActivityForResult(i, 1);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == 1) {

            if (resultCode == Activity.RESULT_OK) {
                //boolean result=data.getBooleanExtra("result", false);     

                if (getActivity() instanceof MainActivity) {
                    ((MainActivity) getActivity()).onSuccessLogin();
                }

                if (reason == LOGGING_REASON.FAVORITE) {

                    processFavorite();
                }

                if (reason == LOGGING_REASON.LIKE) {

                    processLike();
                }

                if (reason == LOGGING_REASON.COMMENT) {

                    submitComment();
                }

                // The comment count, Like count, or the Favorite count (and color) will change.
                mLoadImageDetailsList = new LoadImageDetailsList(getActivity(), mFiveZeroZeroImageAPIBuilder,
                        mLoginManager, mFiveZeroZeroImageBean);
                mLoadImageDetailsList.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
            }
            if (resultCode == Activity.RESULT_CANCELED) {
                // Do Nothing, no need to process whatever triggered the login task
            }
        }
    }

    public void logout() {

        // when logged in - highlight images that are "Liked" (voted)
        imageLikes.setBackgroundResource(R.drawable.ic_background);

        imageFavorites.setBackgroundResource(R.drawable.ic_background);

    }

    /* (non-Javadoc)
     * @see android.app.Fragment#onDestroyView()
     */
    @Override
    public void onDestroyView() {
        Log.d(TAG, "onDestroyView");
        super.onDestroyView();

        Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
        FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
        ft.remove(fragment);
        ft.commit();
    }

    /* (non-Javadoc)
     * @see android.app.Fragment#onDestroy()
     */
    @Override
    public void onDestroy() {
        Log.d(TAG, "onDestroy");
        super.onDestroy();

        // Need to call clean-up
        mAttacher.cleanup();
    }

    /* (non-Javadoc)
     * @see android.app.Fragment#onActivityCreated(android.os.Bundle)
     */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        Log.d(TAG, "onActivityCreated");
        super.onActivityCreated(savedInstanceState);
    }

    /* (non-Javadoc)
     * @see android.app.Fragment#onAttach(android.app.Activity)
     */
    @Override
    public void onAttach(Activity activity) {
        Log.d(TAG, "onAttach");
        super.onAttach(activity);
    }

    /* (non-Javadoc)
     * @see android.app.Fragment#onCreate(android.os.Bundle)
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate");
        super.onCreate(savedInstanceState);
    }

    /* (non-Javadoc)
     * @see android.app.Fragment#onDetach()
     */
    @Override
    public void onDetach() {
        Log.d(TAG, "onDetach");
        super.onDetach();
    }

    /* (non-Javadoc)
     * @see android.app.Fragment#onStart()
     */
    @Override
    public void onStart() {
        Log.d(TAG, "onStart");
        super.onStart();
    }

    /* (non-Javadoc)
     * @see android.app.Fragment#onStop()
     */
    @Override
    public void onStop() {
        Log.d(TAG, "onStop");
        super.onStop();
    }

}