package com.sanchez.fmf;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.os.AsyncTask;
import android.os.Build;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.view.WindowManager;
import com.sanchez.fmf.event.GetMarketListFailEvent;
import com.sanchez.fmf.event.GetMarketListSuccessEvent;
import com.sanchez.fmf.event.MapFABClickEvent;
import com.sanchez.fmf.event.MarketsDetailsRetrievedEvent;
import com.sanchez.fmf.event.PlaceTitleResolvedEvent;
import com.sanchez.fmf.event.RetryGetMarketListEvent;
import com.sanchez.fmf.fragment.MarketListFragment;
import com.sanchez.fmf.fragment.MarketMapFragment;
import com.sanchez.fmf.model.MarketDetailModel;
import com.sanchez.fmf.model.MarketDetailResponseModel;
import com.sanchez.fmf.model.MarketListItemModel;
import com.sanchez.fmf.model.MarketListResponseModel;
import com.sanchez.fmf.service.MarketService;
import com.sanchez.fmf.service.RestClient;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import butterknife.ButterKnife;
import de.greenrobot.event.EventBus;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
public class MarketListActivity extends AppCompatActivity {
public static final String TAG = MarketListActivity.class.getSimpleName();
public static final String EXTRA_COORDINATES = "com.sanchez.fmf.extra_coordinates";
public static final String EXTRA_PLACE_TITLE = "com.sanchez.fmf.extra_place_title";
public static final String EXTRA_PLACE_ID = "com.sanchez.fmf.extra_place_id";
public static final String EXTRA_USED_DEVICE_COORDINATES = "com.sanchez.fmf.extra_used_device_coordinates";
// service for USDA API
private MarketService mMarketService;
private volatile HashMap<MarketListItemModel, MarketDetailModel> mMarketDetailResponses = new HashMap<>();
private volatile int mDetailResponses;
private double[] mCoordinates;
private String mPlaceTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_market_list);
ButterKnife.bind(this);
// get coordinates from MainFragment intent to pass to MarketListFragment
mCoordinates = getIntent().getDoubleArrayExtra(EXTRA_COORDINATES);
String placeId = getIntent().getStringExtra(EXTRA_PLACE_ID);
String placeTitle = getIntent().getStringExtra(EXTRA_PLACE_TITLE);
boolean usedDeviceCoordinates = getIntent().getBooleanExtra(EXTRA_USED_DEVICE_COORDINATES, false);
// color nav bar with app color
Window w = getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
w.setNavigationBarColor(getResources().getColor(R.color.primary_dark));
}
if (usedDeviceCoordinates) {
// user clicked "use current location button", meaning we need to reverse geocode
getLocationName(mCoordinates, this);
}
if (null != placeTitle) {
mPlaceTitle = placeTitle;
}
RestClient client = new RestClient();
mMarketService = client.getMarketService();
getMarkets();
FragmentManager fm = getSupportFragmentManager();
fm.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window w = getWindow();
w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
if (fm.getBackStackEntryCount() == 1) {
w.setStatusBarColor(getResources().getColor(android.R.color.transparent));
} else if (fm.getBackStackEntryCount() == 2) {
w.setStatusBarColor(getResources().getColor(R.color.primary_dark));
}
}
}
});
Fragment listFragment = MarketListFragment.newInstance(placeTitle, placeId, usedDeviceCoordinates);
fm.beginTransaction()
.add(R.id.container_market_list_activity, listFragment, MarketListFragment.TAG)
.addToBackStack(MarketListFragment.TAG)
.commit();
}
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().removeStickyEvent(PlaceTitleResolvedEvent.class);
EventBus.getDefault().unregister(this);
super.onStop();
}
// TODO: Stuff this in a worker fragment with setRetainInstance(true)
private void getMarkets() {
/**
* get markets from USDA API
* coordinates[0] is latitude
* coordinates[1] is longitude
*/
mMarketService.getMarkets(mCoordinates[0], mCoordinates[1], new Callback<MarketListResponseModel>() {
@Override
public void success(MarketListResponseModel marketListModel, Response response) {
EventBus.getDefault().postSticky(new GetMarketListSuccessEvent(marketListModel));
getMarketsDetails(marketListModel);
}
@Override
public void failure(RetrofitError error) {
EventBus.getDefault().postSticky(new GetMarketListFailEvent());
Log.e(TAG, error.toString());
}
});
}
private void getMarketsDetails(MarketListResponseModel marketList) {
for (int i = 0; i < marketList.getMarkets().size(); i++) {
getMarketDetails(marketList.getMarkets().get(i), marketList.getMarkets().size());
}
}
private void getMarketDetails(MarketListItemModel market, int marketListSize) {
mMarketService.getMarket(market.getId(), new Callback<MarketDetailResponseModel>() {
@Override
public void success(MarketDetailResponseModel marketDetailResponseModel, Response response) {
MarketDetailModel details = marketDetailResponseModel.getMarketdetails();
mMarketDetailResponses.put(market, details);
mDetailResponses++;
if (mDetailResponses == marketListSize) {
EventBus.getDefault().postSticky(new MarketsDetailsRetrievedEvent(mMarketDetailResponses));
}
}
@Override
public void failure(RetrofitError error) {
Log.e(TAG, error.toString());
}
});
}
private void showMap() {
MarketMapFragment frag = MarketMapFragment.newInstance(mCoordinates, mPlaceTitle);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction()
.replace(R.id.container_market_list_activity, frag, MarketMapFragment.TAG)
.addToBackStack(MarketMapFragment.TAG)
.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_market_list, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// get a location name based on latitude and longitude (reverse geocoding)
public void getLocationName(final double[] coords, Context c) {
new AsyncTask<Void, Integer, String>() {
@Override
protected String doInBackground(Void... arg0) {
Geocoder coder = new Geocoder(c, Locale.ENGLISH);
List<Address> results = null;
try {
results = coder.getFromLocation(coords[0], coords[1], 1);
} catch (IOException e) {
Log.e(TAG, "Error getting location from coordinates");
}
if(results == null || results.size() < 1) {
return getResources().getString(R.string.markets);
}
String result;
if (null != results.get(0).getLocality()) {
result = results.get(0).getLocality();
} else if (null != results.get(0).getSubLocality()) {
result = results.get(0).getSubLocality();
} else {
result = getResources().getString(R.string.markets);
}
return result;
}
@Override
protected void onPostExecute(String result) {
if (result != null) {
mPlaceTitle = result;
EventBus.getDefault().postSticky(new PlaceTitleResolvedEvent(result));
}
}
}.execute();
}
@Override
public void onBackPressed() {
FragmentManager fm = getSupportFragmentManager();
if (fm.getBackStackEntryCount() == 2) {
// Map fragment is on the stack right now, pop it off
fm.popBackStackImmediate();
} else {
finish();
//fm.popBackStackImmediate();
//super.onBackPressed();
}
}
public void onEvent(RetryGetMarketListEvent event) {
getMarkets();
}
public void onEvent(MapFABClickEvent event) {
showMap();
}
}