package net.osmand.plus.liveupdates;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.AttrRes;
import android.support.annotation.ColorInt;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import net.osmand.AndroidUtils;
import net.osmand.PlatformUtil;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.R;
import net.osmand.plus.base.BaseOsmAndFragment;
import net.osmand.plus.liveupdates.CountrySelectionFragment.CountryItem;
import org.apache.commons.logging.Log;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
public class ReportsFragment extends BaseOsmAndFragment implements CountrySelectionFragment.OnFragmentInteractionListener {
public static final int TITLE = R.string.report;
public static final String DOMAIN = "http://download.osmand.net/";
public static final String TOTAL_CHANGES_BY_MONTH_URL_PATTERN = DOMAIN +
"reports/query_report.php?report=total_changes_by_month&month=%s®ion=%s";
public static final String USERS_RANKING_BY_MONTH = DOMAIN +
"reports/query_report.php?report=ranking_users_by_month&month=%s®ion=%s";
public static final String RECIPIENTS_BY_MONTH = DOMAIN +
"reports/query_report.php?report=recipients_by_month&month=%s®ion=%s";
private static final Log LOG = PlatformUtil.getLog(ReportsFragment.class);
public static final String OSM_LIVE_URL = "http://osmand.net/osm_live";
private TextView contributorsTextView;
private TextView editsTextView;
private TextView donationsTextView;
private TextView recipientsTextView;
private Spinner monthReportsSpinner;
private MonthsForReportsAdapter monthsForReportsAdapter;
private CountrySelectionFragment countrySelectionFragment = new CountrySelectionFragment();
private UsersReportFragment userReportFragment = new UsersReportFragment();
private TextView countryNameTextView;
private CountryItem selectedCountryItem;
private ImageView numberOfContributorsIcon;
private ImageView numberOfEditsIcon;
private ImageView donationsIcon;
private ImageView numberOfRecipientsIcon;
private TextView numberOfContributorsTitle;
private TextView numberOfEditsTitle;
private TextView numberOfRecipientsTitle;
private TextView donationsTitle;
private ProgressBar progressBar;
private int inactiveColor;
private int textColorPrimary;
private int textColorSecondary;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_reports, container, false);
monthReportsSpinner = (Spinner) view.findViewById(R.id.monthReportsSpinner);
final View monthButton = view.findViewById(R.id.monthButton);
monthReportsSpinner.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
event.offsetLocation(AndroidUtils.dpToPx(getActivity(), 48f), 0);
monthButton.onTouchEvent(event);
return true;
}
});
monthsForReportsAdapter = new MonthsForReportsAdapter(getActivity());
monthReportsSpinner.setAdapter(monthsForReportsAdapter);
monthButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
monthReportsSpinner.performClick();
}
});
view.findViewById(R.id.show_all).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(OSM_LIVE_URL));
startActivity(intent);
}
});
((TextView) view.findViewById(R.id.osm_live_url_label)).setText(OSM_LIVE_URL);
View regionReportsButton = view.findViewById(R.id.reportsButton);
regionReportsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
countrySelectionFragment.show(getChildFragmentManager(), "CountriesSearchSelectionFragment");
}
});
OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View v) {
int monthItemPosition = monthReportsSpinner.getSelectedItemPosition();
String monthUrlString = monthsForReportsAdapter.getQueryString(monthItemPosition);
String countryUrlString = selectedCountryItem.getDownloadName();
if (countryUrlString.length() > 0) {
Bundle bl = new Bundle();
bl.putString(UsersReportFragment.URL_REQUEST,
String.format(USERS_RANKING_BY_MONTH, monthUrlString, countryUrlString));
userReportFragment.setArguments(bl);
userReportFragment.show(getChildFragmentManager(), "NumberOfEditsFramgnet");
}
}
};
view.findViewById(R.id.numberOfContributorsLayout).setOnClickListener(listener);
view.findViewById(R.id.numberOfEditsLayout).setOnClickListener(listener);
countrySelectionFragment.initCountries(getMyApplication());
selectedCountryItem = countrySelectionFragment.getCountryItems().get(0);
countryNameTextView = (TextView) regionReportsButton.findViewById(android.R.id.text1);
countryNameTextView.setText(selectedCountryItem.getLocalName());
setThemedDrawable(view, R.id.calendarImageView, R.drawable.ic_action_data);
setThemedDrawable(view, R.id.monthDropDownIcon, R.drawable.ic_action_arrow_drop_down);
setThemedDrawable(view, R.id.regionIconImageView, R.drawable.ic_world_globe_dark);
setThemedDrawable(view, R.id.countryDropDownIcon, R.drawable.ic_action_arrow_drop_down);
numberOfContributorsIcon = (ImageView) view.findViewById(R.id.numberOfContributorsIcon);
numberOfEditsIcon = (ImageView) view.findViewById(R.id.numberOfEditsIcon);
numberOfRecipientsIcon = (ImageView) view.findViewById(R.id.numberOfRecipientsIcon);
donationsIcon = (ImageView) view.findViewById(R.id.donationsIcon);
setThemedDrawable(numberOfContributorsIcon, R.drawable.ic_action_group2);
setThemedDrawable(numberOfRecipientsIcon, R.drawable.ic_group);
setThemedDrawable(donationsIcon, R.drawable.ic_action_bitcoin);
setThemedDrawable(numberOfEditsIcon, R.drawable.ic_map);
numberOfContributorsTitle = (TextView) view.findViewById(R.id.numberOfContributorsTitle);
numberOfEditsTitle = (TextView) view.findViewById(R.id.numberOfEditsTitle);
donationsTitle = (TextView) view.findViewById(R.id.donationsTitle);
numberOfRecipientsTitle = (TextView) view.findViewById(R.id.numberOfRecipientsTitle);
progressBar = (ProgressBar) view.findViewById(R.id.progress);
contributorsTextView = (TextView) view.findViewById(R.id.contributorsTextView);
editsTextView = (TextView) view.findViewById(R.id.editsTextView);
donationsTextView = (TextView) view.findViewById(R.id.donationsTextView);
recipientsTextView = (TextView) view.findViewById(R.id.recipientsTextView);
requestAndUpdateUi();
AdapterView.OnItemSelectedListener onItemSelectedListener = new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
requestAndUpdateUi();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
};
monthReportsSpinner.setOnItemSelectedListener(onItemSelectedListener);
inactiveColor = getColorFromAttr(R.attr.plugin_details_install_header_bg);
textColorPrimary = getColorFromAttr(android.R.attr.textColorPrimary);
textColorSecondary = getColorFromAttr(android.R.attr.textColorSecondary);
return view;
}
public void requestAndUpdateUi() {
int monthItemPosition = monthReportsSpinner.getSelectedItemPosition();
String monthUrlString = monthsForReportsAdapter.getQueryString(monthItemPosition);
String countryUrlString = selectedCountryItem.getDownloadName();
tryUpdateData(monthUrlString, countryUrlString);
}
private void tryUpdateData(String monthUrlString, String regionUrlString) {
GetJsonAsyncTask.OnResponseListener<Protocol.TotalChangesByMonthResponse> onResponseListener =
new GetJsonAsyncTask.OnResponseListener<Protocol.TotalChangesByMonthResponse>() {
@Override
public void onResponse(Protocol.TotalChangesByMonthResponse response) {
if (response != null) {
if (contributorsTextView != null) {
contributorsTextView.setText(String.valueOf(response.users));
}
if (editsTextView != null) {
editsTextView.setText(String.valueOf(response.changes));
}
}
disableProgress();
}
};
GetJsonAsyncTask.OnErrorListener onErrorListener =
new GetJsonAsyncTask.OnErrorListener() {
@Override
public void onError(String error) {
if (contributorsTextView != null) {
contributorsTextView.setText(R.string.data_is_not_available);
}
if (editsTextView != null) {
editsTextView.setText(R.string.data_is_not_available);
}
disableProgress();
}
};
enableProgress();
GetJsonAsyncTask<Protocol.TotalChangesByMonthResponse> totalChangesByMontAsyncTask =
new GetJsonAsyncTask<>(Protocol.TotalChangesByMonthResponse.class);
totalChangesByMontAsyncTask.setOnResponseListener(onResponseListener);
totalChangesByMontAsyncTask.setOnErrorListener(onErrorListener);
String finalUrl = String.format(TOTAL_CHANGES_BY_MONTH_URL_PATTERN, monthUrlString, regionUrlString);
totalChangesByMontAsyncTask.execute(finalUrl);
GetJsonAsyncTask<Protocol.RecipientsByMonth> recChangesByMontAsyncTask =
new GetJsonAsyncTask<>(Protocol.RecipientsByMonth.class);
GetJsonAsyncTask.OnResponseListener<Protocol.RecipientsByMonth> recResponseListener =
new GetJsonAsyncTask.OnResponseListener<Protocol.RecipientsByMonth>() {
@Override
public void onResponse(Protocol.RecipientsByMonth response) {
if (response != null) {
if (recipientsTextView != null) {
recipientsTextView.setText(String.valueOf(response.regionCount));
}
if (donationsTextView != null) {
donationsTextView.setText(String.format("%.3f", response.regionBtc*1000.0) + " mBTC");
}
}
disableProgress();
}
};
recChangesByMontAsyncTask.setOnResponseListener(recResponseListener);
if (recipientsTextView != null) {
recipientsTextView.setText("-");
}
if (donationsTextView != null) {
donationsTextView.setText("-");
}
String recfinalUrl = String.format(RECIPIENTS_BY_MONTH, monthUrlString, regionUrlString);
recChangesByMontAsyncTask.execute(recfinalUrl);
}
@Override
public void onSearchResult(CountryItem item) {
selectedCountryItem = item;
countryNameTextView.setText(item.getLocalName());
requestAndUpdateUi();
}
private static class MonthsForReportsAdapter extends ArrayAdapter<String> {
private static final SimpleDateFormat queryFormat = new SimpleDateFormat("yyyy-MM", Locale.US);
@SuppressLint("SimpleDateFormat")
private static final SimpleDateFormat humanFormat = new SimpleDateFormat("LLLL yyyy");
ArrayList<String> queryString = new ArrayList<>();
public MonthsForReportsAdapter(Context context) {
super(context, android.R.layout.simple_spinner_item);
Calendar startDate = Calendar.getInstance();
startDate.set(Calendar.MONTH, Calendar.SEPTEMBER);
startDate.set(Calendar.YEAR, 2015);
startDate.set(Calendar.DAY_OF_MONTH, 1);
startDate.set(Calendar.HOUR_OF_DAY, 0);
Calendar endDate = Calendar.getInstance();
while (startDate.before(endDate)) {
queryString.add(queryFormat.format(endDate.getTime()));
add(humanFormat.format(endDate.getTime()));
endDate.add(Calendar.MONTH, -1);
}
setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
}
public String getQueryString(int position) {
return queryString.get(position);
}
}
public static class GetJsonAsyncTask<P> extends AsyncTask<String, Void, P> {
private static final Log LOG = PlatformUtil.getLog(GetJsonAsyncTask.class);
private final Class<P> protocolClass;
private final Gson gson = new Gson();
private OnResponseListener<P> onResponseListener;
private OnErrorListener onErrorListener;
private volatile String error;
public GetJsonAsyncTask(Class<P> protocolClass) {
this.protocolClass = protocolClass;
}
@Override
protected P doInBackground(String... params) {
StringBuilder response = new StringBuilder();
error = NetworkUtils.sendGetRequest(params[0], null, response);
if (error == null) {
try {
return gson.fromJson(response.toString(), protocolClass);
} catch (JsonSyntaxException e) {
error = e.getLocalizedMessage();
}
}
LOG.error(error);
return null;
}
@Override
protected void onPostExecute(P protocol) {
if (protocol != null) {
if(onResponseListener != null) {
onResponseListener.onResponse(protocol);
}
} else if (onErrorListener != null) {
onErrorListener.onError(error);
}
}
public void setOnResponseListener(OnResponseListener<P> onResponseListener) {
this.onResponseListener = onResponseListener;
}
public void setOnErrorListener(OnErrorListener onErrorListener) {
this.onErrorListener = onErrorListener;
}
public interface OnResponseListener<Protocol> {
void onResponse(Protocol response);
}
public interface OnErrorListener {
void onError(String error);
}
}
private void enableProgress() {
numberOfContributorsIcon.setImageDrawable(getPaintedContentIcon(R.drawable.ic_group, inactiveColor));
numberOfEditsIcon.setImageDrawable(getPaintedContentIcon(R.drawable.ic_map, inactiveColor));
numberOfRecipientsIcon.setImageDrawable(getPaintedContentIcon(R.drawable.ic_group, inactiveColor));
donationsIcon.setImageDrawable(getPaintedContentIcon(R.drawable.ic_action_bitcoin, inactiveColor));
numberOfContributorsTitle.setTextColor(inactiveColor);
numberOfEditsTitle.setTextColor(inactiveColor);
numberOfRecipientsTitle.setTextColor(inactiveColor);
donationsTitle.setTextColor(inactiveColor);
progressBar.setVisibility(View.VISIBLE);
contributorsTextView.setTextColor(inactiveColor);
donationsTextView.setTextColor(inactiveColor);
recipientsTextView.setTextColor(inactiveColor);
editsTextView.setTextColor(inactiveColor);
}
private void disableProgress() {
numberOfContributorsIcon.setImageDrawable(getContentIcon(R.drawable.ic_group));
numberOfEditsIcon.setImageDrawable(getContentIcon(R.drawable.ic_map));
numberOfRecipientsIcon.setImageDrawable(getContentIcon(R.drawable.ic_group));
donationsIcon.setImageDrawable(getContentIcon(R.drawable.ic_action_bitcoin));
numberOfContributorsTitle.setTextColor(textColorSecondary);
numberOfEditsTitle.setTextColor(textColorSecondary);
numberOfRecipientsTitle.setTextColor(textColorSecondary);
donationsTitle.setTextColor(textColorSecondary);
progressBar.setVisibility(View.INVISIBLE);
contributorsTextView.setTextColor(textColorPrimary);
editsTextView.setTextColor(textColorPrimary);
donationsTextView.setTextColor(textColorPrimary);
recipientsTextView.setTextColor(textColorPrimary);
}
@ColorInt
private int getColorFromAttr(@AttrRes int colorAttribute) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = getActivity().getTheme();
theme.resolveAttribute(colorAttribute, typedValue, true);
return typedValue.data;
}
}