package eu.tpmusielak.securephoto.viewer;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.*;
import android.widget.*;
import eu.tpmusielak.securephoto.R;
import eu.tpmusielak.securephoto.container.SPImage;
import eu.tpmusielak.securephoto.container.SPImageRoll;
import eu.tpmusielak.securephoto.container.wrapper.SPFileWrapper;
import eu.tpmusielak.securephoto.container.wrapper.SPRWrapper;
import eu.tpmusielak.securephoto.verification.VerificationFactorData;
import eu.tpmusielak.securephoto.verification.Verifier;
import eu.tpmusielak.securephoto.viewer.lazylist.ImageLoader;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: Tomasz P. Musielak
* Date: 31/03/12
* Time: 20:33
*/
public class OpenImage extends Activity {
private int width;
private int height;
private int imageSize;
private byte[] imageData;
private File file;
private int frameIndex = -1;
private int frameCount = 0;
private SPFileWrapper wrapper;
private Button showVerifiersButton;
private List<Class<Verifier>> verifiers;
private Map<Class<Verifier>, VerificationFactorData> verifierData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
imageSize = Math.min(width, height);
setupScreen();
}
private void setupScreen() {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.image_view);
showVerifiersButton = (Button) findViewById(R.id.btn_show_verifiers);
showVerifiersButton.setOnClickListener(new VerifiersButtonListener());
// CC-Attribution
// Source: StackOverflow
// Author: Thomas Frankhauser (http://stackoverflow.com/users/408557/thomas-fankhauser)
// Question: http://stackoverflow.com/questions/937313/android-basic-gesture-detection
ActivitySwipeDetector activitySwipeDetector = new ActivitySwipeDetector(this);
RelativeLayout lowestLayout = (RelativeLayout) this.findViewById(R.id.open_image_view);
lowestLayout.setOnTouchListener(activitySwipeDetector);
// End of attribution
}
@Override
protected void onStart() {
super.onStart();
Intent i = getIntent();
if (i.hasExtra("filename")) { // Displaying image from browser
file = new File(i.getStringExtra("filename"));
}
if (i.hasExtra("frameIndex")) {
frameIndex = i.getIntExtra("frameIndex", -1);
}
displayFile();
}
private void displayFile() {
ImageView preview = (ImageView) findViewById(R.id.image);
Bitmap bitmap = null;
if (frameIndex < 0) {
bitmap = ImageLoader.decodeFile(file, imageSize);
} else {
try {
SPImageRoll roll = SPImageRoll.fromFile(file);
frameCount = roll.getFrameCount();
bitmap = ImageLoader.decodeFile(new SPRWrapper(file, roll.getHeader(), frameIndex), imageSize);
} catch (IOException ignored) {
} catch (ClassNotFoundException ignored) {
}
}
preview.setImageBitmap(bitmap);
TextView filename = (TextView) findViewById(R.id.filename);
filename.setText(file.getName());
TextView filedate = (TextView) findViewById(R.id.filedate);
Date date = new Date(file.lastModified());
filedate.setText(date.toLocaleString());
if (operatingSPFile())
showVerifiersButton.setVisibility(View.VISIBLE);
}
protected void loadNextFrame() {
if (frameIndex < (frameCount - 1)) {
frameIndex++;
displayFile();
} else if (frameCount > 0) {
Toast.makeText(OpenImage.this, R.string.last_frame, Toast.LENGTH_SHORT).show();
}
}
protected void loadPreviousFrame() {
if (frameIndex > 0) {
frameIndex--;
displayFile();
} else if (frameCount > 0) {
Toast.makeText(OpenImage.this, R.string.first_frame, Toast.LENGTH_SHORT).show();
}
}
private boolean operatingSPFile() {
return file.getName().endsWith(SPImage.DEFAULT_EXTENSION) || file.getName().endsWith(SPImageRoll.DEFAULT_EXTENSION);
}
private class VerifiersButtonListener implements View.OnClickListener {
@Override
public void onClick(View view) {
displayVerifiers();
}
}
protected void displayVerifiers() {
if (!operatingSPFile())
return;
SPImage image = null;
try {
if (file.getName().endsWith(SPImage.DEFAULT_EXTENSION)) {
image = SPImage.fromFile(file);
} else {
SPImageRoll roll = SPImageRoll.fromFile(file);
image = roll.getFrame(frameIndex);
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
if (image == null)
return;
List<String> verifierNames = new LinkedList<String>();
verifiers = image.getVerificationFactors();
verifierData = image.getVerificationFactorData();
for (Class<Verifier> factorClass : verifiers) {
verifierNames.add(factorClass.getSimpleName());
}
String[] verifierNamesArray = new String[verifierNames.size()];
verifierNames.toArray(verifierNamesArray);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(true);
if (verifierNamesArray.length > 0) {
builder.setTitle(R.string.verification_factors);
builder.setItems(verifierNamesArray, new VerifierPickListener(this));
} else {
builder.setMessage(R.string.no_verifiers_found);
}
AlertDialog dialog = builder.create();
dialog.show();
}
private class VerifierPickListener implements DialogInterface.OnClickListener {
private Context context;
private VerifierPickListener(Context context) {
this.context = context;
}
@Override
public void onClick(DialogInterface dialogInterface, int i) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(true);
Class<Verifier> verifierClass = verifiers.get(i);
VerificationFactorData factorData = verifierData.get(verifierClass);
if (factorData != null)
builder.setMessage(factorData.toString());
AlertDialog dialog = builder.create();
dialog.show();
}
}
// CC-Attribution
// Source: StackOverflow
// Author: Thomas Frankhauser (http://stackoverflow.com/users/408557/thomas-fankhauser)
// Question: http://stackoverflow.com/questions/937313/android-basic-gesture-detection
private class ActivitySwipeDetector implements View.OnTouchListener {
private OpenImage activity;
static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;
public ActivitySwipeDetector(OpenImage activity) {
this.activity = activity;
}
public void onRightToLeftSwipe() {
activity.loadNextFrame();
}
public void onLeftToRightSwipe() {
activity.loadPreviousFrame();
}
public void onTopToBottomSwipe() {
}
public void onBottomToTopSwipe() {
}
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
downX = event.getX();
downY = event.getY();
return true;
}
case MotionEvent.ACTION_UP: {
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// swipe horizontal?
if (Math.abs(deltaX) > MIN_DISTANCE) {
// left or right
if (deltaX < 0) {
this.onLeftToRightSwipe();
return true;
}
if (deltaX > 0) {
this.onRightToLeftSwipe();
return true;
}
} else {
return false; // We don't consume the event
}
// swipe vertical?
if (Math.abs(deltaY) > MIN_DISTANCE) {
// top or down
if (deltaY < 0) {
this.onTopToBottomSwipe();
return true;
}
if (deltaY > 0) {
this.onBottomToTopSwipe();
return true;
}
} else {
return false; // We don't consume the event
}
return true;
}
}
return false;
}
}
// End of attribution
}