package com.wangdaye.mysplash.user.view.widget;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import com.github.rahatarmanahmed.cpv.CircularProgressView;
import com.wangdaye.mysplash.R;
import com.wangdaye.mysplash.common.data.entity.unsplash.Collection;
import com.wangdaye.mysplash.common.data.entity.unsplash.User;
import com.wangdaye.mysplash.common.i.model.CollectionsModel;
import com.wangdaye.mysplash.common.i.model.LoadModel;
import com.wangdaye.mysplash.common.i.model.ScrollModel;
import com.wangdaye.mysplash.common.i.presenter.CollectionsPresenter;
import com.wangdaye.mysplash.common.i.presenter.LoadPresenter;
import com.wangdaye.mysplash.common.i.presenter.PagerPresenter;
import com.wangdaye.mysplash.common.i.presenter.ScrollPresenter;
import com.wangdaye.mysplash.common.i.presenter.SwipeBackPresenter;
import com.wangdaye.mysplash.common.i.view.CollectionsView;
import com.wangdaye.mysplash.common.i.view.LoadView;
import com.wangdaye.mysplash.common.i.view.PagerView;
import com.wangdaye.mysplash.common.i.view.ScrollView;
import com.wangdaye.mysplash.common.i.view.SwipeBackView;
import com.wangdaye.mysplash.common.ui.widget.SwipeBackCoordinatorLayout;
import com.wangdaye.mysplash.common.ui.widget.nestedScrollView.NestedScrollFrameLayout;
import com.wangdaye.mysplash.common.ui.widget.swipeRefreshView.BothWaySwipeRefreshLayout;
import com.wangdaye.mysplash.common.utils.AnimUtils;
import com.wangdaye.mysplash.common.utils.BackToTopUtils;
import com.wangdaye.mysplash.common.utils.DisplayUtils;
import com.wangdaye.mysplash.common.utils.manager.ThemeManager;
import com.wangdaye.mysplash.user.model.widget.CollectionsObject;
import com.wangdaye.mysplash.user.model.widget.LoadObject;
import com.wangdaye.mysplash.user.model.widget.ScrollObject;
import com.wangdaye.mysplash.user.presenter.widget.CollectionsImplementor;
import com.wangdaye.mysplash.user.presenter.widget.LoadImplementor;
import com.wangdaye.mysplash.user.presenter.widget.PagerImplementor;
import com.wangdaye.mysplash.user.presenter.widget.ScrollImplementor;
import com.wangdaye.mysplash.user.presenter.widget.SwipeBackImplementor;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
* User collections view.
*
* This view is used to show collections for
* {@link com.wangdaye.mysplash.user.view.activity.UserActivity}.
*
* */
@SuppressLint("ViewConstructor")
public class UserCollectionsView extends NestedScrollFrameLayout
implements CollectionsView, PagerView, LoadView, ScrollView, SwipeBackView,
BothWaySwipeRefreshLayout.OnRefreshAndLoadListener {
@BindView(R.id.container_loading_view_mini_progressView)
CircularProgressView progressView;
@BindView(R.id.container_loading_view_mini_retryButton)
Button retryButton;
@BindView(R.id.container_photo_list_swipeRefreshLayout)
BothWaySwipeRefreshLayout refreshLayout;
@BindView(R.id.container_photo_list_recyclerView)
RecyclerView recyclerView;
private CollectionsModel collectionsModel;
private CollectionsPresenter collectionsPresenter;
private PagerPresenter pagerPresenter;
private LoadModel loadModel;
private LoadPresenter loadPresenter;
private ScrollModel scrollModel;
private ScrollPresenter scrollPresenter;
private SwipeBackPresenter swipeBackPresenter;
private static class SavedState implements Parcelable {
int page;
boolean over;
SavedState(UserCollectionsView view) {
this.page = view.collectionsModel.getCollectionsPage();
this.over = view.collectionsModel.isOver();
}
private SavedState(Parcel in) {
this.page = in.readInt();
this.over = in.readByte() != 0;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(this.page);
out.writeByte(this.over ? (byte) 1 : (byte) 0);
}
public static final Parcelable.Creator<SavedState> CREATOR
= new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
public UserCollectionsView(Activity a, User u, int id) {
super(a);
this.setId(id);
this.initialize(a, u);
}
// init.
@SuppressLint("InflateParams")
private void initialize(Activity a, User u) {
View loadingView = LayoutInflater.from(getContext())
.inflate(R.layout.container_loading_view_mini, this, false);
addView(loadingView);
View contentView = LayoutInflater.from(getContext())
.inflate(R.layout.container_photo_list, null);
addView(contentView);
ButterKnife.bind(this, this);
initModel(a, u);
initPresenter();
initView();
}
private void initModel(Activity a, User u) {
this.collectionsModel = new CollectionsObject(a, u);
this.loadModel = new LoadObject(LoadObject.LOADING_STATE);
this.scrollModel = new ScrollObject();
}
private void initPresenter() {
this.collectionsPresenter = new CollectionsImplementor(collectionsModel, this);
this.pagerPresenter = new PagerImplementor(this);
this.loadPresenter = new LoadImplementor(loadModel, this);
this.scrollPresenter = new ScrollImplementor(scrollModel, this);
this.swipeBackPresenter = new SwipeBackImplementor(this);
}
private void initView() {
retryButton.setVisibility(GONE);
refreshLayout.setColorSchemeColors(ThemeManager.getContentColor(getContext()));
refreshLayout.setProgressBackgroundColorSchemeColor(ThemeManager.getRootColor(getContext()));
refreshLayout.setOnRefreshAndLoadListener(this);
refreshLayout.setPermitRefresh(false);
refreshLayout.setVisibility(GONE);
int navigationBarHeight = DisplayUtils.getNavigationBarHeight(getResources());
refreshLayout.setDragTriggerDistance(
BothWaySwipeRefreshLayout.DIRECTION_BOTTOM,
navigationBarHeight + getResources().getDimensionPixelSize(R.dimen.normal_margin));
int columnCount = DisplayUtils.getGirdColumnCount(getContext());
recyclerView.setAdapter(collectionsPresenter.getAdapter());
if (columnCount > 1) {
int margin = getResources().getDimensionPixelSize(R.dimen.little_margin);
recyclerView.setPadding(margin, margin, 0, 0);
} else {
recyclerView.setPadding(0, 0, 0, 0);
}
recyclerView.setLayoutManager(
new StaggeredGridLayoutManager(columnCount, StaggeredGridLayoutManager.VERTICAL));
recyclerView.addOnScrollListener(scrollListener);
}
// control.
@Override
public boolean isParentOffset() {
return true;
}
// collection.
public void updateCollection(Collection c, boolean refreshView) {
collectionsPresenter.getAdapter().updateCollection(c, false, refreshView);
}
/**
* Get the collections from the adapter in this view.
*
* @return Collections in adapter.
* */
public List<Collection> getCollections() {
return collectionsPresenter.getAdapter().getCollectionData();
}
/**
* Set collections to the adapter in this view.
*
* @param list Collections that will be set to the adapter.
* */
public void setCollections(List<Collection> list) {
if (list == null) {
list = new ArrayList<>();
}
collectionsPresenter.getAdapter().setCollectionData(list);
if (list.size() == 0) {
refreshPager();
} else {
setNormalState();
}
}
// interface.
// on click listener.
@OnClick(R.id.container_loading_view_mini_retryButton) void retryRefresh() {
collectionsPresenter.initRefresh(getContext());
}
// on refresh an load listener.
@Override
public void onRefresh() {
collectionsPresenter.refreshNew(getContext(), false);
}
@Override
public void onLoad() {
collectionsPresenter.loadMore(getContext(), false);
}
// on scroll listener.
private RecyclerView.OnScrollListener scrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
scrollPresenter.autoLoad(dy);
}
};
// view.
// collections view.
@Override
public void setRefreshing(boolean refreshing) {
refreshLayout.setRefreshing(refreshing);
}
@Override
public void setLoading(boolean loading) {
refreshLayout.setLoading(loading);
}
@Override
public void setPermitRefreshing(boolean permit) {
refreshLayout.setPermitRefresh(permit);
}
@Override
public void setPermitLoading(boolean permit) {
refreshLayout.setPermitLoad(permit);
}
@Override
public void initRefreshStart() {
loadPresenter.setLoadingState();
}
@Override
public void requestCollectionsSuccess() {
loadPresenter.setNormalState();
}
@Override
public void requestCollectionsFailed(String feedback) {
loadPresenter.setFailedState();
}
// pager view.
@Override
public void onSaveInstanceState(Bundle bundle) {
bundle.putParcelable(String.valueOf(getId()), new SavedState(this));
}
@Override
public void onRestoreInstanceState(Bundle bundle) {
SavedState ss = bundle.getParcelable(String.valueOf(getId()));
if (ss != null) {
collectionsPresenter.setPage(ss.page);
collectionsPresenter.setOver(ss.over);
}
}
@Override
public void checkToRefresh() { // interface
if (pagerPresenter.checkNeedRefresh()) {
pagerPresenter.refreshPager();
}
}
@Override
public boolean checkNeedRefresh() {
return loadPresenter.getLoadState() == LoadObject.FAILED_STATE
|| (loadPresenter.getLoadState() == LoadObject.LOADING_STATE
&& !collectionsPresenter.isRefreshing() && !collectionsPresenter.isLoading());
}
@Override
public boolean checkNeedBackToTop() {
return scrollPresenter.needBackToTop();
}
@Override
public void refreshPager() {
collectionsPresenter.initRefresh(getContext());
}
@Override
public void scrollToPageTop() { // interface.
scrollPresenter.scrollToTop();
}
@Override
public void cancelRequest() {
collectionsPresenter.cancelRequest();
}
@Override
public void setKey(String key) {
// do nothing.
}
@Override
public String getKey() {
return null;
}
@Override
public boolean canSwipeBack(int dir) {
return swipeBackPresenter.checkCanSwipeBack(dir);
}
@Override
public int getItemCount() {
if (loadPresenter.getLoadState() != LoadObject.NORMAL_STATE) {
return 0;
} else {
return collectionsPresenter.getAdapter().getRealItemCount();
}
}
// load view.
@Override
public void animShow(View v) {
AnimUtils.animShow(v);
}
@Override
public void animHide(final View v) {
AnimUtils.animHide(v);
}
@Override
public void setLoadingState() {
animShow(progressView);
animHide(retryButton);
}
@Override
public void setFailedState() {
animShow(retryButton);
animHide(progressView);
}
@Override
public void setNormalState() {
animShow(refreshLayout);
animHide(progressView);
}
@Override
public void resetLoadingState() {
animShow(progressView);
animHide(refreshLayout);
}
// scroll view.
@Override
public void scrollToTop() {
BackToTopUtils.scrollToTop(recyclerView);
}
@Override
public void autoLoad(int dy) {
int[] lastVisibleItems = ((StaggeredGridLayoutManager) recyclerView.getLayoutManager())
.findLastVisibleItemPositions(null);
int totalItemCount = collectionsPresenter.getAdapter().getRealItemCount();
if (collectionsPresenter.canLoadMore()
&& lastVisibleItems[lastVisibleItems.length - 1] >= totalItemCount - 10
&& totalItemCount > 0
&& dy > 0) {
collectionsPresenter.loadMore(getContext(), false);
}
if (!ViewCompat.canScrollVertically(recyclerView, -1)) {
scrollPresenter.setToTop(true);
} else {
scrollPresenter.setToTop(false);
}
if (!ViewCompat.canScrollVertically(recyclerView, 1) && collectionsPresenter.isLoading()) {
refreshLayout.setLoading(true);
}
}
@Override
public boolean needBackToTop() {
return !scrollPresenter.isToTop()
&& loadPresenter.getLoadState() == LoadObject.NORMAL_STATE;
}
// swipe back view.
@Override
public boolean checkCanSwipeBack(int dir) {
switch (loadPresenter.getLoadState()) {
case LoadObject.NORMAL_STATE:
return SwipeBackCoordinatorLayout.canSwipeBack(recyclerView, dir)
|| collectionsPresenter.getAdapter().getRealItemCount() <= 0;
default:
return true;
}
}
}