package com.boardgamegeek.ui;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.widget.ContentLoadingProgressBar;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.boardgamegeek.R;
import com.boardgamegeek.model.TopGame;
import com.boardgamegeek.ui.adapter.TopGamesAdapter;
import com.boardgamegeek.util.AnimationUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import rx.Single;
import rx.SingleSubscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import timber.log.Timber;
public class TopGamesFragment extends Fragment {
Unbinder unbinder;
TopGamesAdapter adapter;
@BindView(android.R.id.progress) ContentLoadingProgressBar progressView;
@BindView(android.R.id.empty) TextView emptyView;
@BindView(android.R.id.list) RecyclerView recyclerView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_top_games, container, false);
unbinder = ButterKnife.bind(this, rootView);
setUpRecyclerView();
loadTopGames();
return rootView;
}
private void setUpRecyclerView() {
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setHasFixedSize(true);
}
private void loadTopGames() {
Single
.create(new Single.OnSubscribe<List<TopGame>>() {
@Override
public void call(SingleSubscriber<? super List<TopGame>> singleSubscriber) {
try {
List<TopGame> topGames = findTopGames();
singleSubscriber.onSuccess(topGames);
} catch (Throwable t) {
singleSubscriber.onError(t);
}
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleSubscriber<List<TopGame>>() {
@Override
public void onSuccess(List<TopGame> topGames) {
if (topGames.isEmpty()) {
AnimationUtils.fadeIn(emptyView);
} else {
adapter = new TopGamesAdapter(topGames);
recyclerView.setAdapter(adapter);
AnimationUtils.fadeIn(getActivity(), recyclerView, isResumed());
}
progressView.hide();
}
@Override
public void onError(Throwable error) {
Timber.e(error, "Error loading top games");
if (isAdded()) {
emptyView.setText(getString(R.string.empty_http_error, error.getLocalizedMessage()));
}
AnimationUtils.fadeIn(emptyView);
progressView.hide();
}
});
}
private List<TopGame> findTopGames() throws IOException {
List<TopGame> topGames = new ArrayList<>();
int rank = 1;
Document doc = Jsoup.connect("https://www.boardgamegeek.com/browse/boardgame").get();
Elements gameElements = doc.select("td.collection_thumbnail");
for (Element element : gameElements) {
TopGame game = new TopGame();
Element link = element.getElementsByTag("a").first();
game.id = getGameIdFromLink(link.attr("href"));
game.rank = rank;
game.yearPublished = 0;
game.thumbnailUrl = link.child(0).attr("src").replaceAll("_mt\\.", "_t.");
Element gameNameElement = element.parent().select(".collection_objectname").get(0).child(1);
game.name = gameNameElement.child(0).text();
String yearPublishedText = gameNameElement.child(1).text();
game.yearPublished = Integer.parseInt(yearPublishedText.substring(1, yearPublishedText.length() - 1));
topGames.add(game);
rank++;
}
return topGames;
}
private int getGameIdFromLink(String href) {
int boardGameIndex = href.indexOf("/boardgame/");
String afterBoardGameString;
if (boardGameIndex != -1) {
afterBoardGameString = href.substring(boardGameIndex + 11);
} else {
int boardGameExpansionIndex = href.indexOf("/boardgameexpansion/");
afterBoardGameString = href.substring(boardGameExpansionIndex + 20);
}
int slashIndex = afterBoardGameString.indexOf("/");
return Integer.parseInt(afterBoardGameString.substring(0, slashIndex));
}
}