package tech.starwin.widget;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by SiKang on 2018/12/17.
 */
public class BannerView extends ViewPager {
    private BannerAdapter bannerAdapter;
    private OnPageChangeListener pageChangeListener;

    public BannerView(@NonNull Context context) {
        super(context);
    }

    public BannerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 绑定数据
     */
    public <Data> void setData(List<Data> data, OnBannerChangedListener<Data> listener) {
        bannerAdapter = new BannerAdapter<>(getContext(), data, listener);
        setAdapter(bannerAdapter);
    }


    /**
     * 开启循环
     */
    public void startLoop() {
        if (bannerAdapter != null && !bannerAdapter.isLoopping()) {
            bannerAdapter.openLoop();
            setCurrentItem(1);
            pageChangeListener = new OnPageChangeListener() {
                @Override
                public void onPageScrolled(int i, float v, int i1) {

                }

                @Override
                public void onPageSelected(int i) {

                }

                @Override
                public void onPageScrollStateChanged(int state) {
                    //若viewpager滑动未停止，或没有开启循环，则不做处理
                    if (state != ViewPager.SCROLL_STATE_IDLE || !bannerAdapter.isLoopping())
                        return;
                    //循环，若当前为第一张，设置页面为倒数第二张 反之同理
                    int current = getCurrentItem();
                    if (current == 0) {
                        setCurrentItem(bannerAdapter.getCount() - 2, false);
                    } else if (current == bannerAdapter.getCount() - 1) {
                        // 若当前为倒数第一张，设置页面为第二张
                        setCurrentItem(1, false);
                    }
                }
            };
            addOnPageChangeListener(pageChangeListener);
        }
    }

    /**
     * 停止循环
     */
    public void stopLoop() {
        if (bannerAdapter != null && bannerAdapter.isLoopping) {
            if (pageChangeListener != null) {
                removeOnPageChangeListener(pageChangeListener);
                pageChangeListener = null;
            }
            bannerAdapter.colseLoop();
            setCurrentItem(0);
        }
    }

    public interface OnBannerChangedListener<Data> {
        void onPageCreate(ImageView imageView, int posigion, Data data);

        void onPageClick(ImageView imageView, int posigion, Data data);
    }

    public static class BannerAdapter<Data> extends PagerAdapter {
        private Context context;
        /**
         * Banner数据
         */
        private List<Data> dataList;
        /**
         * 缓存的Page
         */
        private List<ImageView> viewList;
        /**
         * 是否开启无线循环
         */
        private boolean isLoopping = false;

        private OnBannerChangedListener<Data> pagerChangedListener;

        /**
         * 开启循环
         */
        public void openLoop() {
            if (!isLoopping) {
                isLoopping = true;
                dataList.add(0, dataList.get(dataList.size() - 1));
                dataList.add(dataList.get(1));
                notifyDataSetChanged();
            }
        }

        /**
         * 关闭循环
         */
        public void colseLoop() {
            if (isLoopping) {
                isLoopping = false;
                dataList.remove(0);
                dataList.remove(dataList.size() - 1);
                notifyDataSetChanged();
            }
        }

        public BannerAdapter(Context context, List<Data> datas, OnBannerChangedListener<Data> listener) {
            this.context = context;
            this.dataList = datas;
            this.viewList = new ArrayList<>();
            this.pagerChangedListener = listener;
        }

        @Override
        public int getCount() {
            return dataList.size();
        }


        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, final int position) {
            final ImageView pagerView = new ImageView(context);
            ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
            pagerView.setLayoutParams(layoutParams);
            pagerView.setScaleType(ImageView.ScaleType.FIT_XY);


            pagerView.setTag(position);
            container.addView(pagerView);
            viewList.add(pagerView);

            if (pagerChangedListener != null) {
                pagerChangedListener.onPageCreate(pagerView, position, dataList.get(position));
                pagerView.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        pagerChangedListener.onPageClick(pagerView, position, dataList.get(position));
                    }
                });
            }

            return pagerView;
        }

        @Override
        public void destroyItem(@NonNull final ViewGroup container, final int position, @NonNull Object object) {
            ImageView removePager = null;
            for (ImageView pager : viewList) {
                if (pager.getTag() != null == pager.getTag() instanceof Integer) {
                    if ((int) pager.getTag() == position) {
                        removePager = pager;
                    }
                }
            }
            if (removePager != null) {
                container.removeView(removePager);
                viewList.remove(removePager);
            }
        }

        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
            return view == o;
        }

        public boolean isLoopping() {
            //如果只有一个item，则循环不可用
            if (dataList.size() < 2) {
                return true;
            }
            return isLoopping;
        }
    }
}
