app.CT.BTCCalculator.fragments.BreakevenFragment.java Source code

Java tutorial

Introduction

Here is the source code for app.CT.BTCCalculator.fragments.BreakevenFragment.java

Source

/*
 * Copyright (C) 2017 Chris Tarazi
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package app.CT.BTCCalculator.fragments;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
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 com.squareup.otto.Subscribe;

import java.text.DecimalFormat;

import app.CT.BTCCalculator.R;
import app.CT.BTCCalculator.activities.AboutActivity;
import app.CT.BTCCalculator.events.BusProvider;

public class BreakevenFragment extends Fragment {
    private EditText btcBought;
    private EditText btcBoughtPrice;
    private EditText btcSold;
    private EditText btcSoldPrice;
    private EditText optimalBTCPrice;
    private EditText optimalBTC;

    private TextView resultText;

    private String rate;

    private boolean[] containsCurrentRate = { false, false };

    private Menu menu;

    // Function round to two decimals.
    public double roundTwoDecimals(double d) {
        DecimalFormat df = new DecimalFormat("###.##");
        return Double.parseDouble(df.format(d));
    }

    // Otto function to subscribe to Event Bus changes.
    @Subscribe
    public void onPriceUpdated(String mRate) {
        rate = mRate.replace(",", "");

        // If btcBoughtPrice field has the current price, update it.
        if (containsCurrentRate[0])
            btcBoughtPrice.setText(rate);
        // If btcSoldPrice has the current price, update it as well.
        if (containsCurrentRate[1])
            btcSoldPrice.setText(rate);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_breakeven, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // Register Bus Provider instance.
        BusProvider.getInstance().register(this);

        View view = getView();

        // Initialize text fields.
        assert view != null;
        btcBought = (EditText) view.findViewById(R.id.btcBought);
        btcBoughtPrice = (EditText) view.findViewById(R.id.btcBoughtPrice);
        btcSold = (EditText) view.findViewById(R.id.btcSold);
        btcSoldPrice = (EditText) view.findViewById(R.id.btcSoldPrice);
        optimalBTCPrice = (EditText) view.findViewById(R.id.optimalBTCPrice);
        optimalBTC = (EditText) view.findViewById(R.id.optimalBTC);
        resultText = (TextView) view.findViewById(R.id.resultText);

        Button buttonCalculate = (Button) view.findViewById(R.id.buttonCalculate);

        // Checks whether the first visible EditText element is focused in order to enable
        // and show the keyboard to the user. The corresponding XML element has android:imeOptions="actionNext".
        // All EditText elements below are now programmed to show keyboard when pressed.
        btcBought.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSoftKeyboard(v);
            }
        });

        btcBoughtPrice.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSoftKeyboard(v);
            }
        });

        btcSold.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSoftKeyboard(v);
            }
        });

        btcSoldPrice.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSoftKeyboard(v);
            }
        });

        optimalBTCPrice.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSoftKeyboard(v);
            }
        });

        optimalBTC.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSoftKeyboard(v);
            }
        });

        optimalBTCPrice.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                try {
                    float result = ((Float.valueOf(btcSold.getText().toString()))
                            * Float.valueOf(btcSoldPrice.getText().toString()))
                            / Float.valueOf(optimalBTCPrice.getText().toString());
                    optimalBTC.setText(String.valueOf(result));
                } catch (Exception ignored) {
                }

            }
        });

        btcBoughtPrice.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                containsCurrentRate[0] = false;
            }
        });

        btcSoldPrice.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                containsCurrentRate[1] = false;
            }
        });

        buttonCalculate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                float buyAmount, buyCost, sellAmount, sellPrice, optimalBTCCost, optimalBTCAmount, remainder,
                        totalCost, totalAmount, finalPrice;
                boolean didItWork = true;
                boolean validTransaction = true;

                // Error checking to prevent crashes.
                try {
                    // Gets the input entered from the user.
                    buyAmount = Float.valueOf(btcBought.getText().toString());
                    buyCost = Float.valueOf(btcBoughtPrice.getText().toString());
                    sellAmount = Float.valueOf(btcSold.getText().toString());
                    sellPrice = Float.valueOf(btcSoldPrice.getText().toString());
                    optimalBTCCost = Float.valueOf(optimalBTCPrice.getText().toString());
                    optimalBTCAmount = Float.valueOf(optimalBTC.getText().toString());

                    // Calculates remainder from the buying and selling.
                    remainder = Math.abs((buyAmount - sellAmount));

                    // User cannot sell more than they own.
                    if (roundTwoDecimals(optimalBTCAmount * optimalBTCCost) > roundTwoDecimals(
                            sellAmount * sellPrice)) {
                        final android.support.v7.app.AlertDialog.Builder alertDialog = new android.support.v7.app.AlertDialog.Builder(
                                getActivity());
                        alertDialog.setTitle("Error");
                        alertDialog.setMessage(getString(R.string.optimalBTCErrorMsg));
                        alertDialog.setCancelable(false);
                        alertDialog.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.cancel();
                            }
                        });
                        alertDialog.show();
                        validTransaction = false;
                    }

                    // Checks if the user typed in a greater selling amount than buying.
                    if (sellAmount > buyAmount) {
                        // Create new dialog popup.
                        final android.support.v7.app.AlertDialog.Builder alertDialog = new android.support.v7.app.AlertDialog.Builder(
                                getActivity());

                        alertDialog.setTitle("Error");
                        alertDialog.setMessage("You cannot sell more than you own.");
                        alertDialog.setCancelable(false);
                        alertDialog.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                // If this button is clicked, close current dialog.
                                dialog.cancel();
                            }
                        });
                        alertDialog.show();

                        // Invalidates transaction since selling amount > buying amount.
                        validTransaction = false;
                    }

                    // Calculations to output.
                    totalCost = buyAmount * buyCost;
                    totalAmount = optimalBTCAmount + remainder;
                    finalPrice = totalCost / totalAmount;

                    if (validTransaction) {
                        resultText.setText(String.format(getString(R.string.resultText),
                                String.valueOf(totalAmount), String.valueOf(roundTwoDecimals(finalPrice))));
                    }
                } catch (Exception e) {
                    // Sets bool to false in order to execute "finally" block below.
                    didItWork = false;
                } finally {
                    if (!didItWork) {
                        // Creates new dialog popup.
                        final AlertDialog.Builder alertDialog2 = new AlertDialog.Builder(getActivity());

                        alertDialog2.setTitle("Error");
                        alertDialog2.setMessage("Please fill in all fields.");
                        alertDialog2.setCancelable(false);
                        alertDialog2.setNeutralButton("Ok", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                // If this button is clicked, close current dialog.
                                dialog.cancel();
                            }
                        });

                        // Show the dialog.
                        alertDialog2.show();
                    }
                }

            }
        });
    }

    public void showSoftKeyboard(View view) {
        if (view.requestFocus()) {
            InputMethodManager imm = (InputMethodManager) getActivity()
                    .getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.menu, menu);
        this.menu = menu;
        updateMenuTitles();
        enableMenuItems();
    }

    // When Options Menu items are selected; adds or removes the current price from their corresponding fields.
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        /*
        0 represents the buy field
        1 represents the sell field
        */

        View view = getView();
        if (view == null) {
            return false;
        }

        switch (item.getItemId()) {
        case R.id.editCurrentBuyField: {
            try {
                EditText btcBoughtPrice = (EditText) view.findViewById(R.id.btcBoughtPrice);

                // If field contains the current price, remove it; else, add the current price.
                if (containsCurrentRate[0]) {
                    btcBoughtPrice.setText("");
                    containsCurrentRate[0] = false;
                } else {
                    btcBoughtPrice.setText(rate);
                    containsCurrentRate[0] = true;
                }
            } catch (Exception ignored) {
            }
            break;
        }
        case R.id.editCurrentSellField: {
            try {
                EditText btcSoldPrice = (EditText) view.findViewById(R.id.btcSoldPrice);

                // If field contains the current price, remove it; else, add the current price.
                if (containsCurrentRate[1]) {
                    btcSoldPrice.setText("");
                    containsCurrentRate[1] = false;
                } else {
                    btcSoldPrice.setText(rate);
                    containsCurrentRate[1] = true;
                }
            } catch (Exception ignored) {
            }
            break;
        }
        case R.id.resetAll: {
            btcBought.setText("");
            btcBoughtPrice.setText("");
            btcSold.setText("");
            btcSoldPrice.setText("");
            optimalBTC.setText("");
            optimalBTCPrice.setText("");
            resultText.setText("");
            containsCurrentRate[0] = containsCurrentRate[1] = false;
            break;
        }
        case R.id.aboutPage: {
            startActivity(new Intent(getContext(), AboutActivity.class));
        }
        default:
            return super.onOptionsItemSelected(item);
        }

        updateMenuTitles();
        return true;
    }

    private void enableMenuItems() {
        MenuItem buy = menu.findItem(R.id.editCurrentBuyField);
        MenuItem sell = menu.findItem(R.id.editCurrentSellField);
        MenuItem reset = menu.findItem(R.id.resetAll);

        if (!buy.isEnabled())
            buy.setEnabled(true);
        if (!sell.isEnabled())
            sell.setEnabled(true);
        if (!reset.isEnabled())
            reset.setEnabled(true);
    }

    private void updateMenuTitles() {
        MenuItem buy = menu.findItem(R.id.editCurrentBuyField);
        MenuItem sell = menu.findItem(R.id.editCurrentSellField);

        if (containsCurrentRate[0])
            buy.setTitle(R.string.removeBuyField);
        else
            buy.setTitle(R.string.addBuyField);

        if (containsCurrentRate[1])
            sell.setTitle(R.string.removeSellField);
        else
            sell.setTitle(R.string.addSellField);
    }
}