package com.example.mycustomviewdemo.widget.roundprogressbar;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import com.example.mycustomviewdemo.R;


/**
 * 需求增加：在2的基础上实现拖动功能，重写onToutchEvent
 * 增加中间带文字显进度
 * <p>
 * <p>
 * Created by 兴兴 on 2016/7/8.
 */
public class MyRoundProgressBar3 extends View {
    private static final float DEFAULT_PROGRESS_WIDTH = 40f;//默认轨道宽度
    private static final float DEFAULT_TAG_RADIUS = 25f;//默认拖动小圆点的半径
    private static final int DEFAULT_TAG_COLOR = Color.CYAN;//默认拖动小圆点的颜色
    private static final int DEFAULT_BACK_COLOR = 0xFF080808;//默认轨道背景色
    private static final int DEFAULT_PROGRESS_COLOR = 0xFFFF4081;//默认进度条颜色

    private Paint mPaint;//画笔
    private int backColor;//圆环背景颜色
    private int progressColor;//圆环进度条的颜色
    private float center;//该控件中心点
    private float progressWidth;//进度条的宽度
    private float radius;//圆环半径
    private float tagRadius;//拖动小圆点的半径
    private float textSize;//中间进度文本的大小

    private int maxProgress = 100;//总进度值，默认值100
    private int progress;

    private float mX;//小圆点x坐标
    private float mY;//小圆点y坐标
    private double mAngle;
    private int mScaledTouchSlop;
    private boolean canMove;

    private float oldX;
    private float oldY;


    public MyRoundProgressBar3(Context context) {
        super(context);
    }

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

    public MyRoundProgressBar3(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        //设置画笔
        mPaint = new Paint();

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyRoundProgressBar);
        backColor = typedArray.getColor(R.styleable.MyRoundProgressBar_backColor, DEFAULT_BACK_COLOR);
        progressColor = typedArray.getColor(R.styleable.MyRoundProgressBar_progressColor, DEFAULT_PROGRESS_COLOR);
        progressWidth = typedArray.getDimension(R.styleable.MyRoundProgressBar_progressWidth, DEFAULT_PROGRESS_WIDTH);
        progress = typedArray.getInt(R.styleable.MyRoundProgressBar_progress, 0);
        tagRadius = typedArray.getDimension(R.styleable.MyRoundProgressBar_tagRadius, DEFAULT_TAG_RADIUS);
        typedArray.recycle();

        mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //设置描边
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(progressWidth);

        //先绘制大圆
        mPaint.setColor(backColor);
        mPaint.setDither(true);//设置抖动
        mPaint.setAntiAlias(true);//消除锯齿
        canvas.drawCircle(center, center, radius, mPaint);

        //绘制进度条
        mPaint.setColor(progressColor);
        RectF rectF = new RectF(tagRadius, tagRadius, 2 * radius + tagRadius, 2 * radius + tagRadius);
        canvas.drawArc(rectF, 270, 360 * progress / maxProgress, false, mPaint);

        //绘制文字（正中间）
        mPaint.setTextSize(textSize);
        mPaint.setTextAlign(Paint.Align.CENTER);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setStrokeWidth(2);
        Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt();
        int baseLineY = getMeasuredHeight()/2 + (fontMetrics.descent- fontMetrics.ascent)/2 - fontMetrics.descent;
        canvas.drawText(progress + "%",center,baseLineY,mPaint);

        //绘制可拖动小圆点
        mPaint.setColor(DEFAULT_TAG_COLOR);
        if (progress > maxProgress) {
            progress = maxProgress;
        }
        mAngle = 2 * Math.PI * progress / maxProgress;//转过的弧度
        mX = getTagX(mAngle);
        mY = getTagY(mAngle);
        canvas.drawCircle(mX, mY, tagRadius, mPaint);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        center = w / 2;
        radius = center - tagRadius;

        textSize = 2*radius/3;

    }

    /**
     * 增加同步锁，增加安全性,可以在非主线程中使用postInvalidate()进行刷新视图
     *
     * @param progress
     */
    public synchronized void setProgress(int progress) {
        this.progress = progress;
        postInvalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                oldX = event.getX();
                oldY = event.getY();
                canMove = isTouchArc(oldX, oldY);
                if (canMove) {
                    refreshLocation(oldX, oldY);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float x = event.getX();
                float y = event.getRawY();
                if (isTouchArc(x, y)) {
                    mX = x;
                    mAngle = getAngleWithX(x);
                    mY = getTagY(mAngle);
                    //更新progress
                    progress = (int) (mAngle * maxProgress / (2 * Math.PI));
                    refreshLocation(x,y);
                    return true;
                }
                break;

            case MotionEvent.ACTION_UP:

                break;
        }
        return super.onTouchEvent(event);
    }

    /**
     * 检查是否按在圆上
     *
     * @param x
     * @param y
     * @return
     */
    private boolean isTouchArc(float x, float y) {
        double fromArcCenter = distanceFromArcCenter(mX,mY, x, y);
        if (fromArcCenter <= tagRadius) {
            return true;
        }
        return false;
    }

    /**
     * 刷新小圆点的位置
     *
     * @param x
     * @param y
     */
    private void refreshLocation(float x, float y) {
        mX = x;
        mY = y;
        postInvalidate();
    }

    /**
     * 当前坐标点距离圆心的坐标
     *
     * @param cx 圆心x坐标
     * @param cy 圆心y坐标
     * @param x  当前x坐标
     * @param y  当前y坐标
     * @return
     */
    private double distanceFromArcCenter(float cx, float cy, float x, float y) {
        return Math.hypot(x - cx, y - cy);
    }

    /**
     * 使用x坐标获得弧度
     * @param x
     * @return
     */
    private float getAngleWithX(float x) {
        return (float) Math.asin((x - center) / radius);
    }

    /**
     * 使用y坐标获得弧度
     * @param y
     * @return
     */
    private float getAngleWithY(float y) {
        return (float) Math.acos((radius + tagRadius - y) / radius);
    }

    /**
     * 根据转过的弧度获取Y坐标
     * @param angle
     * @return
     */
    private float getTagY(double angle) {
        return (float) (tagRadius + radius * (1 - Math.cos(angle)));
    }

    /**
     * 根据转过的弧度获取X坐标
     * @param angle
     * @return
     */
    private float getTagX(double angle) {
        return (float) (center + radius * Math.sin(angle));
    }



}
