package com.code44.finance.ui;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.Button;
import android.widget.TextView;
import com.code44.finance.R;
import com.code44.finance.utils.Calculator;
import javax.inject.Inject;
public class CalculatorFragment extends BaseFragment implements View.OnClickListener, View.OnLongClickListener {
private static final String ARG_VALUE = "ARG_VALUE";
private static final String ARG_RAW_VALUE = "ARG_RAW_VALUE";
private static final String STATE_EXPRESSION = "STATE_EXPRESSION";
@Inject Calculator calculator;
private ViewGroup resultContainer_V;
private TextView result_TV;
private View resultClearer_V;
private CalculatorListener listener;
public static CalculatorFragment newInstance(long value) {
final Bundle args = new Bundle();
args.putLong(ARG_VALUE, value);
final CalculatorFragment fragment = new CalculatorFragment();
fragment.setArguments(args);
return fragment;
}
public static CalculatorFragment newInstance(double value) {
final Bundle args = new Bundle();
args.putDouble(ARG_RAW_VALUE, value);
final CalculatorFragment fragment = new CalculatorFragment();
fragment.setArguments(args);
return fragment;
}
@Override public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof CalculatorListener) {
listener = (CalculatorListener) activity;
} else {
throw new IllegalArgumentException("Activity " + activity.getClass().getSimpleName() + " must implement " + CalculatorListener.class.getSimpleName());
}
}
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_calculator, container, false);
}
@Override public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Get views
resultContainer_V = (ViewGroup) view.findViewById(R.id.resultContainer_V);
result_TV = (TextView) view.findViewById(R.id.result_TV);
resultClearer_V = view.findViewById(R.id.resultClearer_V);
final Button equals_B = (Button) view.findViewById(R.id.equals_B);
final Button delete_B = (Button) view.findViewById(R.id.delete_B);
final Button divide_B = (Button) view.findViewById(R.id.divide_B);
final Button multiply_B = (Button) view.findViewById(R.id.multiply_B);
final Button minus_B = (Button) view.findViewById(R.id.minus_B);
final Button plus_B = (Button) view.findViewById(R.id.plus_B);
final Button dot_B = (Button) view.findViewById(R.id.dot_B);
final Button number0_B = (Button) view.findViewById(R.id.number0_B);
final Button number1_B = (Button) view.findViewById(R.id.number1_B);
final Button number2_B = (Button) view.findViewById(R.id.number2_B);
final Button number3_B = (Button) view.findViewById(R.id.number3_B);
final Button number4_B = (Button) view.findViewById(R.id.number4_B);
final Button number5_B = (Button) view.findViewById(R.id.number5_B);
final Button number6_B = (Button) view.findViewById(R.id.number6_B);
final Button number7_B = (Button) view.findViewById(R.id.number7_B);
final Button number8_B = (Button) view.findViewById(R.id.number8_B);
final Button number9_B = (Button) view.findViewById(R.id.number9_B);
// Setup
delete_B.setOnLongClickListener(this);
delete_B.setOnClickListener(this);
divide_B.setOnClickListener(this);
multiply_B.setOnClickListener(this);
minus_B.setOnClickListener(this);
plus_B.setOnClickListener(this);
dot_B.setOnClickListener(this);
equals_B.setOnClickListener(this);
number0_B.setOnClickListener(this);
number1_B.setOnClickListener(this);
number2_B.setOnClickListener(this);
number3_B.setOnClickListener(this);
number4_B.setOnClickListener(this);
number5_B.setOnClickListener(this);
number6_B.setOnClickListener(this);
number7_B.setOnClickListener(this);
number8_B.setOnClickListener(this);
number9_B.setOnClickListener(this);
if (savedInstanceState == null) {
final double value;
if (getArguments().containsKey(ARG_VALUE)) {
value = getArguments().getLong(ARG_VALUE, 0) / 100.0;
} else {
value = getArguments().getDouble(ARG_RAW_VALUE, 0);
}
if (value != 0) {
calculator.setValue(value);
}
} else {
if (savedInstanceState.containsKey(STATE_EXPRESSION)) {
String exp = savedInstanceState.getString(STATE_EXPRESSION, null);
if (exp != null) {
calculator.setExpression(exp);
}
}
}
updateResult();
//noinspection ConstantConditions
getView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
getView().getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
//noinspection deprecation
getView().getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
onLayoutFinished();
}
});
}
@Override public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(STATE_EXPRESSION, calculator.getExpression());
}
@Override public void onDetach() {
super.onDetach();
listener = null;
}
@Override public void onClick(View v) {
switch (v.getId()) {
case R.id.delete_B:
calculator.delete();
updateResult();
break;
case R.id.equals_B:
if (calculator.hasExpression()) {
calculator.calculate();
updateResult();
} else {
listener.onCalculatorResult(calculator.getResult(), calculator.getResultRaw());
}
break;
case R.id.divide_B:
calculator.divide();
updateResult();
break;
case R.id.multiply_B:
calculator.multiply();
updateResult();
break;
case R.id.minus_B:
calculator.minus();
updateResult();
break;
case R.id.plus_B:
calculator.plus();
updateResult();
break;
case R.id.dot_B:
calculator.decimal();
updateResult();
break;
case R.id.number0_B:
calculator.number(0);
updateResult();
break;
case R.id.number1_B:
calculator.number(1);
updateResult();
break;
case R.id.number2_B:
calculator.number(2);
updateResult();
break;
case R.id.number3_B:
calculator.number(3);
updateResult();
break;
case R.id.number4_B:
calculator.number(4);
updateResult();
break;
case R.id.number5_B:
calculator.number(5);
updateResult();
break;
case R.id.number6_B:
calculator.number(6);
updateResult();
break;
case R.id.number7_B:
calculator.number(7);
updateResult();
break;
case R.id.number8_B:
calculator.number(8);
updateResult();
break;
case R.id.number9_B:
calculator.number(9);
updateResult();
break;
}
}
@Override public boolean onLongClick(View v) {
switch (v.getId()) {
case R.id.delete_B:
clear();
return true;
}
return false;
}
public void updateResult() {
result_TV.setText(calculator.getFormattedExpression());
}
private void onLayoutFinished() {
final ViewGroup.LayoutParams params = resultClearer_V.getLayoutParams();
params.width = resultContainer_V.getWidth();
params.height = resultContainer_V.getHeight();
}
private void clear() {
int cx = resultClearer_V.getRight();
int cy = resultClearer_V.getBottom();
float radius = Math.max(resultClearer_V.getWidth(), resultClearer_V.getHeight()) * 2.0f;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (resultClearer_V.getVisibility() != View.VISIBLE) {
Animator reveal = ViewAnimationUtils.createCircularReveal(resultClearer_V, cx, cy, 0, radius);
reveal.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
resultClearer_V.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
calculator.clear();
updateResult();
resultClearer_V.animate().alpha(0.0f).setDuration(200).withEndAction(new Runnable() {
@Override
public void run() {
resultClearer_V.setVisibility(View.INVISIBLE);
resultClearer_V.setAlpha(1.0f);
}
}).start();
}
});
reveal.setDuration(600);
reveal.start();
}
} else {
calculator.clear();
updateResult();
}
}
static interface CalculatorListener {
public void onCalculatorResult(long result, double rawResult);
}
}