/*
* Copyright 2015 Daniel Dittmar
*
* 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 dan.dit.whatsthat.system;
import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.github.johnpersano.supertoasts.SuperCardToast;
import com.github.johnpersano.supertoasts.SuperToast;
import com.github.johnpersano.supertoasts.util.OnClickWrapper;
import com.plattysoft.leonids.ParticleSystem;
import java.io.File;
import java.net.URL;
import dan.dit.whatsthat.R;
import dan.dit.whatsthat.achievement.AchievementProperties;
import dan.dit.whatsthat.image.Image;
import dan.dit.whatsthat.image.ImageAuthor;
import dan.dit.whatsthat.image.ImageObfuscator;
import dan.dit.whatsthat.preferences.User;
import dan.dit.whatsthat.preferences.WebPhotoStorage;
import dan.dit.whatsthat.riddle.achievement.holders.MiscAchievementHolder;
import dan.dit.whatsthat.riddle.types.PracticalRiddleType;
import dan.dit.whatsthat.testsubject.TestSubject;
import dan.dit.whatsthat.util.general.VersionSafe;
import dan.dit.whatsthat.util.image.ImageUtil;
import dan.dit.whatsthat.util.ui.GlasDialog;
/**
* Created by daniel on 06.05.15.
*/
public class NoPanicDialog extends DialogFragment {
public static final String KEY_IMAGE = "key_image_hash";
public static final String KEY_TYPE = "key_type_full_name";
public static final String KEY_SOLUTION_INPUT_DATA = "key_solution_input_data";
private static final String KEY_NO_SECRETS = "key_no_secrets";
private PracticalRiddleType mType;
private String mSolutionInputData;
private Image mImage;
private Callback mCallback;
private ViewGroup mAskTypeAnswer;
private TextView mAskTypeAnswerText;
private int mFunCounter;
private ViewGroup mAuthorContainer;
private Button mShareExperiment;
private URL mToShareLink;
private Bitmap mToShare;
private AsyncTask<Void, Void, File> mShareBuildTask;
private ViewGroup mTotalContainer;
public interface Callback {
boolean canSkip();
void onSkip();
void onComplain(Image image);
void onRetryWithDifferentRiddle();
}
@Override
public void onDestroy() {
super.onDestroy();
ImageUtil.CACHE.makeReusable(mToShare);
mToShare = null;
User.clearTempDirectory();
mToShareLink = null;
if (mShareBuildTask != null) {
mShareBuildTask.cancel(true);
mShareBuildTask = null;
}
this.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
}
@Override
public void onDetach() {
if (mShareBuildTask != null) {
mShareBuildTask.cancel(true);
mShareBuildTask = null;
}
super.onDetach();
}
@Override
public void onActivityCreated(Bundle arg0) {
super.onActivityCreated(arg0);
getDialog().getWindow()
.getAttributes().windowAnimations = R.style.NoPanicDialogAnimation;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View baseView = getActivity().getLayoutInflater().inflate(R.layout.panic_dialog, null);
this.getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
String imageHash = null;
String typeName = null;
boolean noSecrets = false;
String solutionInputData = null;
Bundle args = getArguments();
if (savedInstanceState != null) {
imageHash = savedInstanceState.getString(KEY_IMAGE);
typeName = savedInstanceState.getString(KEY_TYPE);
noSecrets = savedInstanceState.getBoolean(KEY_NO_SECRETS);
solutionInputData = savedInstanceState.getString(KEY_SOLUTION_INPUT_DATA);
} else if (args != null) {
imageHash = args.getString(KEY_IMAGE);
typeName = args.getString(KEY_TYPE);
noSecrets = args.getBoolean(KEY_NO_SECRETS);
solutionInputData = args.getString(KEY_SOLUTION_INPUT_DATA);
}
if (typeName != null) {
mType = PracticalRiddleType.getInstance(typeName);
}
if (imageHash != null) {
mImage = RiddleFragment.ALL_IMAGES.get(imageHash);
}
mSolutionInputData = solutionInputData;
if (mImage != null) {
String[] headings = getResources().getStringArray(R.array.panic_author_credit_title);
Button authorQuestion = (Button) baseView.findViewById(R.id.author_ask);
authorQuestion.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onAskAuthor();
}
});
mAuthorContainer = (ViewGroup) baseView.findViewById(R.id.author_container);
authorQuestion.setVisibility(View.VISIBLE);
mAuthorContainer.setVisibility(View.GONE);
mTotalContainer = (ViewGroup) baseView.findViewById(R.id.panic_container);
((TextView) baseView.findViewById(R.id.credits_heading)).setText(headings[(int) (Math.random() * headings.length)]);
ImageAuthor author = mImage.getAuthor();
TextView nameView = (TextView) baseView.findViewById(R.id.author_name);
setTextIfAvailable(nameView, R.string.image_author_name, author.getName());
nameView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getActionMasked() == MotionEvent.ACTION_DOWN) {
new ParticleSystem(getResources(), 10, R.drawable.heart, 1000L,
mTotalContainer)
.setScaleRange(0.7f, 1.3f)
.setSpeedModuleAndAngleRange(0.07f, 0.16f, 180, 360)
.setRotationSpeedRange(-90, 90)
.setAcceleration(0.00013f, 90)
.setFadeOut(200, new AccelerateInterpolator())
.emitWithGravity(view, Gravity.CENTER, 3, 3000);
AchievementProperties data = TestSubject.getInstance().getAchievementHolder().getMiscData();
if (data != null) {
data.increment(MiscAchievementHolder.KEY_ADMIRED_IMAGE_AUTHOR, 1L, 0L);
}
}
return false;
}
});
setTextIfAvailable(((TextView) baseView.findViewById(R.id.author_license)), R.string.image_author_license, author.getLicense());
if (noSecrets) {
setTextIfAvailable(((TextView) baseView.findViewById(R.id.author_source)), R.string.image_author_source, author.getSource());
setTextIfAvailable(((TextView) baseView.findViewById(R.id.author_details)), R.string.image_author_details, author.getTitle() + "; " + author.getExtras());
} else {
setTextIfAvailable(((TextView) baseView.findViewById(R.id.author_source)), R.string.image_author_source, author.sourceExtractWebsite());
baseView.findViewById(R.id.author_details).setVisibility(View.GONE);
}
} else {
baseView.findViewById(R.id.author_ask).setVisibility(View.GONE);
baseView.findViewById(R.id.author_container).setVisibility(View.GONE);
}
Button skip = (Button) baseView.findViewById(R.id.panic_skip);
if (!mCallback.canSkip()) {
skip.setEnabled(false);
skip.setText(R.string.panic_cannot_skip);
} else {
skip.setEnabled(true);
skip.setText(R.string.panic_skip);
skip.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
mCallback.onSkip();
}
});
}
Button retry = (Button) baseView.findViewById(R.id.panic_retry);
retry.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SuperCardToast toast = new SuperCardToast(getActivity(), SuperToast.Type.BUTTON);
toast.setText(getResources().getString(R.string.panic_retry_notification));
toast.setDuration(SuperToast.Duration.EXTRA_LONG);
toast.setButtonIcon(R.drawable.panic_retry, getResources().getString(R.string
.panic_retry_confirm));
toast.setButtonTextSize(15);
toast.setOnClickWrapper(new OnClickWrapper("PANIC_RETRY", new SuperToast.OnClickListener() {
@Override
public void onClick(View view, Parcelable token) {
mCallback.onRetryWithDifferentRiddle();
}
}));
dismiss();
toast.show();
}
});
View askType = baseView.findViewById(R.id.panic_ask_type);
mAskTypeAnswer = (ViewGroup) baseView.findViewById(R.id.panic_ask_type_answer);
mAskTypeAnswerText = (TextView) baseView.findViewById(R.id.panic_ask_type_answer_text);
if (mType == null || mType.getExplanationResId() == 0) {
askType.setVisibility(View.GONE);
mAskTypeAnswer.setVisibility(View.GONE);
} else {
askType.setVisibility(View.VISIBLE);
mAskTypeAnswer.setVisibility(View.GONE);
askType.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onAskType();
}
});
}
View complainView = baseView.findViewById(R.id.panic_complain);
complainView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismiss();
mCallback.onComplain(mImage);
}
});
mShareExperiment = (Button) baseView.findViewById(R.id.panic_share);
if (mImage == null) {
mShareExperiment.setVisibility(View.GONE);
} else {
mShareExperiment.setVisibility(View.VISIBLE);
mShareExperiment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
shareCurrentExperiment();
}
});
}
final String dontPanicAnims = getResources().getString(R.string.no_panic_anims);
View dontPanic = baseView.findViewById(R.id.panic_dontpanic);
dontPanic.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
ImageView image = (ImageView) v;
Rect bounds = image.getDrawable().getBounds();
if (!bounds.contains((int) (event.getX() - v.getWidth() / 2 + bounds.width() / 2), (int) (event.getY() - v.getHeight() / 2 + bounds.height() / 2))) {
dismiss();
} else {
v.clearAnimation();
int animNumber = 0;
try {
animNumber = Integer.parseInt(String.valueOf(dontPanicAnims.charAt
(mFunCounter)));
} catch (NumberFormatException nfe) {
Log.e("Riddle", "Illegal dontpanicanims string: " + dontPanicAnims);
}
int anim;
switch (animNumber) {
case 0:
anim = R.anim.panic_fun_zoom;
break;
case 1:
anim = R.anim.panic_fun_roll;
break;
default:
anim = R.anim.panic_fun_bounce;
break;
}
mFunCounter++;
mFunCounter %= dontPanicAnims.length();
v.startAnimation(AnimationUtils.loadAnimation(getActivity(), anim));
}
}
return true;
}
});
return new GlasDialog(getActivity(), baseView);
}
private void shareCurrentExperiment() {
mShareExperiment.setEnabled(false);
mShareExperiment.startAnimation(AnimationUtils.loadAnimation(getActivity(), R.anim.panic_share_progress));
if (mToShareLink != null) {
executeShare();
return;
}
if (mImage != null) {
mShareBuildTask = new AsyncTask<Void, Void, File>() {
@Override
protected File doInBackground(Void... params) {
mToShare = ImageObfuscator.makeHidden(getResources(), mImage, mType, User
.getInstance().getLogo(getResources()), mSolutionInputData);
boolean success = mToShare != null;
File toShare = null;
if (success && !isCancelled()) {
success = false;
String origin = User.getInstance().getOriginName();
String name = (origin == null ? "-" : origin)
+ "_"
+ System.currentTimeMillis();
if (!name.endsWith(ImageObfuscator.FILE_EXTENSION)) {
if (name.endsWith(".png")) {
name = name.substring(0, name.length() - 4) + ImageObfuscator.FILE_EXTENSION;
} else {
name = name + ImageObfuscator.FILE_EXTENSION;
}
}
File tempDir = User.getTempDirectory();
Log.d("Image", "Made hidden success, now attempting to save in dir " + tempDir + " with name " + name);
if (tempDir != null) {
File target = new File(tempDir, name);
if (ImageUtil.saveToFile(mToShare, target, Bitmap.CompressFormat.PNG, 100)) {
toShare = target;
success = true;
}
}
}
if (!success && !isCancelled()) {
Toast.makeText(getActivity(), R.string.panic_share_failed, Toast.LENGTH_SHORT).show();
}
return toShare;
}
@Override
public void onPostExecute(File result) {
if (result != null) {
User.getInstance().uploadPhoto(result, new WebPhotoStorage.UploadListener() {
@Override
public void onPhotoUploaded(String photoLink, URL photoShareLink) {
mToShareLink = photoShareLink;
Log.d("Riddle", "On Photo uploaded: " + photoLink + " and " +
photoShareLink);
if (VersionSafe.isDetached(NoPanicDialog.this)) {
Log.d("Riddle", "On Photo uploaded and dialog not visible");
return;
}
executeShare();
}
@Override
public void onPhotoUploadFailed(int error) {
if (VersionSafe.isDetached(NoPanicDialog.this)) {
return;
}
clearShareButton();
Toast.makeText(getActivity(), getResources().getString(R.string
.share_failed_upload, error),
Toast.LENGTH_SHORT).show();
}
});
}
}
}.execute();
} else {
clearShareButton();
}
}
private void clearShareButton() {
mShareExperiment.setEnabled(true);
mShareExperiment.clearAnimation();
}
private void executeShare() {
clearShareButton();
if (mToShareLink == null) {
return;
}
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("text/plain");
share.putExtra(Intent.EXTRA_TEXT, mToShareLink.toString());
share.putExtra(android.content.Intent.EXTRA_SUBJECT, getResources().getString(R.string
.share_experiment_link_subject));
getActivity().startActivity(Intent.createChooser(share, getActivity().getResources().getString(R.string.panic_share_dialog)));
}
private void onAskType() {
int explanationResId = mType.getExplanationResId();
if (mAskTypeAnswer.getVisibility() == View.GONE && explanationResId != 0) {
mAskTypeAnswer.setVisibility(View.VISIBLE);
mAskTypeAnswerText.setText(explanationResId);
} else {
mAskTypeAnswer.setVisibility(View.GONE);
}
}
private void onAskAuthor() {
if (mAuthorContainer.getVisibility() == View.GONE) {
mAuthorContainer.setVisibility(View.VISIBLE);
} else {
mAuthorContainer.setVisibility(View.GONE);
}
}
private void setTextIfAvailable(TextView view, int resId, String text) {
if (TextUtils.isEmpty(text)) {
view.setVisibility(View.GONE);
return;
}
view.setVisibility(View.VISIBLE);
view.setText(getResources().getString(resId, text));
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if (mType != null) {
outState.putString(KEY_TYPE, mType.getFullName());
}
if (mImage != null) {
outState.putString(KEY_IMAGE, mImage.getHash());
}
outState.putString(KEY_SOLUTION_INPUT_DATA, mSolutionInputData);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (Callback) activity;
} catch (ClassCastException e) {
throw new IllegalArgumentException("Activity needs to implement callback!");
}
}
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
dialog.setCanceledOnTouchOutside(true);
}
}
}