<commit_before>package com.marverenic.heterogeneousadapter;

import android.support.annotation.IdRes;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

public class DragDropAdapter extends HeterogeneousAdapter {

    private DragSection mDragSection;
    private ItemTouchHelper mTouchHelper;

    /**
     * Attach this adapter to a View. You MUST call this method if you want drag and drop to work.
     * This method will call {@link RecyclerView#setAdapter(RecyclerView.Adapter)} in addition to
     * setting up drag and drop.
     * @param recyclerView The RecyclerView to bind this adapter to
     */
    public void attach(RecyclerView recyclerView) {
        recyclerView.setAdapter(this);
        mTouchHelper = new ItemTouchHelper(new TouchCallback(this));
        mTouchHelper.attachToRecyclerView(recyclerView);
    }

    @Override
    public EnhancedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        final EnhancedViewHolder viewHolder = super.onCreateViewHolder(parent, viewType);

        if (mDragSection != null && viewType == mDragSection.getTypeId()) {
            View handle = viewHolder.itemView.findViewById(mDragSection.getDragHandleId());
            handle.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
                        mTouchHelper.startDrag(viewHolder);
                        viewHolder.itemView.setTag(new DragMarker(viewHolder.getAdapterPosition()));
                    }
                    return false;
                }
            });
        }
        return viewHolder;
    }

    public DragDropAdapter setDragSection(DragSection section) {
        return setDragSection(section, getSectionCount());
    }

    public DragDropAdapter setDragSection(DragSection section, int index) {
        if (mDragSection != null) {
            throw new IllegalStateException("A DragSection has already been attached. "
                    + "You must remove it before setting a new drag section.");
        }

        super.addSection(section, index);
        mDragSection = section;
        return this;
    }

    private void drag(int from, int to) {
        int leadingViews = getLeadingViewCount(mDragSection.getTypeId());
        mDragSection.onDrag(from - leadingViews, to - leadingViews);
        notifyItemMoved(from, to);
    }

    private void drop(RecyclerView.ViewHolder viewHolder) {
        int leadingViews = getLeadingViewCount(mDragSection.getTypeId());
        mDragSection.onDrop(
                ((DragMarker) viewHolder.itemView.getTag()).from - leadingViews,
                viewHolder.getAdapterPosition() - leadingViews);
        viewHolder.itemView.setTag(null);
    }

    public static abstract class DragSection<Type> extends Section<Type> {

        /**
         * @return The view ID of that may be touched to begin a drag gesture. If the entire view
         *         may be used, return its ID, otherwise return the ID of a specific view in
         *         the itemView hierarchy
         */
        @IdRes
        public abstract int getDragHandleId();

        /**
         * Called when a drag and drop operation has caused items in the Section to move.
         * Implementors are only responsible for updating the backing data set.
         * {@link android.support.v7.widget.RecyclerView.Adapter#notifyItemMoved(int, int)} will be
         * called automatically. Because this method may be called many times throughout the
         * lifecycle of a drag gesture, it should not be used to apply the change of this operation<commit_msg>Fix unexpected behavior when reordering queue items<commit_after>package com.marverenic.heterogeneousadapter;

import android.support.annotation.IdRes;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import java.util.List;

public class DragDropAdapter extends HeterogeneousAdapter {

    private DragSection mDragSection;
    private ItemTouchHelper mTouchHelper;

    /**
     * Attach this adapter to a View. You MUST call this method if you want drag and drop to work.
     * This method will call {@link RecyclerView#setAdapter(RecyclerView.Adapter)} in addition to
     * setting up drag and drop.
     * @param recyclerView The RecyclerView to bind this adapter to
     */
    public void attach(RecyclerView recyclerView) {
        recyclerView.setAdapter(this);
        mTouchHelper = new ItemTouchHelper(new TouchCallback(this));
        mTouchHelper.attachToRecyclerView(recyclerView);
    }

    @Override
    public EnhancedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        final EnhancedViewHolder viewHolder = super.onCreateViewHolder(parent, viewType);

        if (mDragSection != null && viewType == mDragSection.getTypeId()) {
            View handle = viewHolder.itemView.findViewById(mDragSection.getDragHandleId());
            handle.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    if (event.getAction() == MotionEvent.ACTION_DOWN) {
                        mTouchHelper.startDrag(viewHolder);
                        viewHolder.itemView.setTag(new DragMarker(viewHolder.getAdapterPosition()));
                    }
                    return false;
                }
            });
        }
        return viewHolder;
    }

    public DragDropAdapter setDragSection(DragSection section) {
        return setDragSection(section, getSectionCount());
    }

    public DragDropAdapter setDragSection(DragSection section, int index) {
        if (mDragSection != null) {
            throw new IllegalStateException("A DragSection has already been attached. "
                    + "You must remove it before setting a new drag section.");
        }

        super.addSection(section, index);
        mDragSection = section;
        return this;
    }

    private void drag(int from, int to) {
        int leadingViews = getLeadingViewCount(mDragSection.getTypeId());
        mDragSection.onDrag(from - leadingViews, to - leadingViews);
        notifyItemMoved(from, to);
    }

    private void drop(RecyclerView.ViewHolder viewHolder) {
        int leadingViews = getLeadingViewCount(mDragSection.getTypeId());
        mDragSection.onDrop(
                ((DragMarker) viewHolder.itemView.getTag()).from - leadingViews,
                viewHolder.getAdapterPosition() - leadingViews);
        viewHolder.itemView.setTag(null);
        notifyDataSetChanged();
    }

    public static abstract class DragSection<Type> extends Section<Type> {

        /**
         * @return The view ID of that may be touched to begin a drag gesture. If the entire view
         *         may be used, return its ID, otherwise return the ID of a specific view in
         *         the itemView hierarchy
         */
        @IdRes
        public abstract int getDragHandleId();

        /**
         * Called when a drag and drop operation has caused items in the Section to move.
         * Implementors are only responsible for updating the backing data set.
         * {@link android.support.v7.widget.RecyclerView.Adapter#notifyItemMoved(int, int)} will be
         * called automatically. Because this method may be called many times throughout the
         * lifecycle of a drag gesture, it should not be used to apply the change of this operation
{'fraction_non_alphanumeric': 0.07504474558936333, 'fraction_numerical': 0.000767067246228586, 'mean_word_length': 2.6318477251624883, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, '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': '5400650', 'n_tokens_mistral': 2005, 'n_tokens_neox': 1930, 'n_words': 594}