package net.idik.lib.slimadapter.ex.loadmore;

import android.content.Context;
import android.os.HandlerThread;
import android.os.Message;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import net.idik.lib.slimadapter.SlimAdapter;

import java.util.List;

/**
 * Created by linshuaibin on 16/05/2017.
 */

public abstract class SlimMoreLoader extends RecyclerView.OnScrollListener {
    private static final int WHAT_LOAD_MORE = 1;

    private SlimLoadMoreView loadMoreView;
    private boolean loading;
    private LoadMoreViewCreator loadMoreViewCreator;
    private Context context;

    private SlimAdapter slimAdapter;
    private android.os.Handler eventHandler;

    private Handler handler;


    protected SlimMoreLoader(Context context, LoadMoreViewCreator creator) {
        this.context = context;
        this.loadMoreViewCreator = creator;
        this.loadMoreViewCreator.attachLoader(this);
        initHandler();
    }

    public SlimMoreLoader(Context context) {
        this(context, new SimpleLoadMoreViewCreator(context));
    }

    public void setSlimAdapter(SlimAdapter slimAdapter) {
        this.slimAdapter = slimAdapter;
    }

    private void initHandler() {
        handler = new Handler();
        HandlerThread eventHandlerThread = new HandlerThread(SlimMoreLoader.class.getSimpleName() + ".Thread");
        eventHandlerThread.start();
        eventHandler = new android.os.Handler(eventHandlerThread.getLooper(), new android.os.Handler.Callback() {
            @Override
            public boolean handleMessage(Message msg) {
                switch (msg.what) {
                    case WHAT_LOAD_MORE:
                        onLoadMore(handler);
                        return true;
                    default:
                        return false;
                }
            }
        });
    }

    public SlimLoadMoreView getLoadMoreView() {
        if (loadMoreView == null) {
            loadMoreView = new SlimLoadMoreView(context, loadMoreViewCreator);
        }
        return loadMoreView;
    }

    protected abstract void onLoadMore(Handler handler);

    protected abstract boolean hasMore();

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        switch (newState) {
            case RecyclerView.SCROLL_STATE_IDLE:
                int last = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
                if (slimAdapter.getItem(last) == this && !loading) {
                    loadMore();
                }
                break;
            default:
                break;
        }
    }

    void loadMore() {
        if (hasMore()) {
            loading = true;
            getLoadMoreView().visibleLoadingView();
            eventHandler.removeMessages(WHAT_LOAD_MORE);
            eventHandler.sendEmptyMessage(WHAT_LOAD_MORE);
        } else {
            reset();
        }
    }

    public void reset() {
        loading = false;
        if (hasMore()) {
            getLoadMoreView().visiblePullToLoadMoreView();
        } else {
            getLoadMoreView().visibleNoMoreView();
        }
    }

    protected final class Handler {

        Handler() {
        }

        public void loadCompleted(List<?> data) {
            if (data == null) {
                reset();
                return;
            }
            if (loading) {
                List currentData = slimAdapter.getData();
                if (currentData == null) {
                    currentData = data;
                } else {
                    currentData.addAll(data);
                }
                slimAdapter.updateData(currentData);
            }
        }

        public void error() {
            loading = false;
            getLoadMoreView().visibleErrorView();
        }
    }

}

@@ -304,16 +304,83 @@
 .List;%0A%0A
+import static android.support.v7.widget.RecyclerView.NO_POSITION;%0A%0A
 /**%0A * C
@@ -2617,24 +2617,112 @@
 Position();%0A
+                if (NO_POSITION == last) %7B%0A                    break;%0A                %7D%0A
             

fix ArrayIndexOutOfBoundsException when no complete visible item available