package com.nauk.coinfolio.DataManagers; import android.os.StrictMode; import android.util.Log; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.Volley; import com.nauk.coinfolio.DataManagers.CurrencyData.Currency; import com.nauk.coinfolio.DataManagers.ExchangeManager.BinanceManager; import com.nauk.coinfolio.DataManagers.ExchangeManager.HitBtcManager; import com.nauk.coinfolio.R; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.regex.Pattern; /** * Created by Tiji on 25/12/2017. */ public class BalanceManager { private String publicHitKey; private String publicBinanceKey; private String publicPoloniex; private String privateHitKey; private String privateBinanceKey; private String privatePoloniex; final private String hitBalanceUrl = "https://api.hitbtc.com/api/2/trading/balance"; final private String detailUrl = "https://www.cryptocompare.com/api/data/coinlist/"; private RequestQueue requestQueue; private List<Currency> binanceBalance; private List<Currency> hitBalance; private List<Currency> manualBalances; private List<Currency> totalBalance; private android.content.Context context; private LinkedHashMap<String, String> coinInfosHashmap; private PreferencesManager preferenceManager; private DatabaseManager databaseManager; private int balanceCounter; //NEW IMPLEMENTATION private List<HitBtcManager> hitBtcManagers; private List<BinanceManager> binanceManagers; public BalanceManager(android.content.Context context) { this.context = context; preferenceManager = new PreferencesManager(context); requestQueue = Volley.newRequestQueue(context); binanceBalance = new ArrayList<Currency>(); hitBalance = new ArrayList<Currency>(); manualBalances = new ArrayList<Currency>(); databaseManager = new DatabaseManager(context); hitBtcManagers = new ArrayList<>(); binanceManagers = new ArrayList<>(); balanceCounter = 0; } public List<String> getCurrenciesName() { List<String> currenciesName = new ArrayList<>(); for (String symbol : coinInfosHashmap.keySet()) { try { JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol)); currenciesName.add(jsonObject.getString("CoinName")); } catch (JSONException e) { e.printStackTrace(); } } return currenciesName; } public List<String> getBiggestCurrencies() { List<String> currenciesDetails = new ArrayList<>(); int index = 0; Iterator<String> coinIterator = coinInfosHashmap.keySet().iterator(); while(index < 11) { index++; Log.d("coinfolio", "For " + index + " : " + coinIterator.next()); } return currenciesDetails; } public List<String> getOrders() { List<String> currenciesOrder = new ArrayList<>(); for(String symbol : coinInfosHashmap.keySet()) { try { JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol)); currenciesOrder.add(jsonObject.getString("SortOrder")); } catch (JSONException e) { e.printStackTrace(); } } return currenciesOrder; } public List<String> getCurrenciesSymbol() { return new ArrayList<>(coinInfosHashmap.keySet()); } public void updateExchangeKeys() { String publicKey = preferenceManager.getHitBTCPublicKey(); String privateKey = preferenceManager.getHitBTCPrivateKey(); hitBtcManagers.clear(); if(publicKey != null && privateKey != null && preferenceManager.isHitBTCActivated()) { hitBtcManagers.add(new HitBtcManager(context, publicKey, privateKey)); } publicKey = preferenceManager.getBinancePublicKey(); privateKey = preferenceManager.getBinancePrivateKey(); binanceManagers.clear(); if(publicKey != null && privateKey != null && preferenceManager.isBinanceActivated()) { binanceManagers.add(new BinanceManager(publicKey, privateKey)); } } public List<Currency> getTotalBalance() { return totalBalance; } public void updateTotalBalance(final VolleyCallBack callBack) { boolean isUpdated = false; manualBalances = databaseManager.getAllCurrencyFromManualCurrency(); if(binanceManagers.size() > 0) { isUpdated = true; for(int i = 0; i < binanceManagers.size(); i++) { binanceManagers.get(i).updateBalance(new BinanceManager.BinanceCallBack() { @Override public void onSuccess() { countBalances(callBack); } @Override public void onError(String error) { callBack.onError(error); } }); } } if(hitBtcManagers.size() > 0) { isUpdated = true; for(int i = 0; i < hitBtcManagers.size(); i++) { hitBtcManagers.get(i).updateBalance(new HitBtcManager.HitBtcCallBack() { @Override public void onSuccess() { countBalances(callBack); } @Override public void onError(String error) { callBack.onError(error); } }); } } if(!isUpdated) { refreshAllBalances(callBack); } } private void countBalances(VolleyCallBack callBack) { balanceCounter++; if(balanceCounter == hitBtcManagers.size() + binanceManagers.size()) { refreshAllBalances(callBack); balanceCounter = 0; } } private void refreshAllBalances(final VolleyCallBack callBack) { totalBalance = new ArrayList<>(); for(int i = 0; i < hitBtcManagers.size(); i++) { mergeBalanceTotal(hitBtcManagers.get(i).getBalance()); } for(int i = 0; i < binanceManagers.size(); i++) { mergeBalanceTotal(binanceManagers.get(i).getBalance()); } mergeBalanceTotal(manualBalances); callBack.onSuccess(); } private void mergeBalanceTotal(List<Currency> balance) { if(balance != null) { for(int i = 0; i < balance.size(); i++) { boolean isIn = false; for(int j = 0; j < totalBalance.size(); j++) { if(balance.get(i).getSymbol().equals(totalBalance.get(j).getSymbol())) { totalBalance.get(j).setBalance(totalBalance.get(j).getBalance() + balance.get(i).getBalance()); isIn = true; } } if(!isIn) { totalBalance.add(balance.get(i)); } } } } public interface VolleyCallBack { void onSuccess(); void onError(String error); } public interface IconCallBack { void onSuccess(); } public void sortCoins() { for(int i = 0; i < totalBalance.size(); i++) { for(int j = i; j < totalBalance.size(); j++) { if(totalBalance.get(j).getBalance() * totalBalance.get(j).getValue() > totalBalance.get(i).getBalance() * totalBalance.get(i).getValue()) { Currency temp = totalBalance.get(j); totalBalance.set(j, totalBalance.get(i)); totalBalance.set(i, temp); } } } } public void updateDetails(final IconCallBack callBack) { StringRequest strRequest = new StringRequest(Request.Method.GET, detailUrl, new Response.Listener<String>() { @Override public void onResponse(String response) { if (response.length() > 0) { processDetailResult(response, callBack); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } }); requestQueue.add(strRequest); } public String getIconUrl(String symbol) { String url; try { JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol)); url = "https://www.cryptocompare.com" + jsonObject.getString("ImageUrl") + "?width=50"; } catch (NullPointerException e) { Log.d(context.getResources().getString(R.string.debug), symbol + " has no icon URL"); url = null; } catch (JSONException e) { Log.d(context.getResources().getString(R.string.debug), "Url parsing error for " + symbol); url = null; } return url; } public String getCurrencyName(String symbol) { String currencyName = null; try { JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol)); currencyName = jsonObject.getString("CoinName"); } catch (JSONException e) { e.printStackTrace(); } return currencyName; } public int getCurrencyId(String symbol) { int id = 0; try { JSONObject jsonObject = new JSONObject(coinInfosHashmap.get(symbol)); id = jsonObject.getInt("Id"); } catch (JSONException e) { e.printStackTrace(); } return id; } private void processDetailResult(String response, final IconCallBack callBack) { response = response.substring(response.indexOf("\"Data\"") + 7, response.lastIndexOf("},\"Type\":100}")); String[] tab = response.split(Pattern.quote("},")); coinInfosHashmap = new LinkedHashMap<>(); for(int i = 0; i < tab.length; i++) { tab[i] = tab[i].substring(tab[i].indexOf("\":{")+2, tab[i].length()) + "}"; try { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); JSONObject jsonObject = new JSONObject(tab[i]); coinInfosHashmap.put(jsonObject.getString("Symbol"), tab[i]); } catch (JSONException e) { Log.d(context.getResources().getString(R.string.debug), "ImageUrl not found."); } } sortDetails(); callBack.onSuccess(); } private void sortDetails() { LinkedHashMap<String, String> sortedHashmap = new LinkedHashMap<>(); List<String> listInfos = new ArrayList<>(coinInfosHashmap.values()); List<String> listSymbols = new ArrayList<>(coinInfosHashmap.keySet()); for(int i = 0; i < coinInfosHashmap.keySet().size(); i++) { try { JSONObject jsonObject = new JSONObject(listInfos.get(i)); int index = jsonObject.getInt("SortOrder"); listInfos.add(index, listInfos.get(i)); listSymbols.add(index, listSymbols.get(i)); } catch (JSONException e) { e.printStackTrace(); } } for(int i = 0; i < listInfos.size(); i++) { sortedHashmap.put(listSymbols.get(i), listInfos.get(i)); } coinInfosHashmap = sortedHashmap; } }