package de.jeisfeld.augendiagnoselib.activities;
import android.app.DialogFragment;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.GridView;
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import de.jeisfeld.augendiagnoselib.R;
import de.jeisfeld.augendiagnoselib.components.EyeImageView;
import de.jeisfeld.augendiagnoselib.components.SelectTwoPicturesArrayAdapter;
import de.jeisfeld.augendiagnoselib.util.DialogUtil;
import de.jeisfeld.augendiagnoselib.util.DialogUtil.ConfirmDialogFragment.ConfirmDialogListener;
import de.jeisfeld.augendiagnoselib.util.TwoImageSelectionHandler;
import de.jeisfeld.augendiagnoselib.util.imagefile.EyePhoto;
import de.jeisfeld.augendiagnoselib.util.imagefile.FileUtil;
import de.jeisfeld.augendiagnoselib.util.imagefile.ImageUtil;
/**
* Activity to select a pair of eye photos from a folder and return the paths to the parent activity.
*/
public class SelectTwoPicturesActivity extends StandardActivity {
/**
* The requestCode with which this activity is started.
*/
public static final int REQUEST_CODE = 2;
/**
* The resource key for the folder name.
*/
private static final String STRING_EXTRA_FOLDER = "de.jeisfeld.augendiagnoselib.FOLDER";
/**
* The resource key for the array of filenames.
*/
private static final String STRING_EXTRA_FILENAMES = "de.jeisfeld.augendiagnoselib.FILENAMES";
/**
* The resource key for the name of the first selected file.
*/
private static final String STRING_RESULT_FILENAME1 = "de.jeisfeld.augendiagnoselib.FILENAME1";
/**
* The resource key for the name of the second selected file.
*/
private static final String STRING_RESULT_FILENAME2 = "de.jeisfeld.augendiagnoselib.FILENAME2";
/**
* The image folder.
*/
private File mFolder;
/**
* The list of image files.
*/
private String[] mFileNames;
/**
* The view showing the eye photos.
*/
private GridView mGridView;
/**
* The selected view when displaying the context menu.
*/
private EyeImageView mSelectedView;
/**
* Static helper method to start the activity, passing the path of the folder.
*
* @param activity The activity starting this activity.
* @param foldername The image folder.
*/
public static void startActivity(@NonNull final OrganizeNewPhotosActivity activity, final String foldername) {
Intent intent = new Intent(activity, SelectTwoPicturesActivity.class);
intent.putExtra(STRING_EXTRA_FOLDER, foldername);
activity.startActivityForResult(intent, REQUEST_CODE);
}
/**
* Static helper method to start the activity, passing the list of files.
*
* @param activity The activity starting this activity.
* @param fileNames The list of image files.
*/
public static void startActivity(@NonNull final OrganizeNewPhotosActivity activity, final String[] fileNames) {
Intent intent = new Intent(activity, SelectTwoPicturesActivity.class);
intent.putExtra(STRING_EXTRA_FILENAMES, fileNames);
activity.startActivityForResult(intent, REQUEST_CODE);
}
/**
* Static helper method to extract the first selected filename from the activity response.
*
* @param resultCode The result code indicating if the response was successful.
* @param data The activity response data.
* @return The returned file name.
*/
public static String getResultFile1(final int resultCode, @NonNull final Intent data) {
if (resultCode == RESULT_OK) {
Bundle res = data.getExtras();
return res.getString(STRING_RESULT_FILENAME1);
}
else {
return null;
}
}
/**
* Static helper method to extract the second selected filename from the activity response.
*
* @param resultCode The result code indicating if the response was successful.
* @param data The activity response data.
* @return The returned file name.
*/
public static String getResultFile2(final int resultCode, @NonNull final Intent data) {
if (resultCode == RESULT_OK) {
Bundle res = data.getExtras();
return res.getString(STRING_RESULT_FILENAME2);
}
else {
return null;
}
}
@Override
protected final void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_two_pictures);
String folderName = getIntent().getStringExtra(STRING_EXTRA_FOLDER);
if (folderName != null) {
mFolder = new File(folderName);
}
mFileNames = getIntent().getStringArrayExtra(STRING_EXTRA_FILENAMES);
// Prepare the view
mGridView = (GridView) findViewById(R.id.gridViewSelectTwoPictures);
mGridView.setAdapter(new SelectTwoPicturesArrayAdapter(this, getEyePhotos()));
displayButtons(TwoImageSelectionHandler.getInstance().getSelectedImages().size() > 0);
}
@Override
protected final void onDestroy() {
super.onDestroy();
}
@Override
protected final int getHelpResource() {
return R.string.html_organize_photos;
}
/**
* Helper method to retrieve the list of photos in the folder as EyePhoto objects.
*
* @return The list of eye photos.
*/
@NonNull
private EyePhoto[] getEyePhotos() {
File[] files;
if (isStartedWithInputFolder()) {
// Get files from folder
files = mFolder.listFiles(new ImageUtil.ImageFileFilter());
if (files == null) {
files = new File[0];
}
Arrays.sort(files, new Comparator<File>() {
@Override
public int compare(@NonNull final File f1, @NonNull final File f2) {
return Long.valueOf(f2.lastModified()).compareTo(f1.lastModified());
}
});
}
else {
files = new File[mFileNames.length];
for (int i = 0; i < mFileNames.length; i++) {
files[i] = new File(mFileNames[i]);
}
}
EyePhoto[] result = new EyePhoto[files.length];
for (int i = 0; i < files.length; i++) {
result[i] = new EyePhoto(files[i]);
}
return result;
}
/**
* Helper method: Return the selected filenames and finish the activity.
*
* @param filename1 The first filename.
* @param filename2 The second filename.
*/
public final void returnResult(final String filename1, final String filename2) {
Bundle resultData = new Bundle();
resultData.putCharSequence(STRING_RESULT_FILENAME1, filename1);
resultData.putCharSequence(STRING_RESULT_FILENAME2, filename2);
Intent intent = new Intent();
if (filename1 == null && filename2 == null) {
setResult(RESULT_CANCELED, intent);
}
else {
intent.putExtras(resultData);
setResult(RESULT_OK, intent);
}
finish();
}
/*
* Create the context menu.
*/
@Override
public final void onCreateContextMenu(final ContextMenu menu, final View v, final ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_select_two, menu);
mSelectedView = (EyeImageView) v;
}
/*
* Handle items in the context menu.
*/
@Override
public final boolean onContextItemSelected(@NonNull final MenuItem item) {
int itemId = item.getItemId();
if (itemId == R.id.action_delete_selected_image) {
ConfirmDialogListener listenerDelete = new ConfirmDialogListener() {
/**
* The serial version id.
*/
private static final long serialVersionUID = -3186094978749077352L;
@Override
public void onDialogPositiveClick(final DialogFragment dialog) {
// delete image
boolean success = mSelectedView.getEyePhoto().delete();
updateEyePhotoList();
if (success) {
if (TwoImageSelectionHandler.getInstance().getSelectedImages().contains(mSelectedView.getEyePhoto())) {
TwoImageSelectionHandler.getInstance().deselectView(mSelectedView);
}
}
else {
DialogUtil.displayError(SelectTwoPicturesActivity.this,
R.string.message_dialog_failed_to_delete_file, false, mSelectedView
.getEyePhoto().getFilename());
}
}
@Override
public void onDialogNegativeClick(final DialogFragment dialog) {
// Do nothing
}
};
DialogUtil.displayConfirmationMessage(this, listenerDelete, R.string.button_delete,
R.string.message_dialog_confirm_delete_photo, mSelectedView.getEyePhoto().getFilename());
return true;
}
else if (itemId == R.id.action_delete_all_images) {
ConfirmDialogListener listenerDeleteAll = new ConfirmDialogListener() {
/**
* The serial version id.
*/
private static final long serialVersionUID = -4135840952030307156L;
@Override
public void onDialogPositiveClick(final DialogFragment dialog) {
if (isStartedWithInputFolder()) {
// delete images
boolean success = FileUtil.deleteFilesInFolder(mFolder);
updateEyePhotoList();
if (success) {
setResult(OrganizeNewPhotosActivity.RESULT_FINISH);
finish();
}
else {
DialogUtil.displayError(SelectTwoPicturesActivity.this,
R.string.message_dialog_failed_to_delete_all_files, false, mSelectedView.getEyePhoto().getFilename());
}
}
}
@Override
public void onDialogNegativeClick(final DialogFragment dialog) {
// Do nothing
}
};
DialogUtil.displayConfirmationMessage(this, listenerDeleteAll, R.string.button_delete,
R.string.message_dialog_confirm_delete_all_photos, mSelectedView.getEyePhoto().getFilename());
return true;
}
else {
return super.onContextItemSelected(item);
}
}
/**
* onClick action for Button "Preview".
*
* @param view The view triggering the onClick action.
*/
public final void onPreviewClick(final View view) {
List<EyePhoto> selectedImages = TwoImageSelectionHandler.getInstance().getSelectedImages();
if (selectedImages.size() >= 2) {
DisplayTwoActivity.startActivity(this, selectedImages.get(0).getAbsolutePath(), selectedImages.get(1).getAbsolutePath(), false);
}
else if (selectedImages.size() == 1) {
DisplayOneActivity.startActivity(this, selectedImages.get(0).getAbsolutePath());
}
}
/**
* onClick action for Button "Apply Selection".
*
* @param view The view triggering the onClick action.
*/
public final void onSelectClick(final View view) {
List<EyePhoto> selectedImages = TwoImageSelectionHandler.getInstance().getSelectedImages();
if (selectedImages.size() >= 2) {
returnResult(selectedImages.get(0).getAbsolutePath(), selectedImages.get(1).getAbsolutePath());
}
else if (selectedImages.size() == 1) {
returnResult(selectedImages.get(0).getAbsolutePath(), null);
}
else {
returnResult(null, null);
}
}
/**
* Display or hide the activity buttons.
*
* @param display true will display teh buttons, false will hide them.
*/
public final void displayButtons(final boolean display) {
findViewById(R.id.layoutSelectTwoButtons).setVisibility(display ? View.VISIBLE : View.GONE);
}
/**
* Update the list of eye photo pairs.
*/
private void updateEyePhotoList() {
mGridView.setAdapter(new SelectTwoPicturesArrayAdapter(this, getEyePhotos()));
}
/**
* Gives information if the activity is started via input folder or via list of files.
*
* @return true if started via input folder.
*/
public final boolean isStartedWithInputFolder() {
return mFolder != null;
}
}