package com.wangdaye.mysplash.collection.view.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import com.github.rahatarmanahmed.cpv.CircularProgressView;
import com.wangdaye.mysplash.Mysplash;
import com.wangdaye.mysplash.R;
import com.wangdaye.mysplash.common.data.entity.unsplash.Photo;
import com.wangdaye.mysplash.common.data.entity.unsplash.User;
import com.wangdaye.mysplash.common.i.model.ScrollModel;
import com.wangdaye.mysplash.common.i.presenter.SwipeBackPresenter;
import com.wangdaye.mysplash.common.i.view.SwipeBackView;
import com.wangdaye.mysplash.common._basic.MysplashActivity;
import com.wangdaye.mysplash.common.ui.adapter.PhotoAdapter;
import com.wangdaye.mysplash.common.ui.dialog.SelectCollectionDialog;
import com.wangdaye.mysplash.common.ui.widget.SwipeBackCoordinatorLayout;
import com.wangdaye.mysplash.common.ui.widget.nestedScrollView.NestedScrollFrameLayout;
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.AuthManager;
import com.wangdaye.mysplash.common.utils.manager.ThemeManager;
import com.wangdaye.mysplash.collection.model.widget.LoadObject;
import com.wangdaye.mysplash.collection.model.widget.PhotosObject;
import com.wangdaye.mysplash.collection.model.widget.ScrollObject;
import com.wangdaye.mysplash.collection.presenter.widget.LoadImplementor;
import com.wangdaye.mysplash.collection.presenter.widget.PhotosImplementor;
import com.wangdaye.mysplash.collection.presenter.widget.ScrollImplementor;
import com.wangdaye.mysplash.common.data.entity.unsplash.Collection;
import com.wangdaye.mysplash.common.i.model.LoadModel;
import com.wangdaye.mysplash.common.i.model.PhotosModel;
import com.wangdaye.mysplash.common.i.presenter.LoadPresenter;
import com.wangdaye.mysplash.common.i.presenter.PhotosPresenter;
import com.wangdaye.mysplash.common.i.presenter.ScrollPresenter;
import com.wangdaye.mysplash.common.i.view.LoadView;
import com.wangdaye.mysplash.common.i.view.PhotosView;
import com.wangdaye.mysplash.common.i.view.ScrollView;
import com.wangdaye.mysplash.common.ui.widget.swipeRefreshView.BothWaySwipeRefreshLayout;
import com.wangdaye.mysplash.collection.presenter.widget.SwipeBackImplementor;
import com.wangdaye.mysplash.collection.view.activity.CollectionActivity;
import java.util.ArrayList;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
/**
* Collection photos view.
*
* This view is used to show the photos in a collection.
*
* */
public class CollectionPhotosView extends NestedScrollFrameLayout
implements PhotosView, LoadView, ScrollView, SwipeBackView,
View.OnClickListener, BothWaySwipeRefreshLayout.OnRefreshAndLoadListener,
SelectCollectionDialog.OnCollectionsChangedListener {
@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 PhotosModel photosModel;
private PhotosPresenter photosPresenter;
private LoadModel loadModel;
private LoadPresenter loadPresenter;
private ScrollModel scrollModel;
private ScrollPresenter scrollPresenter;
private SwipeBackPresenter swipeBackPresenter;
public CollectionPhotosView(Context context) {
super(context);
this.initialize();
}
public CollectionPhotosView(Context context, AttributeSet attrs) {
super(context, attrs);
this.initialize();
}
public CollectionPhotosView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.initialize();
}
// init.
@SuppressLint("InflateParams")
private void initialize() {
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);
initView();
}
private void initView() {
this.initContentView();
this.initLoadingView();
}
private void initContentView() {
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,
(int) (navigationBarHeight + new DisplayUtils(getContext()).dpToPx(16)));
int columnCount = DisplayUtils.getGirdColumnCount(getContext());
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(onScrollListener);
}
private void initLoadingView() {
retryButton.setVisibility(GONE);
retryButton.setOnClickListener(this);
}
public void initMP(CollectionActivity a, Collection c) {
initModel(a, c);
initPresenter();
recyclerView.setAdapter(photosPresenter.getAdapter());
photosPresenter.getAdapter().setRecyclerView(recyclerView);
}
private void initModel(CollectionActivity a, Collection c) {
PhotoAdapter adapter = new PhotoAdapter(
a, new ArrayList<Photo>(Mysplash.DEFAULT_PER_PAGE), this, a);
adapter.setInMyCollection(
AuthManager.getInstance().getUsername() != null
&& AuthManager.getInstance().getUsername().equals(c.user.username));
this.photosModel = new PhotosObject(
adapter,
c,
c.curated ? PhotosObject.PHOTOS_TYPE_CURATED : PhotosObject.PHOTOS_TYPE_NORMAL);
this.loadModel = new LoadObject(LoadObject.LOADING_STATE);
this.scrollModel = new ScrollObject();
}
private void initPresenter() {
this.photosPresenter = new PhotosImplementor(photosModel, this);
this.loadPresenter = new LoadImplementor(loadModel, this);
this.scrollPresenter = new ScrollImplementor(scrollModel, this);
this.swipeBackPresenter = new SwipeBackImplementor(this);
}
// control nested scroll.
@Override
public boolean isParentOffset() {
return false;
}
// control.
/**
* Set activity for the adapter in this view.
*
* @param a Container activity.
* */
public void setActivity(MysplashActivity a) {
photosPresenter.setActivityForAdapter(a);
}
/**
* Execute the initialize animation.
* */
public void initAnimShow() {
AnimUtils.animInitShow(progressView, 400);
}
public void initRefresh() {
photosPresenter.initRefresh(getContext());
}
public void cancelRequest() {
photosPresenter.cancelRequest();
}
public boolean needPagerBackToTop() {
return scrollPresenter.needBackToTop();
}
/**
* Control the photo list in this view to scroll to the top.
* */
public void pagerBackToTop() {
scrollPresenter.scrollToTop();
}
public boolean canSwipeBack(int dir) {
return swipeBackPresenter.checkCanSwipeBack(dir);
}
public Collection getCollection() {
return (Collection) photosPresenter.getRequestKey();
}
public void updatePhoto(Photo photo) {
photosPresenter.getAdapter().updatePhoto(photo, false, false);
}
/**
* Get the photos from the adapter in this view.
*
* @return Photos in adapter.
* */
public List<Photo> getPhotos() {
return photosPresenter.getAdapter().getPhotoData();
}
/**
* Set photos to the adapter in this view.
*
* @param list Photos that will be set to the adapter.
* */
public void setPhotos(List<Photo> list) {
if (list == null) {
list = new ArrayList<>();
}
photosPresenter.getAdapter().setPhotoData(list);
if (list.size() == 0) {
initRefresh();
} else {
setNormalState();
}
}
// interface.
// on click listener.
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.container_loading_view_mini_retryButton:
photosPresenter.initRefresh(getContext());
break;
}
}
// on refresh and load listener.
@Override
public void onRefresh() {
photosPresenter.refreshNew(getContext(), false);
}
@Override
public void onLoad() {
photosPresenter.loadMore(getContext(), false);
}
// on scroll listener.
private RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
scrollPresenter.autoLoad(dy);
}
};
// on collections change listener.
@Override
public void onAddCollection(Collection c) {
// do nothing.
}
@Override
public void onUpdateCollection(Collection c, User u, Photo p) {
photosPresenter.getAdapter().updatePhoto(p, false, true);
if (((Collection) photosPresenter.getRequestKey()).id == c.id) {
for (int i = 0; i < p.current_user_collections.size(); i ++) {
if (p.current_user_collections.get(i).id == c.id) {
photosPresenter.getAdapter().insertItemToFirst(p);
return;
}
}
photosPresenter.getAdapter().removeItem(p);
}
}
// view.
// photos 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 requestPhotosSuccess() {
loadPresenter.setNormalState();
}
@Override
public void requestPhotosFailed(String feedback) {
loadPresenter.setFailedState();
}
// 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 = photosPresenter.getAdapter().getRealItemCount();
if (photosPresenter.canLoadMore()
&& lastVisibleItems[lastVisibleItems.length - 1] >= totalItemCount - 10
&& totalItemCount > 0
&& dy > 0) {
photosPresenter.loadMore(getContext(), false);
}
if (!ViewCompat.canScrollVertically(recyclerView, -1)) {
scrollPresenter.setToTop(true);
} else {
scrollPresenter.setToTop(false);
}
if (!ViewCompat.canScrollVertically(recyclerView, 1) && photosPresenter.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)
|| photosPresenter.getAdapter().getRealItemCount() <= 0;
default:
return true;
}
}
}