package treehou.se.habit.ui.sitemaps;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.trello.rxlifecycle.RxLifecycle;
import com.trello.rxlifecycle.components.support.RxFragment;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import io.realm.Realm;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.subjects.BehaviorSubject;
import se.treehou.ng.ohcommunicator.connector.models.OHServer;
import se.treehou.ng.ohcommunicator.connector.models.OHSitemap;
import treehou.se.habit.HabitApplication;
import treehou.se.habit.R;
import treehou.se.habit.module.ServerLoaderFactory;
import treehou.se.habit.ui.adapter.SitemapListAdapter;
import treehou.se.habit.util.Settings;
public class SitemapListFragment extends RxFragment {
private static final String TAG = "SitemapSelectFragment";
private static final String ARG_SHOW_SITEMAP = "showSitemap";
@Inject Settings settings;
@Inject ServerLoaderFactory serverLoaderFactory;
@BindView(R.id.list) RecyclerView listView;
@BindView(R.id.empty) TextView emptyView;
private SitemapListAdapter sitemapAdapter;
private String showSitemap = "";
private Realm realm;
private Unbinder unbinder;
private BehaviorSubject<OHServer> serverBehaviorSubject = BehaviorSubject.create();
/**
* Create fragment where user can select sitemap.
*
* @return Fragment
*/
public static SitemapListFragment newInstance() {
SitemapListFragment fragment = new SitemapListFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
/**
* Load sitemaps for servers.
* Open provided sitemap if loaded.
*
* @param sitemap name of sitemap to load
* @return Fragment
*/
public static SitemapListFragment newInstance(String sitemap) {
SitemapListFragment fragment = new SitemapListFragment();
Bundle args = new Bundle();
args.putString(ARG_SHOW_SITEMAP, sitemap);
fragment.setArguments(args);
return fragment;
}
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public SitemapListFragment() {}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((HabitApplication) getActivity().getApplication()).component().inject(this);
realm = Realm.getDefaultInstance();
if(savedInstanceState != null) showSitemap = "";
else showSitemap = getArguments().getString(ARG_SHOW_SITEMAP);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_sitemaplist, container, false);
unbinder = ButterKnife.bind(this, view);
setupActionBar();
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 1);
listView.setLayoutManager(gridLayoutManager);
listView.setItemAnimator(new DefaultItemAnimator());
sitemapAdapter = new SitemapListAdapter(getContext());
sitemapAdapter.setSitemapSelectedListener(new SitemapListAdapter.SitemapSelectedListener() {
@Override
public void onSelected(OHServer server, OHSitemap sitemap) {
settings.setDefaultSitemap(sitemap);
openSitemap(server, sitemap);
}
@Override
public void onErrorSelected(OHServer server) {
serverBehaviorSubject.onNext(server);
}
});
listView.setAdapter(sitemapAdapter);
return view;
}
/**
* Open fragment showing sitemap.
*
* @param server the server of default sitemap.
* @param sitemap the name of sitemap to show.
*/
private void openSitemap(OHServer server, OHSitemap sitemap){
FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.page_container, SitemapFragment.newInstance(server, sitemap))
.addToBackStack(null)
.commit();
}
/**
* Setup actionbar.
*/
private void setupActionBar(){
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if(actionBar != null) actionBar.setTitle(R.string.sitemaps);
}
/**
* Clears list of sitemaps.
*/
private void clearList() {
emptyView.setVisibility(View.VISIBLE);
sitemapAdapter.clear();
}
@Override
public void onResume() {
super.onResume();
clearList();
loadSitemapsFromServers();
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@Override
public void onDestroy() {
super.onDestroy();
realm.close();
}
/**
* Load servers from database and request their sitemaps.
*/
private void loadSitemapsFromServers(){
Observable.merge(Realm.getDefaultInstance().asObservable().compose(serverLoaderFactory.loadServersRx()),
serverBehaviorSubject.asObservable())
.doOnNext(server -> {
//sitemapAdapter.setServerState(server, SitemapListAdapter.STATE_LOADING);
emptyView.setVisibility(View.GONE);
})
.compose(serverLoaderFactory.serverToSitemap(getActivity()))
.observeOn(AndroidSchedulers.mainThread())
.compose(RxLifecycle.bindFragment(this.lifecycle()))
.compose(serverLoaderFactory.filterDisplaySitemaps())
.subscribe(serverSitemaps -> {
OHServer server = serverSitemaps.first;
List<OHSitemap> sitemaps = serverSitemaps.second;
if(sitemaps.size() <= 0){
sitemapAdapter.setServerState(server, SitemapListAdapter.STATE_ERROR);
} else {
boolean autoloadLast = settings.getAutoloadSitemapRx().get();
for (OHSitemap sitemap : sitemaps) {
sitemapAdapter.add(server, sitemap);
if (autoloadLast && sitemap.getName().equals(showSitemap)) {
showSitemap = null; // Prevents sitemap from being accessed again.
openSitemap(server, sitemap);
}
}
}
}, throwable -> {
Log.e(TAG, "Request sitemap failed", throwable);
});
}
}