package com.jasonrobinson.racer.ui.ladder; import android.os.AsyncTask.Status; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.MenuItemCompat; import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.Toast; import com.jasonrobinson.racer.R; import com.jasonrobinson.racer.adapter.LadderAdapter; import com.jasonrobinson.racer.async.LadderAsyncTask; import com.jasonrobinson.racer.async.LadderAsyncTask.LadderParams; import com.jasonrobinson.racer.enumeration.PoeClass; import com.jasonrobinson.racer.model.Ladder; import com.jasonrobinson.racer.model.Ladder.Entry; import com.jasonrobinson.racer.model.Race; import com.jasonrobinson.racer.model.ServerError; import com.jasonrobinson.racer.model.WatchType; import com.jasonrobinson.racer.ui.base.BaseListFragment; import com.jasonrobinson.racer.ui.ladder.WatchCharacterDialogFragment.WatchCharacterDialogListener; import com.jasonrobinson.racer.util.LadderUtils; import java.util.Timer; import java.util.TimerTask; import retrofit.RetrofitError; public class LadderFragment extends BaseListFragment { private static final String TAG = LadderFragment.class.getSimpleName(); private static final String EXTRA_ID = "id"; private static final String TAG_WATCH_CHARACTER = "watchCharacter"; private Race mRace; private String mWatchedName; private PoeClass mWatchedCharacterClass; private PoeClass mWatchedClass; private WatchType mWatchedType; private Timer mAutoRefreshTimer; private boolean mRefreshing; private LadderAdapter mAdapter; private LadderTask mTask; private boolean mTracked; private boolean mRefreshEnabled = true; private boolean mAutoRefreshEnabled; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); setEmptyText(getString(R.string.no_rankings)); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (getArguments() != null) { String id = getArguments().getString(EXTRA_ID); if (id != null) { mRace = getDatabaseManager().getRace(id); fetchLadder(); } } } @Override public void onResume() { super.onResume(); if (mTask != null && mTask.getStatus() != Status.RUNNING && mRace != null) { fetchLadder(); } } @Override public void onPause() { super.onPause(); cancelAutoRefresh(); } @Override public void onDestroyView() { super.onDestroyView(); if (mTask != null) { mTask.cancel(true); } cancelAutoRefresh(); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.refresh_menu, menu); MenuItem refreshItem = menu.findItem(R.id.menu_refresh); refreshItem.setEnabled(mRefreshEnabled); if (!mRefreshing) { MenuItemCompat.setActionView(refreshItem, null); } } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.menu_refresh) { fetchLadder(); getAnalyticsManager().trackEvent("Ladder", "Refresh", "Manual"); } else if (id == R.id.menu_watch_character) { showCharacterDialog(); } else { super.onOptionsItemSelected(item); } return true; } private void showCharacterDialog() { FragmentTransaction ft = getFragmentManager().beginTransaction(); Fragment prev = getFragmentManager().findFragmentByTag(TAG_WATCH_CHARACTER); if (prev != null) { ft.remove(prev); } WatchCharacterDialogFragment fragment = WatchCharacterDialogFragment.newInstance(mWatchedName, mWatchedType); fragment.setWatchCharacterDialogListener(new WatchCharacterDialogListener() { @Override public void onRemove() { getAnalyticsManager().trackEvent("Ladder", "Remove", "Character Watcher"); mWatchedName = null; mWatchedCharacterClass = null; fetchLadder(); } @Override public void onNameSelected(String name, WatchType type) { getAnalyticsManager().trackEvent("Ladder", "Use", "Character Watcher"); getAnalyticsManager().trackEvent("Ladder", "Character Watcher", type.name()); mWatchedName = name; mWatchedType = type; getListView().smoothScrollToPosition(0); fetchLadder(); } @Override public void onCancel() { // no-op } }); fragment.show(ft, TAG_WATCH_CHARACTER); } private void fetchLadder() { fetchLadder(mRace.getRaceId(), mWatchedClass); } public void fetchLadder(String id, PoeClass poeClass) { if (mRace == null || !mRace.getRaceId().equals(id)) { mRace = getDatabaseManager().getRace(id); } boolean resetAdapter = mWatchedClass != poeClass; mWatchedClass = poeClass; if (mTask != null) { mTask.cancel(true); } LadderParams params = new LadderParams(id, 0, poeClass == null ? 200 : 50, mWatchedClass, mWatchedName, mWatchedType, mWatchedCharacterClass); mTask = new LadderTask(resetAdapter); mTask.execute(params); if (!mTracked) { mTracked = true; getAnalyticsManager().trackEvent("Ladder", "View", id); } } private void cancelAutoRefresh() { if (mAutoRefreshTimer != null) { mAutoRefreshTimer.cancel(); mAutoRefreshTimer.purge(); } } private void startAutoRefresh() { cancelAutoRefresh(); mAutoRefreshTimer = new Timer(); mAutoRefreshTimer.schedule(new RefreshTimerTask(), 30000); } private void setRefreshing(boolean refreshing) { mRefreshing = refreshing; getActivity().supportInvalidateOptionsMenu(); if (refreshing) { cancelAutoRefresh(); } else { if (mAutoRefreshEnabled) { startAutoRefresh(); } } } public void setAutoRefreshEnabled(boolean enabled) { if (mAutoRefreshEnabled == enabled) { return; } mAutoRefreshEnabled = enabled; if (mAutoRefreshEnabled) { startAutoRefresh(); } else { cancelAutoRefresh(); } } public void setRefreshEnabled(boolean enabled) { if (mRefreshEnabled == enabled) { return; } mRefreshEnabled = enabled; getActivity().supportInvalidateOptionsMenu(); } private class LadderTask extends LadderAsyncTask { private boolean mReset; public LadderTask(boolean resetAdapter) { mReset = resetAdapter; } @Override protected void onPreExecute() { super.onPreExecute(); getActivity().runOnUiThread(new Runnable() { @Override public void run() { setRefreshing(true); if (mReset) { setListShown(false); } } }); } // TODO: This method is a mess and needs to be cleaned up @Override protected void onPostExecute(LadderResult result) { super.onPostExecute(result); setRefreshing(false); Entry[] entries = null; Entry watchedEntry = null; String toastMessage = getString(R.string.error_unavailable); if (result != null) { Ladder ladder = result.ladder; if (ladder != null) { entries = ladder.getEntries().toArray(new Entry[ladder.getEntries().size()]); } else if (result.retrofitError != null) { RetrofitError error = result.retrofitError; if (error.getResponse() != null) { ServerError body = (ServerError) error.getBodyAs(ServerError.class); if (body.getError() != null) { Log.e(TAG, "Error code: " + body.getError().getCode() + ", Message: " + body.getError().getMessage()); toastMessage = body.getError().getMessage(); } } } } if (entries != null) { if (!TextUtils.isEmpty(mWatchedName)) { watchedEntry = LadderUtils.findEntry(result.ladder.getEntries(), mWatchedName, mWatchedType); if (watchedEntry == null && mWatchedCharacterClass == null) { Toast.makeText(getActivity(), getString(R.string.character_not_found, mWatchedName), Toast.LENGTH_LONG).show(); mWatchedName = null; } else { if (watchedEntry != null) { mWatchedCharacterClass = PoeClass.getClassForName(watchedEntry.getCharacter().getPoeClass()); } } } boolean borderFirstItem = !TextUtils.isEmpty(mWatchedName) && watchedEntry != null; if (mAdapter == null || mReset) { mAdapter = new LadderAdapter(entries, mWatchedClass != null, borderFirstItem); setListAdapter(mAdapter); } else { mAdapter.setBorderFirstItem(borderFirstItem); mAdapter.setEntries(entries, mWatchedClass != null); } } else { Toast.makeText(getActivity(), toastMessage, Toast.LENGTH_LONG).show(); } setListShown(true); } } private class RefreshTimerTask extends TimerTask { @Override public void run() { if (mRace != null) { getActivity().runOnUiThread(new Runnable() { @Override public void run() { fetchLadder(); getAnalyticsManager().trackEvent("Ladder", "Refresh", "Automatic"); } }); } } } }