package com.yuqirong.viewpagerindicator.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.yuqirong.viewpagerindicator.R;

/**
 * ViewPager指示器
 * Created by yuqirong on 2016/4/27.
 */
public class ViewPagerIndicator extends LinearLayout {

    // tab可见数
    private int visibleTabNum;
    // 选中的颜色
    private int selectedColor;
    // 未选中的颜色
    private int unselectedColor;
    // 屏幕宽度
    private int screenWidth;
    // tab的宽度
    private int tabWidth;
    // 横线的偏移
    private float offset;
    // 画笔
    private Paint mPaint;
    // 高度
    private int height;
    // 横线的高度
    private float indicatorHeight;
    // 默认横线的高度
    private float defaultIndicatorHeight;
    // viewpager当前页数
    private int mCurrentItem;
    // 字体大小
    private float textSize;
    // 默认字体大小
    private float defaultTextSize;

    private ViewPager mViewPager;
    // 滑动的最小距离
    private int touchSlop;
    // 上次触摸的x轴坐标
    private float lastX;

    private static final String TAG = "ViewPagerIndicator";

    // 设置offset
    private void setOffset(float offset) {
        this.offset = offset;
        invalidate();
    }

    public ViewPagerIndicator(Context context) {
        this(context, null);
    }

    public ViewPagerIndicator(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 设置横向
        setOrientation(LinearLayout.HORIZONTAL);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerIndicator);
        selectedColor = a.getColor(R.styleable.ViewPagerIndicator_selected_color, Color.BLUE);
        unselectedColor = a.getColor(R.styleable.ViewPagerIndicator_unselected_color, Color.WHITE);
        visibleTabNum = a.getInt(R.styleable.ViewPagerIndicator_visible_tab_num, 4);
        // 默认字体大小
        defaultTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10, context.getResources().getDisplayMetrics());
        textSize = a.getDimension(R.styleable.ViewPagerIndicator_text_size, defaultTextSize);
        // 默认下划横线高度
        defaultIndicatorHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, context.getResources().getDisplayMetrics());
        indicatorHeight = a.getDimension(R.styleable.ViewPagerIndicator_indicator_height, defaultIndicatorHeight);
        a.recycle();
        screenWidth = context.getResources().getDisplayMetrics().widthPixels;
        tabWidth = screenWidth / visibleTabNum;
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(selectedColor);
        mPaint.setStrokeWidth(indicatorHeight);
        mPaint.setStyle(Paint.Style.FILL);
        // 得到touchSlop
        touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
    }

    /**
     * 设置ViewPager， 请确保在设置了adapter之后调用该方法
     *
     * @param viewPager
     */
    public void setViewPager(ViewPager viewPager) {
        if (viewPager == null) {
            return;
        }
        this.mViewPager = viewPager;
        // 得到适配器
        PagerAdapter adapter = viewPager.getAdapter();
        // adapter不能为空
        if (adapter == null) {
            throw new IllegalArgumentException("the adapter of viewpager must be not null..");
        }
        // 先移除所有的子view
        this.removeAllViews();
        // 添加Textview
        for (int i = 0; i < adapter.getCount(); i++) {
            createTextView(adapter.getPageTitle(i).toString(), i);
        }

        mCurrentItem = viewPager.getCurrentItem();
        ((TextView) getChildAt(mCurrentItem)).setTextColor(selectedColor);
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                // 设置了横线的偏移，并引起重绘
                setOffset((position + positionOffset) * tabWidth);
                // tab也要进行相应的移动
                if (position + positionOffset + 1 > visibleTabNum - 1 && position + positionOffset + 1 <= getChildCount() - 1) {
                    scrollTo((int) ((position + positionOffset - visibleTabNum + 2) * tabWidth), 0);
                }
            }

            @Override
            public void onPageSelected(int position) {
                // 字体颜色改变
                ((TextView) getChildAt(mCurrentItem)).setTextColor(unselectedColor);
                ((TextView) getChildAt(position)).setTextColor(selectedColor);
                mCurrentItem = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    // 添加textview到ViewPagerIndicator中
    private void createTextView(String title, int i) {
        TextView tv = new TextView(getContext());
        LinearLayout.LayoutParams params = new LayoutParams(tabWidth, LayoutParams.MATCH_PARENT);
        tv.setLayoutParams(params);
        tv.setText(title);
        tv.setGravity(Gravity.CENTER);
        tv.setTextColor(unselectedColor);
        tv.setTag(i);
        tv.setTextSize(textSize);
        tv.setOnClickListener(tvClickListener);
        this.addView(tv);
    }

    // textview的点击监听器
    OnClickListener tvClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            int i = (int) v.getTag();
            if (mViewPager != null) {
                mViewPager.setCurrentItem(i, true);
            }
        }
    };


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // 当大小改变时，得到一个tab的宽度
        tabWidth = w / visibleTabNum;
        height = h;
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        if (mViewPager != null) {
            canvas.save();
            // 绘制横线
            canvas.drawLine(offset, height - indicatorHeight, offset + tabWidth, height - indicatorHeight, mPaint);
            canvas.restore();
        }
        super.dispatchDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = x;
                break;
            case MotionEvent.ACTION_MOVE:
                float offsetX = x - lastX;
                // 滑动相应的距离
                scrollBy(-(int) offsetX, 0);
                // 最左边界值检查
                if (getScrollX() < 0) {
                    scrollTo(0, 0);
                }
                // 最右边界值检查
                if (getScrollX() > tabWidth * (getChildCount() - visibleTabNum)) {
                    scrollTo(tabWidth * (getChildCount() - visibleTabNum), 0);
                }
                lastX = x;
                break;
            case MotionEvent.ACTION_UP:
                lastX = 0f;
                break;
        }
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean result = false;
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                lastX = ev.getX();
                break;
            case MotionEvent.ACTION_MOVE:
                float offsetX = ev.getX() - lastX;
                // 当移动大于touchSlop时，拦截该触摸事件
                if (Math.abs(offsetX) >= touchSlop) {
                    result = true;
                } else {
                    result = false;
                }
                break;
            case MotionEvent.ACTION_UP:
                lastX = 0f;
                break;
        }
        Log.i(TAG, "onInterceptTouchEvent result = " + result);
        return result;
    }

}
