package edu.stanford.cs.sujogger.viewer;
import com.admob.android.ads.AdManager;
import com.admob.android.ads.AdView;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.LinearLayout.LayoutParams;
import edu.stanford.cs.gaming.sdk.model.AppResponse;
import edu.stanford.cs.gaming.sdk.model.Group;
import edu.stanford.cs.gaming.sdk.model.ScoreBoard;
import edu.stanford.cs.gaming.sdk.model.User;
import edu.stanford.cs.gaming.sdk.service.GamingServiceConnection;
import edu.stanford.cs.sujogger.R;
import edu.stanford.cs.sujogger.db.DatabaseHelper;
import edu.stanford.cs.sujogger.db.GPStracking.Stats;
import edu.stanford.cs.sujogger.util.Common;
import edu.stanford.cs.sujogger.util.Constants;
import edu.stanford.cs.sujogger.util.LeaderBoardAdapter;
import edu.stanford.cs.sujogger.util.SegmentedControl;
public class LeaderBoard extends ListActivity {
private static final String TAG = "OGT.LeaderBoard";
public static final String STAT_TYPE_KEY = "statistic_type";
public static final String STAT_TIME_KEY = "statistic_time";
public static final String IS_GROUP_KEY = "is_group";
public static final String ALREADY_UPDATED_KEY = "already_updated";
//Request IDs
private static final int GET_USER_SBS_RID = 1;
private static final int GET_GROUP_SBS_RID = 2;
private static final int GET_APP_USERS_RID = 3;
private static final int GET_GROUPS_RID = 4;
private DatabaseHelper mDbHelper;
private Cursor mScores;
private LeaderBoardAdapter lbAdapter;
private GamingServiceConnection mGameCon;
private LeaderBoardReceiver mReceiver;
private SharedPreferences mSharedPreferences;
private Handler mHandler = new Handler();
ArrayAdapter<String> mSpinnerTypeAdapterSolo;
ArrayAdapter<String> mSpinnerTypeAdapterGroup;
private int mStatisticType;
private int mTimeScale;
private boolean mIsGroup;
private int mGetUsersGroupsProgress;
private int mGetUsersGroupsGoal = 0;
private Spinner mSpinnerTypeSolo;
private Spinner mSpinnerTypeGroup;
private Spinner mSpinnerTime;
private ProgressDialog mUserGroupWaitDialog;
private ProgressDialog mScoreWaitDialog;
private Runnable mRefreshTask = new Runnable() {
public void run() {
long timeNow = System.currentTimeMillis();
boolean updateUsers = timeNow - mSharedPreferences.getLong(Constants.ALL_USERS_UPDATE_KEY, 0) >
Constants.UPDATE_INTERVAL;
boolean updateGroups = timeNow - mSharedPreferences.getLong(Constants.ALL_GROUPS_UPDATE_KEY, 0) >
Constants.UPDATE_INTERVAL;
if (updateUsers || updateGroups) {
mUserGroupWaitDialog = ProgressDialog.show(LeaderBoard.this, "", "Updating users and groups...", true);
try {
if (updateUsers) {
mGetUsersGroupsGoal++;
mGameCon.getAppsUser(GET_APP_USERS_RID);
}
if (updateGroups) {
mGetUsersGroupsGoal++;
mGameCon.getGroups(GET_GROUPS_RID, null, -1, -1, -1);
}
}
catch (RemoteException e) {}
}
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Common.log(TAG, "onCreate()");
this.setContentView(R.layout.leaderboard);
mStatisticType = savedInstanceState != null ? savedInstanceState.getInt(STAT_TYPE_KEY) : 1;
mTimeScale = savedInstanceState != null ? savedInstanceState.getInt(STAT_TIME_KEY) : 0;
mIsGroup = savedInstanceState != null ? savedInstanceState.getBoolean(IS_GROUP_KEY) : false;
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
mDbHelper = new DatabaseHelper(this);
mDbHelper.openAndGetDb();
mReceiver = new LeaderBoardReceiver();
mGameCon = new GamingServiceConnection(this, mReceiver, Constants.APP_ID,
Constants.APP_API_KEY, LeaderBoard.class.toString());
mGameCon.bind();
User user = Common.getRegisteredUser(this);
mGameCon.setUserId(user.id, user.fb_id, user.fb_token);
mGetUsersGroupsProgress = 0;
mSpinnerTypeAdapterSolo = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, Stats.STAT_TYPES_SOLO);
mSpinnerTypeAdapterSolo.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
mSpinnerTypeAdapterGroup = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, Stats.STAT_TYPES_GROUP);
mSpinnerTypeAdapterGroup.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
mSpinnerTypeSolo = (Spinner) findViewById(R.id.lb_spinner_type_solo);
mSpinnerTypeGroup = (Spinner) findViewById(R.id.lb_spinner_type_group);
mSpinnerTypeSolo.setAdapter(mSpinnerTypeAdapterSolo);
mSpinnerTypeSolo.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (mIsGroup) return;
pos++;
mStatisticType = pos;
updateLBSelection(false);
}
public void onNothingSelected(AdapterView<?> parent) {}
});
mSpinnerTypeGroup.setAdapter(mSpinnerTypeAdapterGroup);
mSpinnerTypeGroup.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (!mIsGroup) return;
pos++;
mStatisticType = pos;
updateLBSelection(false);
}
public void onNothingSelected(AdapterView<?> parent) {}
});
mSpinnerTime = (Spinner) findViewById(R.id.lb_spinner_time);
ArrayAdapter<String> spinnerTimeAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, Stats.TIME_TYPES);
spinnerTimeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinnerTime.setAdapter(spinnerTimeAdapter);
mSpinnerTime.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
mTimeScale = pos;
updateLBSelection(false);
}
public void onNothingSelected(AdapterView<?> parent) {}
});
LinearLayout bottomControlBar = (LinearLayout)findViewById(R.id.bottom_control_bar);
bottomControlBar.addView(new SegmentedControl(this, new String[] {"Individuals", "Groups"},
mIsGroup ? 1 : 0, new SegmentedControl.SegmentedControlListener() {
public void onValueChanged(int newValue) {
mIsGroup = newValue == 1;
updateLBSelection(true);
}
}),
new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
setTitle("Leaderboards");
if (Constants.AD_TEST) AdManager.setTestDevices(new String[] { "3468678E351E95A5F7A64D2271BCB7BF" });
AdView adView = (AdView)View.inflate(this, R.layout.adview, null);
getListView().addHeaderView(adView);
fillData();
mHandler.postDelayed(mRefreshTask, 100);
}
private void updateLBSelection(boolean retrieveScores) {
Common.log(TAG, "updateLBSelection(): statisticId = " + statisticId() +
"; time scale = " + mTimeScale + "; is_group = " + mIsGroup);
if (mIsGroup) {
if (mStatisticType > 4)
mStatisticType = 4;
mSpinnerTypeGroup.setSelection(mStatisticType-1);
mSpinnerTime.setVisibility(View.GONE);
mSpinnerTypeSolo.setVisibility(View.GONE);
mSpinnerTypeGroup.setVisibility(View.VISIBLE);
if (retrieveScores && (System.currentTimeMillis() -
mSharedPreferences.getLong(Constants.LB_GROUPSCORES_UPDATE_KEY, 0) >
Constants.UPDATE_INTERVAL)) {
mScoreWaitDialog = ProgressDialog.show(this, "", "Retrieving scores...", true);
try {
mGameCon.getGroupScoreBoards(GET_GROUP_SBS_RID);
} catch (RemoteException e) {}
}
else {
fillData();
}
}
else {
mSpinnerTypeSolo.setSelection(mStatisticType-1);
mSpinnerTime.setVisibility(View.VISIBLE);
mSpinnerTypeSolo.setVisibility(View.VISIBLE);
mSpinnerTypeGroup.setVisibility(View.GONE);
if (retrieveScores && (System.currentTimeMillis() -
mSharedPreferences.getLong(Constants.LB_USERSCORES_UPDATE_KEY, 0) >
Constants.UPDATE_INTERVAL)) {
mScoreWaitDialog = ProgressDialog.show(this, "", "Retrieving scores...", true);
try {
mGameCon.getUserScoreBoards(GET_USER_SBS_RID);
} catch (RemoteException e) {}
}
else {
fillData();
}
}
Common.log(TAG, "updateLBSelection(): statisticId = " + statisticId() +
"; time scale = " + mTimeScale + "; is_group = " + mIsGroup);
}
private int statisticId() {
return (mTimeScale * 10) + mStatisticType;
}
@Override
protected void onRestart() {
Common.log(TAG, "onRestart()");
mDbHelper.openAndGetDb();
super.onRestart();
}
@Override
protected void onPause() {
Common.log(TAG, "onPause()");
super.onPause();
}
@Override
protected void onResume() {
Common.log(TAG, "onResume()");
super.onResume();
}
@Override
protected void onDestroy() {
mDbHelper.close();
mGameCon.unbind();
super.onDestroy();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Common.log(TAG, "onSaveInstanceState(): mStatisticType = " + mStatisticType);
outState.putInt(STAT_TYPE_KEY, mStatisticType);
outState.putInt(STAT_TIME_KEY, mTimeScale);
outState.putBoolean(IS_GROUP_KEY, mIsGroup);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Log.v(TAG, "position = " + position + "; id = " + id);
position--;
if (mIsGroup) {
}
else {
int userId = (Integer) lbAdapter.getItem(position);
Common.log(TAG, "userID = " + userId);
Intent i = new Intent(this, PeopleTrackList.class);
i.putExtra("userId", userId);
startActivity(i);
}
}
private void fillData() {
if (mScores != null) mScores.close();
if (mIsGroup)
mScores = mDbHelper.getScoresWithGroups(statisticId());
else
mScores = mDbHelper.getScoresWithUsers(statisticId());
startManagingCursor(mScores);
Common.log(TAG, "fillData()");
if (Constants.SHOW_DEBUG) DatabaseUtils.dumpCursor(mScores);
if (lbAdapter == null) {
lbAdapter = new LeaderBoardAdapter(this, mScores, statisticId(), mIsGroup);
setListAdapter(lbAdapter);
}
else
lbAdapter.changeCursor(mScores, statisticId(), mIsGroup);
}
class LeaderBoardReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Common.log(TAG, "onReceive()");
try {
AppResponse appResponse = null;
while ((appResponse = mGameCon.getNextPendingNotification()) != null) {
Common.log(TAG, appResponse.toString());
if (appResponse.result_code.equals(GamingServiceConnection.RESULT_CODE_ERROR)) {
LeaderBoard.this.runOnUiThread(new Runnable() {
public void run() {
if (mUserGroupWaitDialog != null) mUserGroupWaitDialog.dismiss();
if (mScoreWaitDialog != null) mScoreWaitDialog.dismiss();
fillData();
Toast toast = Toast.makeText(LeaderBoard.this,
R.string.connection_error_toast, Toast.LENGTH_SHORT);
toast.show();
}
});
continue;
}
else if (appResponse.result_code.equals(GamingServiceConnection.RESULT_CODE_VERSION_ERROR)) {
LeaderBoard.this.runOnUiThread(new Runnable() {
public void run() {
if (mUserGroupWaitDialog != null) mUserGroupWaitDialog.dismiss();
if (mScoreWaitDialog != null) mScoreWaitDialog.dismiss();
fillData();
Common.displayUpgradeDialog(LeaderBoard.this);
}
});
continue;
}
final ScoreBoard[] scores;
switch (appResponse.request_id) {
case GET_USER_SBS_RID:
scores = (ScoreBoard[])appResponse.object;
LeaderBoard.this.runOnUiThread(new Runnable() {
public void run() {
if (scores != null) {
mDbHelper.fillScoreBoardTemp(scores, false);
fillData();
}
Editor editor = mSharedPreferences.edit();
editor.putLong(Constants.LB_USERSCORES_UPDATE_KEY,
System.currentTimeMillis());
editor.commit();
mScoreWaitDialog.dismiss();
}
});
break;
case GET_GROUP_SBS_RID:
scores = (ScoreBoard[])appResponse.object;
LeaderBoard.this.runOnUiThread(new Runnable() {
public void run() {
if (scores != null) {
mDbHelper.fillScoreBoardTemp(scores, true);
fillData();
}
Editor editor = mSharedPreferences.edit();
editor.putLong( Constants.LB_GROUPSCORES_UPDATE_KEY,
System.currentTimeMillis());
editor.commit();
mScoreWaitDialog.dismiss();
}
});
break;
case GET_APP_USERS_RID:
final User[] users = (User[])appResponse.object;
LeaderBoard.this.runOnUiThread(new Runnable() {
public void run() {
if (users != null)
mDbHelper.addUsers(users);
Editor editor = mSharedPreferences.edit();
editor.putLong(Constants.ALL_USERS_UPDATE_KEY,
System.currentTimeMillis());
editor.commit();
mGetUsersGroupsProgress++;
if (mGetUsersGroupsProgress >= mGetUsersGroupsGoal) {
mUserGroupWaitDialog.dismiss();
updateLBSelection(true);
}
}
});
break;
case GET_GROUPS_RID:
final Group[] groups = (Group[])appResponse.object;
LeaderBoard.this.runOnUiThread(new Runnable() {
public void run() {
if (groups != null)
mDbHelper.addGroupsTemp(groups);
Editor editor = mSharedPreferences.edit();
editor.putLong(Constants.ALL_GROUPS_UPDATE_KEY,
System.currentTimeMillis());
editor.commit();
mGetUsersGroupsProgress++;
if (mGetUsersGroupsProgress >= mGetUsersGroupsGoal) {
mUserGroupWaitDialog.dismiss();
updateLBSelection(true);
}
}
});
break;
default:
break;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}