package fr.ydelouis.selfoss.fragment;
import android.app.Fragment;
import android.content.ContentResolver;
import android.content.SyncStatusObserver;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Background;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.FragmentArg;
import org.androidannotations.annotations.InstanceState;
import org.androidannotations.annotations.UiThread;
import org.androidannotations.annotations.ViewById;
import java.util.ArrayList;
import fr.ydelouis.selfoss.R;
import fr.ydelouis.selfoss.adapter.ArticleAdapter;
import fr.ydelouis.selfoss.entity.Article;
import fr.ydelouis.selfoss.entity.ArticleType;
import fr.ydelouis.selfoss.entity.Filter;
import fr.ydelouis.selfoss.model.ArticleActionHelper;
import fr.ydelouis.selfoss.sync.SyncManager;
import fr.ydelouis.selfoss.view.PagedAdapterViewWrapper;
import uk.co.senab.actionbarpulltorefresh.library.ActionBarPullToRefresh;
import uk.co.senab.actionbarpulltorefresh.library.PullToRefreshLayout;
import uk.co.senab.actionbarpulltorefresh.library.listeners.OnRefreshListener;
@EFragment(R.layout.fragment_articlelist)
public class ArticleListFragment extends Fragment
implements
AdapterView.OnItemClickListener,
OnRefreshListener,
SyncStatusObserver,
AbsListView.MultiChoiceModeListener {
@FragmentArg
@InstanceState
protected Filter filter = new Filter();
@Bean
protected ArticleAdapter adapter;
@Bean
protected SyncManager syncManager;
@Bean
protected ArticleActionHelper actionHelper;
private Object syncStatusHandler;
@InstanceState
protected ArrayList<Article> selectedItems = new ArrayList<Article>();
@ViewById
protected PagedAdapterViewWrapper wrapper;
@ViewById
protected PullToRefreshLayout pullToRefresh;
private MenuItem markRead;
private MenuItem markStarred;
private Listener listener = new DummyListener();
@AfterViews
protected void initViews() {
wrapper.setReloadOnClickOnError(true);
wrapper.getAdapterView().setOnItemClickListener(this);
wrapper.getAdapterView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
wrapper.getAdapterView().setMultiChoiceModeListener(this);
adapter.registerReceivers();
ActionBarPullToRefresh.from(getActivity())
.allChildrenArePullable()
.listener(this)
.setup(pullToRefresh);
}
@Override
public void onResume() {
super.onResume();
syncStatusHandler = ContentResolver.addStatusChangeListener(ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, this);
updateSyncState();
updateAdapterIfNotNewest();
}
@Override
public void onPause() {
ContentResolver.removeStatusChangeListener(syncStatusHandler);
super.onPause();
}
@Override
public void onDestroy() {
adapter.unregisterReceivers();
super.onDestroy();
}
private void updateAdapter() {
adapter.setAdapterViewWrapper(wrapper);
adapter.setFilter(filter);
}
private void updateAdapterIfNotNewest() {
if (!ArticleType.Newest.equals(filter.getType())) {
updateAdapter();
}
}
public void setListener(Listener listener) {
this.listener = listener != null ? listener : new DummyListener();
}
public void setFilter(Filter filter) {
this.filter = filter;
updateAdapter();
}
public Filter getFilter() {
return filter;
}
public void setArticleType(ArticleType type) {
this.filter.setType(type);
updateAdapter();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Article article = adapter.getItem(position);
if (article != null) {
listener.onArticleClicked(article);
}
}
@Override
public void onRefreshStarted(View view) {
synchronize();
}
protected void synchronize() {
if (!syncManager.isActive()) {
syncManager.requestSync();
}
}
@Override
public void onStatusChanged(int i) {
updateSyncState();
}
@UiThread
protected void updateSyncState() {
boolean syncState = syncManager.isActive();
pullToRefresh.setRefreshing(syncState);
}
@Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
if (checked) {
selectedItems.add(adapter.getItem(position));
} else {
selectedItems.remove(adapter.getItem(position));
}
updateContextualMenu(mode);
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
selectedItems.clear();
mode.getMenuInflater().inflate(R.menu.fragment_articlelist_contextual, menu);
markRead = menu.findItem(R.id.markRead);
markStarred = menu.findItem(R.id.markStarred);
updateContextualMenu(mode);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.markRead) {
markReadOrUnread();
mode.finish();
updateAdapterIfNotNewest();
return true;
}
if (item.getItemId() == R.id.markStarred) {
markFavoriteOrUnstarred();
mode.finish();
updateAdapterIfNotNewest();
return true;
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {}
private void updateContextualMenu(ActionMode mode) {
mode.setTitle(String.format(getString(R.string.n_articles), selectedItems.size()));
boolean willMarkRead = willMarkRead();
markRead.setIcon(willMarkRead ? R.drawable.ic_menu_read : R.drawable.ic_menu_unread);
markRead.setTitle(willMarkRead ? R.string.markRead : R.string.markUnread);
boolean willMarkStarred = willMarkStarred();
markStarred.setIcon(willMarkStarred ? R.drawable.ic_menu_starred : R.drawable.ic_menu_unstarred);
markStarred.setTitle(willMarkStarred ? R.string.markStarred : R.string.markUnstarred);
}
private boolean willMarkRead() {
return selectedItems.isEmpty() || selectedItems.get(0).isUnread();
}
private boolean willMarkStarred() {
return selectedItems.isEmpty() || !selectedItems.get(0).isStarred();
}
private void markReadOrUnread() {
if (willMarkRead()) {
actionHelper.markRead(selectedItems);
} else {
actionHelper.markUnread(selectedItems);
}
}
private void markFavoriteOrUnstarred() {
if (willMarkStarred()) {
actionHelper.markStarred(selectedItems);
} else {
actionHelper.markUnstarred(selectedItems);
}
}
@Click(R.id.markAllRead)
@Background
protected void markAllRead() {
actionHelper.markAllRead(filter);
}
public interface Listener {
void onArticleClicked(Article article);
}
private static class DummyListener implements Listener {
@Override
public void onArticleClicked(Article article) {
}
}
}