package com.boardgamegeek.ui;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v4.util.ArrayMap;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import com.boardgamegeek.R;
import com.boardgamegeek.events.CollectionStatusChangedEvent;
import com.boardgamegeek.io.Adapter;
import com.boardgamegeek.io.BggService;
import com.boardgamegeek.model.CollectionItem;
import com.boardgamegeek.model.CollectionResponse;
import com.boardgamegeek.ui.loader.BggLoader;
import com.boardgamegeek.ui.loader.SafeResponse;
import com.boardgamegeek.util.ActivityUtils;
import com.boardgamegeek.util.RandomUtils;
import com.boardgamegeek.util.UIUtils;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent;
import org.greenrobot.eventbus.EventBus;
import java.util.ArrayList;
import java.util.List;
import icepick.Icepick;
import icepick.State;
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
import timber.log.Timber;
public class BuddyCollectionFragment extends StickyHeaderListFragment implements LoaderManager.LoaderCallbacks<SafeResponse<CollectionResponse>> {
private static final int BUDDY_GAMES_LOADER_ID = 1;
private BuddyCollectionAdapter adapter;
private SubMenu subMenu;
private String buddyName;
@State String statusValue;
@State String statusLabel;
private String[] statusValues;
private String[] statusEntries;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent intent = UIUtils.fragmentArgumentsToIntent(getArguments());
buddyName = intent.getStringExtra(ActivityUtils.KEY_BUDDY_NAME);
if (TextUtils.isEmpty(buddyName)) {
Timber.w("Missing buddy name.");
return;
}
statusEntries = getResources().getStringArray(R.array.pref_sync_status_entries);
statusValues = getResources().getStringArray(R.array.pref_sync_status_values);
setHasOptionsMenu(true);
Icepick.restoreInstanceState(this, savedInstanceState);
if (TextUtils.isEmpty(statusValue)) {
statusValue = statusValues[0];
}
if (TextUtils.isEmpty(statusLabel)) {
statusLabel = statusEntries[0];
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setEmptyText(getString(R.string.empty_buddy_collection));
reload();
}
@Override
public void onListItemClick(View convertView, int position, long id) {
super.onListItemClick(convertView, position, id);
int gameId = (int) convertView.getTag(R.id.id);
String gameName = (String) convertView.getTag(R.id.game_name);
ActivityUtils.launchGame(getActivity(), gameId, gameName);
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
Icepick.saveInstanceState(this, outState);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.buddy_collection, menu);
MenuItem mi = menu.findItem(R.id.menu_collection_status);
if (mi != null) {
subMenu = mi.getSubMenu();
if (subMenu != null) {
for (int i = 0; i < statusEntries.length; i++) {
subMenu.add(1, Menu.FIRST + i, i, statusEntries[i]);
}
subMenu.setGroupCheckable(1, true, true);
}
}
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
UIUtils.showMenuItem(menu, R.id.menu_collection_random_game, adapter != null && adapter.getCount() > 0);
// check the proper submenu item
if (subMenu != null) {
for (int i = 0; i < subMenu.size(); i++) {
MenuItem smi = subMenu.getItem(i);
if (smi.getTitle().equals(statusLabel)) {
smi.setChecked(true);
break;
}
}
}
super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
String status = "";
int i = id - Menu.FIRST;
if (i >= 0 && i < statusValues.length) {
status = statusValues[i];
} else if (id == R.id.menu_collection_random_game) {
final int index = RandomUtils.getRandom().nextInt(adapter.getCount());
if (index < adapter.getCount()) {
CollectionItem ci = adapter.getItem(index);
if (ci != null) {
ActivityUtils.launchGame(getActivity(), ci.gameId, ci.gameName());
return true;
}
return false;
}
}
if (!TextUtils.isEmpty(status) && !status.equals(statusValue)) {
statusValue = status;
statusLabel = statusEntries[i];
Answers.getInstance().logCustom(new CustomEvent("Filter")
.putCustomAttribute("contentType", "BuddyCollection")
.putCustomAttribute("filterType", status));
reload();
return true;
}
return super.onOptionsItemSelected(item);
}
private void reload() {
EventBus.getDefault().postSticky(new CollectionStatusChangedEvent(statusLabel));
if (adapter != null) {
adapter.clear();
}
getActivity().supportInvalidateOptionsMenu();
setListShown(false);
getLoaderManager().restartLoader(BUDDY_GAMES_LOADER_ID, null, this);
}
@Override
public Loader<SafeResponse<CollectionResponse>> onCreateLoader(int id, Bundle data) {
return new BuddyGamesLoader(getActivity(), buddyName, statusValue);
}
@Override
public void onLoadFinished(Loader<SafeResponse<CollectionResponse>> loader, SafeResponse<CollectionResponse> data) {
if (getActivity() == null) {
return;
}
List<CollectionItem> list = (data == null || data.getBody() == null) ?
new ArrayList<CollectionItem>() :
data.getBody().items;
if (list == null) list = new ArrayList<>();
if (adapter == null) {
adapter = new BuddyCollectionAdapter(getActivity(), list);
setListAdapter(adapter);
} else {
adapter.setCollection(list);
}
adapter.notifyDataSetChanged();
getActivity().supportInvalidateOptionsMenu();
if (data == null) {
setEmptyText(getString(R.string.empty_buddy_collection));
} else if (data.hasError()) {
setEmptyText(data.getErrorMessage());
} else {
if (isResumed()) {
setListShown(true);
} else {
setListShownNoAnimation(true);
}
restoreScrollState();
}
}
@Override
public void onLoaderReset(Loader<SafeResponse<CollectionResponse>> loader) {
}
private static class BuddyGamesLoader extends BggLoader<SafeResponse<CollectionResponse>> {
private final BggService bggService;
private final String username;
private final ArrayMap<String, String> options;
public BuddyGamesLoader(Context context, String username, String status) {
super(context);
bggService = Adapter.createForXml();
this.username = username;
options = new ArrayMap<>();
options.put(status, "1");
options.put(BggService.COLLECTION_QUERY_KEY_BRIEF, "1");
}
@Override
public SafeResponse<CollectionResponse> loadInBackground() {
return new SafeResponse<>(bggService.collection(username, options));
}
}
public static class BuddyCollectionAdapter extends ArrayAdapter<CollectionItem> implements StickyListHeadersAdapter {
private final LayoutInflater inflater;
public BuddyCollectionAdapter(Activity activity, List<CollectionItem> collection) {
super(activity, R.layout.row_text_2, collection);
inflater = activity.getLayoutInflater();
setCollection(collection);
}
public void setCollection(List<CollectionItem> games) {
notifyDataSetChanged();
}
@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
BuddyGameViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.row_text_2, parent, false);
holder = new BuddyGameViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (BuddyGameViewHolder) convertView.getTag();
}
CollectionItem game;
try {
game = getItem(position);
} catch (ArrayIndexOutOfBoundsException e) {
return convertView;
}
if (game != null) {
holder.title.setText(game.gameName());
holder.text.setText(String.valueOf(game.gameId));
convertView.setTag(R.id.id, game.gameId);
convertView.setTag(R.id.game_name, game.gameName());
}
return convertView;
}
@Override
public View getHeaderView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
if (convertView == null) {
holder = new HeaderViewHolder();
convertView = inflater.inflate(R.layout.row_header, parent, false);
holder.text = (TextView) convertView.findViewById(android.R.id.title);
convertView.setTag(holder);
} else {
holder = (HeaderViewHolder) convertView.getTag();
}
holder.text.setText(getHeaderText(position));
return convertView;
}
@Override
public long getHeaderId(int position) {
return getHeaderText(position).charAt(0);
}
private String getHeaderText(int position) {
if (position < getCount()) {
CollectionItem game = getItem(position);
if (game != null) {
return game.gameSortName().substring(0, 1);
}
}
return "-";
}
class BuddyGameViewHolder {
public final TextView title;
public final TextView text;
public BuddyGameViewHolder(View view) {
title = (TextView) view.findViewById(android.R.id.title);
text = (TextView) view.findViewById(android.R.id.text1);
}
}
class HeaderViewHolder {
TextView text;
}
}
}