<commit_before>package me.everything.android.ui.overscroll.adapters;

import android.graphics.Canvas;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;

import java.util.List;

import me.everything.android.ui.overscroll.HorizontalOverScrollBounceEffectDecorator;
import me.everything.android.ui.overscroll.VerticalOverScrollBounceEffectDecorator;

/**
 * @author amitd
 *
 * @see HorizontalOverScrollBounceEffectDecorator
 * @see VerticalOverScrollBounceEffectDecorator
 */
public class RecyclerViewOverScrollDecorAdapter implements IOverScrollDecoratorAdapter {

    /**
     * A delegation of the adapter implementation of this view that should provide the processing
     * of {@link #isInAbsoluteStart()} and {@link #isInAbsoluteEnd()}. Essentially needed simply
     * because the implementation depends on the layout manager implementation being used.
     */
    protected interface Impl {
        boolean isInAbsoluteStart();
        boolean isInAbsoluteEnd();
    }

    protected final RecyclerView mRecyclerView;
    protected final Impl mImpl;

    protected boolean mIsItemTouchInEffect = false;

    public RecyclerViewOverScrollDecorAdapter(RecyclerView recyclerView) {

        mRecyclerView = recyclerView;

        final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof LinearLayoutManager) {
            mImpl = new ImplLinearLayout(recyclerView, (LinearLayoutManager) layoutManager);
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            mImpl = new ImplStaggeredGridLayout(recyclerView, (StaggeredGridLayoutManager) layoutManager);
        } else {
            throw new IllegalArgumentException("Recycler views with custom layout managers are not supported by this adapter out of the box." +
                    "Try implementing and providing an explicit 'impl' parameter to the other c'tors, or otherwise create a custom adapter subclass of your own.");
        }
    }

    public RecyclerViewOverScrollDecorAdapter(RecyclerView recyclerView, Impl impl) {
        mRecyclerView = recyclerView;
        mImpl = impl;
    }

    public RecyclerViewOverScrollDecorAdapter(RecyclerView recyclerView, ItemTouchHelper.Callback itemTouchHelperCallback) {
        this(recyclerView);
        setUpTouchHelperCallback(itemTouchHelperCallback);
    }

    public RecyclerViewOverScrollDecorAdapter(RecyclerView recyclerView, Impl impl, ItemTouchHelper.Callback itemTouchHelperCallback) {
        this(recyclerView, impl);
        setUpTouchHelperCallback(itemTouchHelperCallback);
    }

    protected void setUpTouchHelperCallback(final ItemTouchHelper.Callback itemTouchHelperCallback) {
        new ItemTouchHelper(new ItemTouchHelperCallbackWrapper(itemTouchHelperCallback) {
            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
                mIsItemTouchInEffect = actionState != 0;
                super.onSelectedChanged(viewHolder, actionState);
            }
        }).attachToRecyclerView(mRecyclerView);
    }

    @Override
    public View getView() {
        return mRecyclerView;
    }

    @Override
    public boolean isInAbsoluteStart() {
        return !mIsItemTouchInEffect && mImpl.isInAbsoluteStart();
    }

    @Override
    public boolean isInAbsoluteEnd() {
        return !mIsItemTouchInEffect && mImpl.isInAbsoluteEnd();
    }

    public static class ImplLinearLayout implements Impl {

        private final RecyclerView mRecyclerView;
        private final LinearLayoutManager mLayoutManager;

        public ImplLinearLayout(RecyclerView recyclerView, LinearLayoutManager layoutManager) {
            mRecyclerView = recyclerView;
            mLayoutManager = layoutManager;
        }

        @Override
        public boolean isInAbsoluteStart() {
            return mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0;
        }

        @Override
        public boolean isInAbsoluteEnd() {
            return mLayoutManager.findLastCompletelyVisibleItemPosition() == (mRecyclerView.getAdapter().getItemCount() - 1);
        }
    }

    protected static class ImplStaggeredGridLayout implements Impl {

        private final RecyclerView mRecyclerView;
        private final StaggeredGridLayoutManager mLayoutManager;
        final int[] mVisiblePositionsBuffer;

        public ImplStaggeredGridLayout(RecyclerView recyclerView, StaggeredGridLayoutManager layoutManager) {
            mRecyclerView = recyclerView;
            mLayoutManager = layoutManager;

            final int spanCount = layoutManager.getSpanCount();
            mVisiblePositionsBuffer = new int[spanCount];
        }

        @Override
        public boolean isInAbsoluteStart() {
            mLayoutManager.findFirstCompletelyVisibleItemPositions(mVisiblePositionsBuffer);
            return mVisiblePositionsBuffer[0] == 0;
        }

        @Override
        public boolean isInAbsoluteEnd() {
            mLayoutManager.findLastCompletelyVisibleItemPositions(mVisiblePositionsBuffer);

            final int lastItemPos = mRecyclerView.getAdapter().getItemCount() - 1;
            for (int item : mVisiblePositionsBuffer) {
                if (item == lastItemPos) {
                    return true;<commit_msg>Issue 9 fix<commit_after>package me.everything.android.ui.overscroll.adapters;

import android.graphics.Canvas;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;

import java.util.List;

import me.everything.android.ui.overscroll.HorizontalOverScrollBounceEffectDecorator;
import me.everything.android.ui.overscroll.VerticalOverScrollBounceEffectDecorator;

/**
 * @author amitd
 *
 * @see HorizontalOverScrollBounceEffectDecorator
 * @see VerticalOverScrollBounceEffectDecorator
 */
public class RecyclerViewOverScrollDecorAdapter implements IOverScrollDecoratorAdapter {

    /**
     * A delegation of the adapter implementation of this view that should provide the processing
     * of {@link #isInAbsoluteStart()} and {@link #isInAbsoluteEnd()}. Essentially needed simply
     * because the implementation depends on the layout manager implementation being used.
     */
    protected interface Impl {
        boolean isInAbsoluteStart();
        boolean isInAbsoluteEnd();
    }

    protected final RecyclerView mRecyclerView;
    protected final Impl mImpl;

    protected boolean mIsItemTouchInEffect = false;

    public RecyclerViewOverScrollDecorAdapter(RecyclerView recyclerView) {

        mRecyclerView = recyclerView;

        final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof LinearLayoutManager) {
            mImpl = new ImplLinearLayout(recyclerView, (LinearLayoutManager) layoutManager);
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            mImpl = new ImplStaggeredGridLayout(recyclerView, (StaggeredGridLayoutManager) layoutManager);
        } else {
            throw new IllegalArgumentException("Recycler views with custom layout managers are not supported by this adapter out of the box." +
                    "Try implementing and providing an explicit 'impl' parameter to the other c'tors, or otherwise create a custom adapter subclass of your own.");
        }
    }

    public RecyclerViewOverScrollDecorAdapter(RecyclerView recyclerView, Impl impl) {
        mRecyclerView = recyclerView;
        mImpl = impl;
    }

    public RecyclerViewOverScrollDecorAdapter(RecyclerView recyclerView, ItemTouchHelper.Callback itemTouchHelperCallback) {
        this(recyclerView);
        setUpTouchHelperCallback(itemTouchHelperCallback);
    }

    public RecyclerViewOverScrollDecorAdapter(RecyclerView recyclerView, Impl impl, ItemTouchHelper.Callback itemTouchHelperCallback) {
        this(recyclerView, impl);
        setUpTouchHelperCallback(itemTouchHelperCallback);
    }

    protected void setUpTouchHelperCallback(final ItemTouchHelper.Callback itemTouchHelperCallback) {
        new ItemTouchHelper(new ItemTouchHelperCallbackWrapper(itemTouchHelperCallback) {
            @Override
            public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
                mIsItemTouchInEffect = actionState != 0;
                super.onSelectedChanged(viewHolder, actionState);
            }
        }).attachToRecyclerView(mRecyclerView);
    }

    @Override
    public View getView() {
        return mRecyclerView;
    }

    @Override
    public boolean isInAbsoluteStart() {
        return !mIsItemTouchInEffect && mImpl.isInAbsoluteStart();
    }

    @Override
    public boolean isInAbsoluteEnd() {
        return !mIsItemTouchInEffect && mImpl.isInAbsoluteEnd();
    }

    public static class ImplLinearLayout implements Impl {

        private final RecyclerView mRecyclerView;
        private final LinearLayoutManager mLayoutManager;

        public ImplLinearLayout(RecyclerView recyclerView, LinearLayoutManager layoutManager) {
            mRecyclerView = recyclerView;
            mLayoutManager = layoutManager;
        }

        @Override
        public boolean isInAbsoluteStart() {
            return mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0;
        }

        @Override
        public boolean isInAbsoluteEnd() {
            if (mLayoutManager.getOrientation() == LinearLayoutManager.HORIZONTAL){
                return !mRecyclerView.canScrollHorizontally(1);
            } else {
                return !mRecyclerView.canScrollVertically(1);
            }
        }
    }

    protected static class ImplStaggeredGridLayout implements Impl {

        private final RecyclerView mRecyclerView;
        private final StaggeredGridLayoutManager mLayoutManager;
        final int[] mVisiblePositionsBuffer;

        public ImplStaggeredGridLayout(RecyclerView recyclerView, StaggeredGridLayoutManager layoutManager) {
            mRecyclerView = recyclerView;
            mLayoutManager = layoutManager;

            final int spanCount = layoutManager.getSpanCount();
            mVisiblePositionsBuffer = new int[spanCount];
        }

        @Override
        public boolean isInAbsoluteStart() {
            mLayoutManager.findFirstCompletelyVisibleItemPositions(mVisiblePositionsBuffer);
            return mVisiblePositionsBuffer[0] == 0;
        }

        @Override
        public boolean isInAbsoluteEnd() {
            mLayoutManager.findLastCompletelyVisibleItemPositions(mVisiblePositionsBuffer);

            final int lastItemPos = mRecyclerView.getAdapter().getItemCount() - 1;
            for (int item : mVisiblePositionsBuffer) {
                if (item == lastItemPos) {
                    return true;
{'fraction_non_alphanumeric': 0.06402083146269193, 'fraction_numerical': 0.0019753973242345336, 'mean_word_length': 3.3120402632597754, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '836731', 'n_tokens_mistral': 2928, 'n_tokens_neox': 2753, 'n_words': 641}