/*
* Copyright 2014 Artem Chikin
* Copyright 2014 Artem Herasymchuk
* Copyright 2014 Tom Krywitsky
* Copyright 2014 Henry Pabst
* Copyright 2014 Bradley Simons
*
* 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 ca.ualberta.cmput301w14t08.geochan.fragments;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import ca.ualberta.cmput301w14t08.geochan.R;
import ca.ualberta.cmput301w14t08.geochan.helpers.ConnectivityHelper;
import ca.ualberta.cmput301w14t08.geochan.helpers.ErrorDialog;
import ca.ualberta.cmput301w14t08.geochan.helpers.ImageHelper;
import ca.ualberta.cmput301w14t08.geochan.helpers.LocationListenerService;
import ca.ualberta.cmput301w14t08.geochan.helpers.SortUtil;
import ca.ualberta.cmput301w14t08.geochan.helpers.Toaster;
import ca.ualberta.cmput301w14t08.geochan.managers.CacheManager;
import ca.ualberta.cmput301w14t08.geochan.managers.PreferencesManager;
import ca.ualberta.cmput301w14t08.geochan.managers.ThreadManager;
import ca.ualberta.cmput301w14t08.geochan.models.Comment;
import ca.ualberta.cmput301w14t08.geochan.models.FavouritesLog;
import ca.ualberta.cmput301w14t08.geochan.models.GeoLocation;
import ca.ualberta.cmput301w14t08.geochan.models.ThreadComment;
import ca.ualberta.cmput301w14t08.geochan.models.ThreadList;
/**
* Responsible for the UI fragment that allows a user to post a new thread.
*
* @author Artem Chikin
*/
public class PostFragment extends Fragment {
public static final int MAX_BITMAP_DIMENSIONS = 900;
private LocationListenerService locationListenerService;
private GeoLocation geoLocation;
private Bitmap image = null;
private Bitmap imageThumb = null;
private File imageFile = null;
private ThreadComment thread = null;
private Comment commentToReplyTo = null;
/**
* Initializes several of the member variables used
* by PostFragment.
* @param savedInstanceState The previously saved state of the fragment.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationListenerService = new LocationListenerService(getActivity());
locationListenerService.startListening();
Bundle args = getArguments();
if (args.getLong("id") != -1) {
commentToReplyTo = (Comment) args.getParcelable("cmt");
boolean fromFavs = args.getBoolean("fromFavs");
if (fromFavs) {
FavouritesLog log = FavouritesLog.getInstance(getActivity());
thread = log.getThreads().get((int) args.getLong("id"));
} else {
thread = ThreadList.getThreads().get((int) args.getLong("id"));
}
}
}
/**
* Set up the fragment's UI.
*
* @param inflater The LayoutInflater used to inflate the fragment's UI.
* @param container The parent View that the fragment's UI is attached to.
* @param savedInstanceState The previously saved state of the fragment.
* @return The View for the fragment's UI.
*
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
setHasOptionsMenu(false);
if (thread == null) {
return inflater.inflate(R.layout.fragment_post_thread, container, false);
} else {
return inflater.inflate(R.layout.fragment_post_comment, container, false);
}
}
/**
* Initializes some UI elements if the user is posting a reply rather than a new ThreadComment.
*/
@Override
public void onStart() {
super.onStart();
if (commentToReplyTo != null) {
TextView replyTo = (TextView) getActivity().findViewById(R.id.comment_replyingTo);
TextView bodyReplyTo = (TextView) getActivity().findViewById(R.id.reply_to_body);
bodyReplyTo.setMovementMethod(new ScrollingMovementMethod());
bodyReplyTo.setText(commentToReplyTo.getTextPost());
replyTo.setText(commentToReplyTo.getUser() + " says:");
}
}
/**
* Resumes the fragment, updating the location and textview states accordingly.
*/
@Override
public void onResume() {
super.onResume();
Bundle args = getArguments();
if (args != null) {
if (args.containsKey("LATITUDE") && args.containsKey("LONGITUDE")) {
Button locButton = (Button) getActivity().findViewById(R.id.location_button);
if (args.getString("LocationType") == "CURRENT_LOCATION") {
locButton.setText("Location: Set");
} else {
Double lat = args.getDouble("LATITUDE");
Double lon = args.getDouble("LONGITUDE");
geoLocation = new GeoLocation(lat, lon);
String locationDescription = args.getString("locationDescription");
geoLocation.setLocationDescription(locationDescription);
locButton.setText("Location: Set");
}
}
if (args.containsKey("IMAGE_THUMB") && args.containsKey("IMAGE_FULL")) {
imageThumb = args.getParcelable("IMAGE_THUMB");
image = args.getParcelable("IMAGE_FULL");
}
}
}
/**
* onClick method for the post button. Extracts the textView information,
* creates the threadComment object and posts it to the server.
*
* @param view
* The post button in the PostThreadFragment.
*/
public void post(View view) {
if (geoLocation == null) {
geoLocation = new GeoLocation(locationListenerService);
}
if (geoLocation.getLocation() == null) {
ErrorDialog.show(getActivity(), "Could not retrieve location. Please specify a custom location.");
return;
}
if (view.getId() == R.id.post_button) {
String title = null;
EditText editTitle = null;
EditText editComment = (EditText) this.getView().findViewById(R.id.commentBody);
ThreadComment threadComment = null;
String comment = editComment.getText().toString();
if (thread == null) {
editTitle = (EditText) this.getView().findViewById(R.id.titlePrompt);
title = editTitle.getText().toString();
}
if (title != null && title.equals("")) {
ErrorDialog.show(getActivity(), "Title can not be left blank.");
} else {
Comment newComment = new Comment(comment, image, geoLocation, commentToReplyTo);
if (commentToReplyTo != null) {
Comment c = thread.findCommentById(thread.getBodyComment(),
commentToReplyTo.getId());
c.addChild(newComment);
int tag = PreferencesManager.getInstance().getCommentSort();
SortUtil.sortComments(tag, thread.getBodyComment().getChildren());
} else {
threadComment = new ThreadComment(newComment, title);
CacheManager.getInstance().serializeThreadList(ThreadList.getThreads());
int tag = PreferencesManager.getInstance().getThreadSort();
SortUtil.sortThreads(tag, ThreadList.getThreads());
}
if (!ConnectivityHelper.getInstance().isConnected()) {
CacheManager cacheManager = CacheManager.getInstance();
if (title == null) {
cacheManager.addCommentToQueue(newComment);
} else {
cacheManager.addThreadCommentToQueue(threadComment);
}
Toaster.toastShort("No internet connection detected. Your post will automatically send on connection.");
} else {
ProgressDialog dialog = new ProgressDialog(getActivity());
dialog.setMessage("Getting Location Data");
ThreadManager.startPost(newComment, title, geoLocation, dialog, false);
}
InputMethodManager inputManager = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
this.getFragmentManager().popBackStackImmediate();
}
}
}
/**
* Displays dialog and either launches camera or gallery
*
* @param view
* the AttachPhoto button in postThreadFragment.
*/
public void attachImage(View view) {
if (view.getId() == R.id.attach_image_button) {
AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity());
dialog.setTitle(R.string.attach_image_title);
dialog.setMessage(R.string.attach_image_dialog);
dialog.setPositiveButton("Gallery", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
FavouritesFragment favFrag = (FavouritesFragment) getParentFragment();
boolean fromFav;
if(favFrag != null){
fromFav = true;
} else {
fromFav = false;
}
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
if(fromFav == true){
arg0.dismiss();
getParentFragment().startActivityForResult(Intent.createChooser(intent, "Test"),
ImageHelper.REQUEST_GALLERY);
} else {
arg0.dismiss();
startActivityForResult(Intent.createChooser(intent, "Test"),
ImageHelper.REQUEST_GALLERY);
}
}
});
dialog.setNegativeButton("Camera", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
FavouritesFragment favFrag = (FavouritesFragment) getParentFragment();
boolean fromFav;
if(favFrag != null){
fromFav = true;
} else {
fromFav = false;
}
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
try {
imageFile = ImageHelper.createImageFile();
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile));
if(fromFav == true){
arg0.dismiss();
getParentFragment().startActivityForResult(Intent.createChooser(intent, "Test"),
ImageHelper.REQUEST_CAMERA);
} else {
arg0.dismiss();
startActivityForResult(Intent.createChooser(intent, "Test"),
ImageHelper.REQUEST_CAMERA);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
dialog.show();
}
}
/**
* Handles the return from the camera activity
*
* @param requestCode Type of activity requested
* @param resultCode Code indicating activity success/failure
* @param data Image data associated with the camera activity
*/
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == ImageHelper.REQUEST_CAMERA) {
Bitmap imageBitmap = null;
try {
imageBitmap = BitmapFactory.decodeStream(getActivity().getContentResolver().openInputStream(Uri.fromFile(imageFile)));
} catch (FileNotFoundException e) {
Toaster.toastShort("Error. Could not load image.");
}
Bitmap squareBitmap = ThumbnailUtils.extractThumbnail(imageBitmap, 100, 100);
image = scaleImage(imageBitmap);
imageThumb = squareBitmap;
Bundle bundle = getArguments();
bundle.putParcelable("IMAGE_THUMB", imageThumb);
bundle.putParcelable("IMAGE_FULL", image);
} else if (requestCode == ImageHelper.REQUEST_GALLERY) {
Bitmap imageBitmap = null;
try {
imageBitmap = MediaStore.Images.Media.getBitmap(getActivity()
.getContentResolver(), data.getData());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Bitmap squareBitmap = ThumbnailUtils.extractThumbnail(imageBitmap, 100, 100);
image = scaleImage(imageBitmap);
imageThumb = squareBitmap;
Bundle bundle = getArguments();
bundle.putParcelable("IMAGE_THUMB", imageThumb);
bundle.putParcelable("IMAGE_FULL", image);
}
}
}
/**
* Scales a bitmap to a suitable size for display.
* @param bitmap The Bitmap to be scaled.
* @return The rescaled Bitmap.
*
*/
private Bitmap scaleImage(Bitmap bitmap) {
// https://github.com/bradleyjsimons/PicPoster/blob/master/src/ca/ualberta/cs/picposter/controller/PicPosterController.java
// Scale the pic if it is too large:
if (bitmap.getWidth() > MAX_BITMAP_DIMENSIONS || bitmap.getHeight() > MAX_BITMAP_DIMENSIONS) {
double scalingFactor = bitmap.getWidth() * 1.0 / MAX_BITMAP_DIMENSIONS;
if (bitmap.getHeight() > bitmap.getWidth())
scalingFactor = bitmap.getHeight() * 1.0 / MAX_BITMAP_DIMENSIONS;
int newWidth = (int) Math.round(bitmap.getWidth() / scalingFactor);
int newHeight = (int) Math.round(bitmap.getHeight() / scalingFactor);
bitmap = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, false);
}
return bitmap;
}
/**
* Stops the locationListenerService from listening.
*/
@Override
public void onStop() {
super.onStop();
locationListenerService.stopListening();
}
}