package com.boardgamegeek.ui;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import com.boardgamegeek.R;
import com.boardgamegeek.auth.AccountUtils;
import com.boardgamegeek.auth.Authenticator;
import com.boardgamegeek.events.PlaySelectedEvent;
import com.boardgamegeek.provider.BggContract;
import com.boardgamegeek.provider.BggContract.PlayerColors;
import com.boardgamegeek.provider.BggContract.Plays;
import com.boardgamegeek.service.SyncService;
import com.boardgamegeek.sorter.LocationsSorter;
import com.boardgamegeek.sorter.LocationsSorterFactory;
import com.boardgamegeek.sorter.PlayersSorter;
import com.boardgamegeek.sorter.PlayersSorterFactory;
import com.boardgamegeek.sorter.PlaysSorter;
import com.boardgamegeek.sorter.PlaysSorterFactory;
import com.boardgamegeek.ui.model.Location;
import com.boardgamegeek.ui.model.PlayModel;
import com.boardgamegeek.ui.model.Player;
import com.boardgamegeek.ui.model.PlayerColor;
import com.boardgamegeek.util.ActivityUtils;
import com.boardgamegeek.util.ColorUtils;
import com.boardgamegeek.util.PreferencesUtils;
import com.boardgamegeek.util.PresentationUtils;
import com.boardgamegeek.util.SelectionBuilder;
import org.greenrobot.eventbus.EventBus;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
public class PlaysSummaryFragment extends Fragment implements LoaderCallbacks<Cursor> {
private static final int PLAYS_TOKEN = 1;
private static final int PLAY_COUNT_TOKEN = 2;
private static final int PLAYERS_TOKEN = 3;
private static final int LOCATIONS_TOKEN = 4;
private static final int COLORS_TOKEN = 5;
private static final int PLAYS_IN_PROGRESS_TOKEN = 6;
private Unbinder unbinder;
@BindView(R.id.card_plays) View playsCard;
@BindView(R.id.plays_subtitle_in_progress) TextView playsInProgressSubtitle;
@BindView(R.id.plays_in_progress_container) LinearLayout playsInProgressContainer;
@BindView(R.id.plays_subtitle_recent) TextView recentPlaysSubtitle;
@BindView(R.id.plays_container) LinearLayout recentPlaysContainer;
@BindView(R.id.card_footer_plays) TextView playsFooter;
@BindView(R.id.card_players) View playersCard;
@BindView(R.id.players_container) LinearLayout playersContainer;
@BindView(R.id.card_locations) View locationsCard;
@BindView(R.id.locations_container) LinearLayout locationsContainer;
@BindView(R.id.card_colors) View colorsCard;
@BindView(R.id.colors_hint) View colorsHint;
@BindView(R.id.color_container) LinearLayout colorContainer;
@BindView(R.id.h_index) TextView hIndexView;
@BindView(R.id.sync_status) TextView syncStatusView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_plays_summary, container, false);
unbinder = ButterKnife.bind(this, rootView);
hIndexView.setText(PresentationUtils.getText(getActivity(), R.string.h_index_prefix, PreferencesUtils.getHIndex(getActivity())));
long oldestDate = Authenticator.getLong(getActivity(), SyncService.TIMESTAMP_PLAYS_OLDEST_DATE);
long newestDate = Authenticator.getLong(getActivity(), SyncService.TIMESTAMP_PLAYS_NEWEST_DATE);
if (oldestDate == 0 && newestDate == 0) {
syncStatusView.setText(R.string.plays_sync_status_none);
} else if (oldestDate == 0) {
syncStatusView.setText(String.format(getString(R.string.plays_sync_status_new),
DateUtils.formatDateTime(getContext(), newestDate, DateUtils.FORMAT_SHOW_DATE)));
} else if (newestDate == 0) {
syncStatusView.setText(String.format(getString(R.string.plays_sync_status_old),
DateUtils.formatDateTime(getContext(), oldestDate, DateUtils.FORMAT_SHOW_DATE)));
} else {
syncStatusView.setText(String.format(getString(R.string.plays_sync_status_range),
DateUtils.formatDateTime(getContext(), oldestDate, DateUtils.FORMAT_SHOW_DATE),
DateUtils.formatDateTime(getContext(), newestDate, DateUtils.FORMAT_SHOW_DATE)));
}
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().restartLoader(PLAYS_TOKEN, null, this);
getLoaderManager().restartLoader(PLAY_COUNT_TOKEN, null, this);
getLoaderManager().restartLoader(PLAYERS_TOKEN, null, this);
getLoaderManager().restartLoader(LOCATIONS_TOKEN, null, this);
if (!TextUtils.isEmpty(AccountUtils.getUsername(getActivity()))) {
getLoaderManager().restartLoader(COLORS_TOKEN, null, this);
}
getLoaderManager().restartLoader(PLAYS_IN_PROGRESS_TOKEN, null, this);
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
CursorLoader loader = null;
switch (id) {
case PLAYS_IN_PROGRESS_TOKEN:
PlaysSorter playsSorter = PlaysSorterFactory.create(getActivity(), PlayersSorterFactory.TYPE_DEFAULT);
loader = new CursorLoader(getActivity(),
Plays.CONTENT_URI,
PlayModel.PROJECTION,
Plays.DIRTY_TIMESTAMP + ">0",
null,
playsSorter == null ? null : playsSorter.getOrderByClause());
break;
case PLAYS_TOKEN:
playsSorter = PlaysSorterFactory.create(getActivity(), PlayersSorterFactory.TYPE_DEFAULT);
loader = new CursorLoader(getActivity(),
Plays.CONTENT_URI.buildUpon().appendQueryParameter(BggContract.QUERY_KEY_LIMIT, "3").build(),
PlayModel.PROJECTION,
SelectionBuilder.whereZeroOrNull(Plays.DIRTY_TIMESTAMP) + " AND " + SelectionBuilder.whereZeroOrNull(Plays.DELETE_TIMESTAMP),
null,
playsSorter == null ? null : playsSorter.getOrderByClause());
break;
case PLAY_COUNT_TOKEN:
loader = new CursorLoader(getActivity(),
Plays.CONTENT_SIMPLE_URI,
new String[] { Plays.SUM_QUANTITY },
null, null, null);
break;
case PLAYERS_TOKEN:
PlayersSorter playersSorter = PlayersSorterFactory.create(getActivity(), PlayersSorterFactory.TYPE_QUANTITY);
loader = new CursorLoader(getActivity(),
Plays.buildPlayersByUniquePlayerUri().buildUpon().appendQueryParameter(BggContract.QUERY_KEY_LIMIT, "4").build(),
Player.PROJECTION,
null, null, playersSorter.getOrderByClause());
break;
case LOCATIONS_TOKEN:
LocationsSorter locationsSorter = LocationsSorterFactory.create(getActivity(), LocationsSorterFactory.TYPE_QUANTITY);
loader = new CursorLoader(getActivity(),
Plays.buildLocationsUri().buildUpon().appendQueryParameter(BggContract.QUERY_KEY_LIMIT, "4").build(),
Location.PROJECTION,
null, null, locationsSorter.getOrderByClause());
break;
case COLORS_TOKEN:
String username = AccountUtils.getUsername(getActivity());
if (!TextUtils.isEmpty(username)) {
loader = new CursorLoader(getActivity(),
PlayerColors.buildUserUri(username),
PlayerColor.PROJECTION,
null, null, null);
}
break;
}
return loader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
if (getActivity() == null) {
return;
}
switch (loader.getId()) {
case PLAYS_IN_PROGRESS_TOKEN:
onPlaysInProgressQueryComplete(cursor);
break;
case PLAYS_TOKEN:
onPlaysQueryComplete(cursor);
break;
case PLAY_COUNT_TOKEN:
onPlayCountQueryComplete(cursor);
break;
case PLAYERS_TOKEN:
onPlayersQueryComplete(cursor);
break;
case LOCATIONS_TOKEN:
onLocationsQueryComplete(cursor);
break;
case COLORS_TOKEN:
onColorsQueryComplete(cursor);
break;
default:
cursor.close();
break;
}
}
private void onPlaysInProgressQueryComplete(Cursor cursor) {
if (cursor == null) {
return;
}
final int visibility = cursor.getCount() == 0 ? View.GONE : View.VISIBLE;
playsInProgressSubtitle.setVisibility(visibility);
playsInProgressContainer.setVisibility(visibility);
recentPlaysSubtitle.setVisibility(visibility);
playsInProgressContainer.removeAllViews();
while (cursor.moveToNext()) {
playsCard.setVisibility(View.VISIBLE);
addPlayToContainer(cursor, playsInProgressContainer);
}
}
private void onPlaysQueryComplete(Cursor cursor) {
if (cursor == null) {
return;
}
recentPlaysContainer.removeAllViews();
while (cursor.moveToNext()) {
playsCard.setVisibility(View.VISIBLE);
recentPlaysContainer.setVisibility(View.VISIBLE);
addPlayToContainer(cursor, recentPlaysContainer);
}
}
private void addPlayToContainer(Cursor cursor, LinearLayout container) {
long internalId = cursor.getLong(cursor.getColumnIndex(Plays._ID));
PlayModel play = PlayModel.fromCursor(cursor, getActivity());
View view = createRow(container, play.getName(), PresentationUtils.describePlayDetails(getActivity(), play.getDate(), play.getLocation(), play.getQuantity(), play.getLength(), play.getPlayerCount()));
view.setTag(R.id.id, internalId);
view.setTag(R.id.game_info_id, play.getGameId());
view.setTag(R.id.game_name, play.getName());
view.setTag(R.id.thumbnail, play.getThumbnailUrl());
view.setTag(R.id.account_image, play.getImageUrl());
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().postSticky(new PlaySelectedEvent(
(long) v.getTag(R.id.id),
(int) v.getTag(R.id.game_info_id),
(String) v.getTag(R.id.game_name),
(String) v.getTag(R.id.thumbnail),
(String) v.getTag(R.id.account_image)));
}
});
}
private void onPlayCountQueryComplete(Cursor cursor) {
if (cursor == null) {
return;
}
if (cursor.moveToFirst()) {
setQuantityTextView(playsFooter, R.plurals.plays_suffix, cursor.getInt(0));
}
}
private void onPlayersQueryComplete(Cursor cursor) {
if (cursor == null) {
return;
}
String accountUsername = AccountUtils.getUsername(getActivity());
int count = 0;
playersContainer.removeAllViews();
while (cursor.moveToNext()) {
Player player = Player.fromCursor(cursor);
if (accountUsername != null && accountUsername.equals(player.getUsername())) {
continue;
}
playersCard.setVisibility(View.VISIBLE);
View view = createRowWithPlayCount(playersContainer, PresentationUtils.describePlayer(player.getName(), player.getUsername()), player.getPlayCount());
view.setTag(R.id.name, player.getName());
view.setTag(R.id.username, player.getUsername());
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ActivityUtils.startBuddyActivity(
getActivity(),
(String) v.getTag(R.id.username),
(String) v.getTag(R.id.name));
}
});
count++;
if (count >= 3) {
break;
}
}
}
private void onLocationsQueryComplete(Cursor cursor) {
if (cursor == null) {
return;
}
int count = 0;
locationsContainer.removeAllViews();
while (cursor.moveToNext()) {
Location location = Location.fromCursor(cursor);
if (TextUtils.isEmpty(location.getName())) {
continue;
}
locationsCard.setVisibility(View.VISIBLE);
View view = createRowWithPlayCount(locationsContainer, location.getName(), location.getPlayCount());
view.setTag(R.id.name, location.getName());
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = ActivityUtils.createLocationIntent(
getActivity(),
(String) v.getTag(R.id.name));
startActivity(intent);
}
});
count++;
if (count >= 3) {
break;
}
}
}
private View createRow(LinearLayout container, String title, String text) {
View view = getLayoutInflater(null).inflate(R.layout.row_player_summary, container, false);
container.addView(view);
((TextView) view.findViewById(android.R.id.title)).setText(title);
((TextView) view.findViewById(android.R.id.text1)).setText(text);
return view;
}
private View createRowWithPlayCount(LinearLayout container, String title, int playCount) {
return createRow(container, title, getResources().getQuantityString(R.plurals.plays_suffix, playCount, playCount));
}
private void setQuantityTextView(TextView textView, int resId, int count) {
textView.setText(getResources().getQuantityString(resId, count, count));
}
private void onColorsQueryComplete(Cursor cursor) {
if (cursor == null) return;
colorContainer.removeAllViews();
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
ImageView view = createViewToBeColored();
PlayerColor color = PlayerColor.fromCursor(cursor);
ColorUtils.setColorViewValue(view, ColorUtils.parseColor(color.getColor()));
colorContainer.addView(view);
}
}
colorsHint.setVisibility(cursor.getCount() == 0 ? View.VISIBLE : View.GONE);
colorsCard.setVisibility(View.VISIBLE);
}
private ImageView createViewToBeColored() {
ImageView view = new ImageView(getActivity());
int size = getResources().getDimensionPixelSize(R.dimen.color_circle_diameter_small);
int margin = getResources().getDimensionPixelSize(R.dimen.color_circle_diameter_small_margin);
LayoutParams lp = new LayoutParams(size, size);
lp.setMargins(margin, margin, margin, margin);
view.setLayoutParams(lp);
return view;
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
@SuppressWarnings("unused")
@OnClick(R.id.card_footer_plays)
public void onPlaysClick() {
startActivity(new Intent(getActivity(), PlaysActivity.class));
}
@SuppressWarnings("unused")
@OnClick(R.id.card_footer_players)
public void onPlayersClick() {
startActivity(new Intent(getActivity(), PlayersActivity.class));
}
@OnClick(R.id.card_footer_locations)
public void onLocationsClick() {
startActivity(new Intent(getActivity(), LocationsActivity.class));
}
@OnClick(R.id.card_footer_colors)
public void onColorsClick() {
Intent intent = new Intent(getActivity(), PlayerColorsActivity.class);
intent.putExtra(ActivityUtils.KEY_BUDDY_NAME, AccountUtils.getUsername(getActivity()));
startActivity(intent);
}
@OnClick(R.id.card_footer_stats)
public void onStatsClick() {
startActivity(new Intent(getActivity(), PlayStatsActivity.class));
}
}