package com.mikepenz.fastadapter_extensions.scroll;

import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.view.View;

public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {

    private int mPreviousTotal = 0;
    private boolean mLoading = true;
    private int mVisibleThreshold = 30;
    private int mFirstVisibleItem, mVisibleItemCount, mTotalItemCount;

    private int mCurrentPage = 1;

    private RecyclerView.LayoutManager mLayoutManager;

    public EndlessRecyclerOnScrollListener(RecyclerView.LayoutManager layoutManager) {
        this.mLayoutManager = layoutManager;
    }

    public EndlessRecyclerOnScrollListener(RecyclerView.LayoutManager layoutManager, int visibleThreshold) {
        this.mLayoutManager = layoutManager;
        this.mVisibleThreshold = visibleThreshold;
    }

    private int findFirstVisibleItemPosition(RecyclerView recyclerView) {
        final View child = findOneVisibleChild(0, mLayoutManager.getChildCount(), false, true);
        return child == null ? RecyclerView.NO_POSITION : recyclerView.getChildAdapterPosition(child);
    }

    private View findOneVisibleChild(int fromIndex, int toIndex, boolean completelyVisible,
                                     boolean acceptPartiallyVisible) {
        OrientationHelper helper;
        if (mLayoutManager.canScrollVertically()) {
            helper = OrientationHelper.createVerticalHelper(mLayoutManager);
        } else {
            helper = OrientationHelper.createHorizontalHelper(mLayoutManager);
        }

        final int start = helper.getStartAfterPadding();
        final int end = helper.getEndAfterPadding();
        final int next = toIndex > fromIndex ? 1 : -1;
        View partiallyVisible = null;
        for (int i = fromIndex; i != toIndex; i += next) {
            final View child = mLayoutManager.getChildAt(i);
            final int childStart = helper.getDecoratedStart(child);
            final int childEnd = helper.getDecoratedEnd(child);
            if (childStart < end && childEnd > start) {
                if (completelyVisible) {
                    if (childStart >= start && childEnd <= end) {
                        return child;
                    } else if (acceptPartiallyVisible && partiallyVisible == null) {
                        partiallyVisible = child;
                    }
                } else {
                    return child;
                }
            }
        }
        return partiallyVisible;
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        mVisibleItemCount = recyclerView.getChildCount();
        mTotalItemCount = mLayoutManager.getItemCount();
        mFirstVisibleItem = findFirstVisibleItemPosition(recyclerView);

        if (mLoading) {
            if (mTotalItemCount > mPreviousTotal) {
                mLoading = false;
                mPreviousTotal = mTotalItemCount;
            }
        }
        if (!mLoading && (mTotalItemCount - mVisibleItemCount)
                <= (mFirstVisibleItem + mVisibleThreshold)) {

            mCurrentPage++;

            onLoadMore(mCurrentPage);

            mLoading = true;
        }
    }

    public int getTotalItemCount() {
        return mTotalItemCount;
    }

    public int getFirstVisibleItem() {
        return mFirstVisibleItem;
    }

    public int getVisibleItemCount() {
        return mVisibleItemCount;
    }

    public int getCurrentPage() {
        return mCurrentPage;
    }

    public abstract void onLoadMore(int currentPage);
}
@@ -172,16 +172,83 @@
 .View;%0A%0A
+import static android.support.v7.widget.RecyclerView.NO_POSITION;%0A%0A
 public a
@@ -738,24 +738,61 @@
 outManager;%0A
+        this.mVisibleThreshold = -1;%0A
     %7D%0A%0A    p
@@ -1270,32 +1270,301 @@
 (child);%0A    %7D%0A%0A
+    private int findLastVisibleItemPosition(RecyclerView recyclerView) %7B%0A        final View child = findOneVisibleChild(recyclerView.getChildCount() - 1, -1, false, true);%0A        return child == null ? NO_POSITION : recyclerView.getChildAdapterPosition(child);%0A    %7D%0A%0A
     private View
@@ -2303,16 +2303,52 @@
 dAt(i);%0A
+            if(child != null) %7B%0A    
         
@@ -2399,32 +2399,36 @@
 edStart(child);%0A
+    
             fina
@@ -2479,32 +2479,36 @@
 d);%0A            
+    
 if (childStart %3C
@@ -2531,24 +2531,28 @@
  %3E start) %7B%0A
+    
             
@@ -2592,32 +2592,36 @@
                 
+    
 if (childStart %3E
@@ -2646,24 +2646,28 @@
 d %3C= end) %7B%0A
+    
             
@@ -2708,24 +2708,28 @@
             
+    
 %7D else if (a
@@ -2773,32 +2773,36 @@
 ible == null) %7B%0A
+    
                 
@@ -2847,34 +2847,42 @@
                 
-%7D%0A
+    %7D%0A    
                 
@@ -2902,32 +2902,36 @@
                 
+    
 return child;%0A  
@@ -2920,32 +2920,54 @@
   return child;%0A
+                    %7D%0A
                 
@@ -3166,16 +3166,174 @@
 x, dy);%0A
+        if (mVisibleThreshold == -1)%0A            mVisibleThreshold = findLastVisibleItemPosition(recyclerView) - findFirstVisibleItemPosition(recyclerView);%0A%0A
         

update EndlessRecyclerOnScrollListener