package com.thanksmister.btcblue.ui;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.widget.SwipeRefreshLayout;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;
import android.widget.TextView;
import com.squareup.sqlbrite.SqlBrite;
import com.thanksmister.btcblue.R;
import com.thanksmister.btcblue.data.ExchangeService;
import com.thanksmister.btcblue.data.api.model.Exchange;
import com.thanksmister.btcblue.db.DbManager;
import com.thanksmister.btcblue.ui.spinner.ExchangeAdapter;
import com.thanksmister.btcblue.utils.Calculations;
import com.thanksmister.btcblue.utils.Conversions;
import com.thanksmister.btcblue.utils.Dates;
import java.util.List;
import javax.inject.Inject;
import butterknife.ButterKnife;
import butterknife.InjectView;
import rx.Observable;
import rx.Subscription;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.subscriptions.Subscriptions;
import static rx.android.app.AppObservable.bindActivity;
public class MainActivity extends BaseActivity implements View.OnClickListener, SwipeRefreshLayout.OnRefreshListener, AppBarLayout.OnOffsetChangedListener
{
@Inject
ExchangeService exchangeService;
@Inject
DbManager dbManager;
@InjectView(R.id.dataFrom)
TextView dataFrom;
@InjectView(R.id.date)
TextView date;
@InjectView(R.id.averageUSDB)
TextView averageUSDB;
@InjectView(R.id.titleUSDB)
TextView titleUSDB;
@InjectView(R.id.askUSDB)
TextView askUSDB;
@InjectView(R.id.bidUSDB)
TextView bidUSDB;
@InjectView(R.id.officialUSDB)
TextView officialUSDB;
@InjectView(R.id.averageUSD)
TextView averageUSD;
@InjectView(R.id.titleUSD)
TextView titleUSD;
@InjectView(R.id.askUSD)
TextView askUSD;
@InjectView(R.id.bidUSD)
TextView bidUSD;
@InjectView(R.id.officialUSD)
TextView officialUSD;
@InjectView(R.id.averageARS)
TextView averageARS;
@InjectView(R.id.titleARS)
TextView titleARS;
@InjectView(R.id.askARS)
TextView askARS;
@InjectView(R.id.bidARS)
TextView bidARS;
@InjectView(R.id.officialARS)
TextView officialARS;
@InjectView(R.id.swipeLayout)
SwipeRefreshLayout swipeLayout;
@InjectView(R.id.appBarLayout)
AppBarLayout appBarLayout;
@InjectView(R.id.exchangeSpinner)
Spinner exchangeSpinner;
@InjectView(R.id.fab)
FloatingActionButton fab;
@InjectView(android.R.id.progress)
View progress;
@InjectView(R.id.content)
View content;
Handler handler;
ExchangeAdapter adapter;
private Observable<List<Exchange>> exchangeObservable;
private Observable<List<Exchange>> exchangeUpdateObservable;
Subscription subscription = Subscriptions.empty();
Subscription updateSubscription = Subscriptions.empty();
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorSchemeColors(getResources().getColor(R.color.blue));
handler = new Handler();
// setup adapter
adapter = new ExchangeAdapter(this, R.layout.spinner_dropdown);
// database data
exchangeObservable = bindActivity(this, dbManager.exchangeQuery());
// update data
exchangeUpdateObservable = bindActivity(this, exchangeService.getExchangesObservable());
setupSpinner();
setupFab();
setFromText();
}
@Override
public void onResume()
{
super.onResume();
appBarLayout.addOnOffsetChangedListener(this);
onRefreshStart();
subscribeData();
updateData();
}
@Override
public void onPause()
{
super.onPause();
appBarLayout.removeOnOffsetChangedListener(this);
subscription.unsubscribe();
updateSubscription.unsubscribe();
handler.removeCallbacks(refreshRunnable);
}
@Override
public void onRefresh()
{
updateData();
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i)
{
if (i == 0) {
swipeLayout.setEnabled(true);
} else {
swipeLayout.setEnabled(false);
}
}
private void onRefreshStart()
{
handler.postDelayed(refreshRunnable, 1000);
}
private void onRefreshStop()
{
handler.removeCallbacks(refreshRunnable);
swipeLayout.setRefreshing(false);
}
private void onProgress(boolean show)
{
progress.setVisibility((show)? View.VISIBLE: View.GONE);
content.setVisibility((show) ? View.GONE : View.VISIBLE);
}
private Runnable refreshRunnable = new Runnable()
{
@Override
public void run()
{
swipeLayout.setRefreshing(true);
}
};
private void setupFab()
{
fab.setOnClickListener(this);
}
private void setupSpinner()
{
exchangeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l)
{
Exchange exchange = (Exchange) adapterView.getAdapter().getItem(i);
exchangeService.setSelectedExchange(exchange.getDisplay_name());
setExchange(exchange);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView)
{
}
});
}
@Override
public void onClick(View view)
{
if (view.getId() == R.id.fab) {
Intent intent = CalculatorActivity.createStartIntent(MainActivity.this);
startActivity(intent);
}
}
public void subscribeData()
{
subscription = exchangeObservable.subscribe(new Action1<List<Exchange>>()
{
@Override
public void call(List<Exchange> exchanges)
{
if(!exchanges.isEmpty()) {
onProgress(false);
updateSelectedExchange(exchanges);
} else {
onProgress(true);
}
}
}, new Action1<Throwable>()
{
@Override
public void call(Throwable throwable)
{
onProgress(false);
reportError(throwable);
}
});
}
public void updateData()
{
updateSubscription = exchangeUpdateObservable.subscribe(new Action1<List<Exchange>>()
{
@Override
public void call(List<Exchange> exchanges)
{
onRefreshStop();
dbManager.updateExchanges(exchanges);
}
}, new Action1<Throwable>()
{
@Override
public void call(Throwable throwable)
{
onRefreshStop();
handleError(throwable, getString(R.string.snack_retry), new Action0()
{
@Override
public void call()
{
updateData();
}
});
}
});
}
private void updateSelectedExchange(final List<Exchange> exchanges)
{
String name = exchangeService.getSelectedExchangeName();
int index = 0;
for (Exchange ex:exchanges) {
if(ex.getDisplay_name().equals(name)) {
break;
}
index ++;
}
adapter.setData(exchanges);
setExchangeSpinner(adapter, index);
Exchange selectedExchange = exchanges.get(index);
setExchange(selectedExchange);
}
public void setExchangeSpinner(ExchangeAdapter adapter, int currentSelectedPosition)
{
exchangeSpinner.setAdapter(adapter);
exchangeSpinner.setSelection(currentSelectedPosition);
}
private void setExchange(Exchange exchange)
{
if(exchange == null) return;
setMarketData(exchange, MarketViewType.ARS_USDB);
setMarketData(exchange, MarketViewType.ARS_BTC);
setMarketData(exchange, MarketViewType.USD_BTC);
setDate(exchange);
}
private void setDate(Exchange exchange)
{
Dates.DateDistance dateDistance = Dates.getTimeInDistance(exchange.getCreated_at());
switch (dateDistance) {
case RECENT:
date.setText(Html.fromHtml(getString(R.string.date_updated_text_recent, exchange.getCreated_at())));
break;
case NOT_SO_MUCH:
date.setText(Html.fromHtml(getString(R.string.date_updated_text_stale, exchange.getCreated_at())));
break;
case LONG_GONE:
date.setText(Html.fromHtml(getString(R.string.date_updated_text_old, exchange.getCreated_at())));
break;
}
}
private void setFromText()
{
dataFrom.setText(Html.fromHtml(getString(R.string.data_provided_by)));
dataFrom.setMovementMethod(LinkMovementMethod.getInstance());
}
private enum MarketViewType
{
USD_BTC,
ARS_BTC,
ARS_USDB,
ARS_USD
}
public void setMarketData(Exchange exchange, MarketViewType type)
{
String ask = "";
String bid = "";
String avg = "";
switch (type) {
case ARS_USDB:
averageUSDB.setText(Calculations.calculateAverageBidAskFormatted(exchange.getBlue_bid(), exchange.getBlue_ask()));
titleUSDB.setText(getString(R.string.title_ars_usdb));
askUSDB.setText(Conversions.formatCurrencyAmount(exchange.getBlue_ask()));
bidUSDB.setText(Conversions.formatCurrencyAmount(exchange.getBlue_bid()));
ask = Conversions.formatCurrencyAmount(exchange.getOfficial_ask());
bid = Conversions.formatCurrencyAmount(exchange.getOfficial_bid());
avg = Calculations.calculateAverageBidAskFormatted(bid, ask);
officialUSDB.setText(getString(R.string.official_text_usd, avg));
break;
case ARS_BTC:
ask = Calculations.calculateBlueARSFormatted(exchange.getBlue_ask(), exchange.getAsk());
bid = Calculations.calculateBlueARSFormatted(exchange.getBlue_bid(), exchange.getBid());
averageARS.setText(Calculations.calculateAverageBidAskFormatted(bid, ask));
titleARS.setText(getString(R.string.title_ars_btc));
askARS.setText(Calculations.calculateBlueARSFormatted(exchange.getBlue_ask(), exchange.getAsk()));
bidARS.setText(Calculations.calculateBlueARSFormatted(exchange.getBlue_bid(), exchange.getBid()));
ask = Calculations.calculateBlueARSFormatted(exchange.getOfficial_ask(), exchange.getAsk());
bid = Calculations.calculateBlueARSFormatted(exchange.getOfficial_bid(), exchange.getBid());
avg = Calculations.calculateAverageBidAskFormatted(bid, ask);
officialARS.setText(getString(R.string.official_text_btc, avg));
break;
case USD_BTC:
averageUSD.setText(Calculations.calculateAverageBidAskFormatted(exchange.getBid(), exchange.getAsk()));
titleUSD.setText(getString(R.string.title_usd_btc));
askUSD.setText(Conversions.formatCurrencyAmount(exchange.getAsk()));
bidUSD.setText(Conversions.formatCurrencyAmount(exchange.getBid()));
officialUSD.setVisibility(View.GONE);
break;
}
}
}