package net.wigle.wigleandroid;
import android.annotation.SuppressLint;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.view.MenuItemCompat;
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.widget.ScrollView;
import android.widget.TextView;
import net.wigle.wigleandroid.background.ApiDownloader;
import net.wigle.wigleandroid.background.ApiListener;
import net.wigle.wigleandroid.background.DownloadHandler;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
public class UserStatsFragment extends Fragment {
public static final int MSG_USER_DONE = 101;
private static final int MENU_SITE_STATS = 201;
private static final int MENU_RANK_STATS = 202;
/*
{
imageBadgeUrl: "/bi/64f3oBpg41EH9bOo2TXr0w.png",
monthRank: 128,
rank: 44,
statistics : {
discoveredCell: 6766,
discoveredCellGPS: 3702,
discoveredWiFi: 1305884,
discoveredWiFiGPS: 668555,
discoveredWiFiGPSPercent: 0,
eventMonthCount: 743,
eventPrevMonthCount: 10908,
first: "20011125-00000",
last: "20170101-00928",
monthRank: 128,
prevMonthRank: 128,
prevRank: 44,
rank: 44,
self : true,
totalWiFiLocations: 12255273,
userName: "arkasha"
}
success: true,
user: "arkasha"
}
*/
public static final String KEY_RANK = "rank";
private static final String KEY_PREV_RANK = "prevRank";
public static final String KEY_MONTH_RANK = "monthRank";
private static final String KEY_PREV_MONTH_RANK = "prevMonthRank";
private static final String KEY_DISCOVERED = "discoveredWiFiGPS";
private static final String KEY_TOTAL = "discoveredWiFi";
private static final String KEY_TOTAL_LOCS = "totalWiFiLocations";
private static final String KEY_GEN_DISC = "discoveredCellGPS";
private static final String KEY_GEN_TOTAL = "discoveredCell";
private static final String KEY_MONTH_COUNT = "eventMonthCount";
private static final String KEY_PREV_MONTH = "eventPrevMonthCount";
private static final String KEY_FIRST_TRANS = "first";
private static final String KEY_LAST_TRANS = "last";
public static final String KEY_IS_CACHE = "iscache";
private static final int COLOR_UP = Color.rgb(30, 200, 30);
private static final int COLOR_DOWN = Color.rgb(200, 30, 30);
private static final int COLOR_BLANK = Color.rgb(80, 80, 80);
private static final String[] ALL_USER_KEYS = new String[] {
KEY_RANK, KEY_PREV_RANK, KEY_MONTH_RANK, KEY_PREV_MONTH_RANK, KEY_DISCOVERED, KEY_TOTAL, KEY_TOTAL_LOCS,
KEY_GEN_DISC, KEY_GEN_TOTAL, KEY_MONTH_COUNT, KEY_PREV_MONTH, KEY_FIRST_TRANS, KEY_LAST_TRANS,
};
private AtomicBoolean finishing;
private NumberFormat numberFormat;
/** Called when the activity is first created. */
@Override
public void onCreate( final Bundle savedInstanceState ) {
MainActivity.info("USERSTATS: onCreate");
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
// set language
MainActivity.setLocale(getActivity());
// media volume
getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC);
finishing = new AtomicBoolean(false);
numberFormat = NumberFormat.getNumberInstance(Locale.US);
if (numberFormat instanceof DecimalFormat) {
numberFormat.setMinimumFractionDigits(0);
numberFormat.setMaximumFractionDigits(2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final int orientation = getResources().getConfiguration().orientation;
MainActivity.info("USERSTATS: onCreateView. orientation: " + orientation);
final ScrollView scrollView = (ScrollView) inflater.inflate(R.layout.userstats, container, false);
final Handler handler = new UserDownloadHandler(scrollView, numberFormat, getActivity().getPackageName(),
getResources());
executeUserDownload(this, new UserDownloadApiListener(handler));
return scrollView;
}
public static void executeUserDownload(final Fragment fragment, final ApiListener apiListener) {
final ApiDownloader task = new ApiDownloader(fragment.getActivity(), ListFragment.lameStatic.dbHelper,
"user-stats-cache.json", MainActivity.USER_STATS_URL, false, true, true,
ApiDownloader.REQUEST_GET,
apiListener);
try {
task.startDownload(fragment);
} catch (WiGLEAuthException waex) {
MainActivity.info("User Stats Download Failed due to failed auth");
}
}
public static class UserDownloadApiListener implements ApiListener {
final Handler handler;
public UserDownloadApiListener(final Handler handler) {
this.handler = handler;
}
@Override
public void requestComplete(final JSONObject json, final boolean isCache) {
MainActivity.info("handleUserStats");
if (json == null) {
MainActivity.info("handleUserStats null json, returning");
return;
}
// MainActivity.info("user stats: " + json);
final Bundle bundle = new Bundle();
bundle.putBoolean(KEY_IS_CACHE, isCache);
try {
if (!json.getBoolean("success")) {
MainActivity.info("handleUserStats json success is false");
bundle.putString("error", "Unable to load user statistics.");
} else {
if (json.isNull("statistics")) {
MainActivity.info("handleUserStats json stats null, returning");
bundle.putString("error", "Unable to load user statistics.");
} else {
final JSONObject stats = json.getJSONObject("statistics");
for (final String key : ALL_USER_KEYS) {
final JSONObject lookupJson = (KEY_RANK.equals(key) || KEY_MONTH_RANK.equals(key)) ? json : stats;
if (!lookupJson.has(key)) continue;
switch (key) {
case KEY_FIRST_TRANS:
case KEY_LAST_TRANS:
bundle.putString(key, lookupJson.getString(key));
break;
default:
bundle.putLong(key, lookupJson.getLong(key));
}
}
}
}
} catch (final JSONException ex) {
MainActivity.error("json error: " + ex, ex);
} catch (final Exception e) {
MainActivity.error("user stats error: " + e, e);
}
final Message message = new Message();
message.setData(bundle);
message.what = MSG_USER_DONE;
handler.sendMessage(message);
}
}
private final static class UserDownloadHandler extends DownloadHandler {
private UserDownloadHandler(final View view, final NumberFormat numberFormat, final String packageName,
final Resources resources) {
super(view, numberFormat, packageName, resources);
}
@SuppressLint("SetTextI18n")
@Override
public void handleMessage(final Message msg) {
final Bundle bundle = msg.getData();
if (msg.what == MSG_USER_DONE) {
if (bundle.containsKey("error")) {
MainActivity.info("handleMessage error loading user stats. TODO: show warning");
} else {
TextView tv;
for (final String key : ALL_USER_KEYS) {
int id = resources.getIdentifier(key, "id", packageName);
tv = (TextView) view.findViewById(id);
switch (key) {
case KEY_FIRST_TRANS:
case KEY_LAST_TRANS:
tv.setText(bundle.getString(key));
break;
case KEY_PREV_RANK: {
final long diff = bundle.getLong(key) - bundle.getLong(KEY_RANK);
diffToString(diff, tv);
tv = (TextView) view.findViewById(R.id.actual_prevrank);
tv.setText(numberFormat.format(bundle.getLong(key)));
break;
}
case KEY_PREV_MONTH_RANK: {
final long diff = bundle.getLong(key) - bundle.getLong(KEY_MONTH_RANK);
diffToString(diff, tv);
tv = (TextView) view.findViewById(R.id.actual_prevmonthrank);
tv.setText(numberFormat.format(bundle.getLong(key)));
break;
}
default:
tv.setText(numberFormat.format(bundle.getLong(key)));
}
}
}
}
}
}
@SuppressLint("SetTextI18n")
public static void diffToString(final long diff, final TextView tv) {
if (diff == 0) {
tv.setText("");
tv.setTextColor(COLOR_BLANK);
return;
}
String plus = " ";
if (diff > 0) {
plus = " ↑";
tv.setTextColor(COLOR_UP);
}
else if (diff < 0) {
plus = " ↓";
tv.setTextColor(COLOR_DOWN);
}
tv.setText(plus + Long.toString(diff));
}
@Override
public void onDestroy() {
MainActivity.info( "STATS: onDestroy" );
finishing.set( true );
super.onDestroy();
}
@Override
public void onResume() {
MainActivity.info("STATS: onResume");
super.onResume();
getActivity().setTitle(R.string.user_stats_app_name);
}
@Override
public void onStart() {
MainActivity.info( "STATS: onStart" );
super.onStart();
}
@Override
public void onPause() {
MainActivity.info( "STATS: onPause" );
super.onPause();
}
@Override
public void onStop() {
MainActivity.info( "STATS: onStop" );
super.onStop();
}
@Override
public void onConfigurationChanged( final Configuration newConfig ) {
MainActivity.info("STATS: config changed");
super.onConfigurationChanged( newConfig );
}
/* Creates the menu items */
@Override
public void onCreateOptionsMenu (final Menu menu, final MenuInflater inflater) {
MenuItem item = menu.add(0, MENU_SITE_STATS, 0, getString(R.string.site_stats_app_name));
item.setIcon( R.drawable.wiglewifi_small_black_white );
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
item = menu.add(0, MENU_SITE_STATS, 0, getString(R.string.site_stats_app_name));
item.setIcon(R.drawable.wiglewifi_small_black_white);
item = menu.add(0, MENU_RANK_STATS, 0, getString(R.string.rank_stats_app_name));
item.setIcon(android.R.drawable.ic_menu_sort_by_size);
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
item = menu.add(0, MENU_RANK_STATS, 0, getString(R.string.rank_stats_app_name));
item.setIcon(android.R.drawable.ic_menu_sort_by_size);
super.onCreateOptionsMenu(menu, inflater);
}
/* Handles item selections */
@Override
public boolean onOptionsItemSelected( final MenuItem item ) {
final MainActivity main = MainActivity.getMainActivity();
switch ( item.getItemId() ) {
case MENU_SITE_STATS:
main.selectFragment(MainActivity.SITE_STATS_TAB_POS);
return true;
case MENU_RANK_STATS:
main.selectFragment(MainActivity.RANK_STATS_TAB_POS);
return true;
}
return false;
}
}