package com.daya.live_teaching.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;

public class MCircleSeekBar extends View {
    /**
     * The context
     */
    private Context              mContext;
    /**
     * seekbar变化监听
     */
    private OnSeekChangeListener mListener;
    /**
     * 画圆环的paint
     */
    private Paint                circlePaint;

    /**
     * 移动之后的角度
     */
    private int                  lastAngle = 0;


    /**
     * seekbar可选择的最大值
     */
    private int maxProgress = 150;

    /**
     * 当前的百分值
     */
    private int progress    = 90;
    /**
     * 百分值
     */
    private int progressPercent;

    /**
     * 外圆半径
     */
    private float radius;


    /**
     * progressMark X坐标
     */
    private float dx;
    /**
     * progressMark Y坐标
     */
    private float dy;

    /**
     * 标记的seekbar当前位置的X坐标，预设置值为12点位置
     */
    private float markPointX;
    /**
     * T标记的seekbar当前位置的Y坐标，预设置值为12点位置
     */
    private float markPointY;

    /**
     * 进度条点
     */
    private Paint progressMark;

    /**
     * 是否手指按下的标志位
     */
    private boolean IS_PRESSED = false;



    /**
     * 圆环的宽度
     */
    private int    circleWidth;
    private float  center;
    private int    widthPixels;
    private int    heightPixels;

    /**
     * 画文字的画笔
     */
    private Paint textPaint;

    private String rhythns[] = {"4  |  2", "4  |  3", "4  |  4", "8  |  6"};

    {

        /*
         * Paint.ANTI_ALIAS_FLAG为抗锯齿
         */
        circlePaint = new Paint();
        progressMark = new Paint();
        progressMark.setColor(Color.parseColor("#2DC4BE"));
        progressMark.setAntiAlias(true);
        progressMark.setStyle(Paint.Style.FILL);

        textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setDither(true);
        textPaint.setFakeBoldText(true);//设置是否为粗体
    }

    /**
     * MCircleSeekBar的构造方法.
     * @param context
     * @param attrs
     * @param defStyle
     */
    public MCircleSeekBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
        circleWidth = dp2px(mContext, 10);
        radius = dp2px(mContext, 70);
    }

    /**
     * MCircleSeekBar的构造方法.
     * @param context
     * @param attrs
     */
    public MCircleSeekBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        circleWidth = dp2px(mContext, 10);
        radius = dp2px(mContext, 70);
    }

    /**
     * MCircleSeekBar的构造方法.
     * @param context
     */
    public MCircleSeekBar(Context context) {
        super(context);
        mContext = context;
        circleWidth = dp2px(mContext, 10);
        radius = dp2px(mContext, 70);
    }

    /*
     * 重写view的计算方法
     *
     * @see android.view.View#onMeasure(int, int)
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 分别获取期望的宽度和高度，并取其中较小的尺寸作为该控件的宽和高,并且不超过屏幕宽高
        //获取屏幕宽
        widthPixels = this.getResources().getDisplayMetrics().widthPixels;
        //获取屏幕高
        heightPixels = this.getResources().getDisplayMetrics().heightPixels;
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int hedight = MeasureSpec.getSize(heightMeasureSpec);
        int minWidth = Math.min(widthPixels, width);
        int minHedight = Math.min(heightPixels, hedight);
        setMeasuredDimension(Math.min(minWidth, minHedight), Math.min(minWidth, minHedight));
        center = width / 2;

        markPointX = getXByProgress(progress);
        markPointY = getYByProgress(progress);

    }

    /**
     *
     */
    @Override
    protected void onDraw(Canvas canvas) {
        drawCircle(canvas, center, radius);
        drawText(canvas, center);
        /*
         * 获取seek点X坐标
         */
        dx = getXFromAngle();
        /*
         * 获取seek点Y坐标
         */
        dy = getYFromAngle();
        /*
         * 绘制seek点的位置
         */
        drawMarkerAtProgress(canvas);

        super.onDraw(canvas);
    }


    /**
     * 绘制文字
     * @param canvas
     *         画布对象
     * @param center
     *         圆心的x和y坐标
     */
    private void drawText(Canvas canvas, float center) {

        textPaint.setTextSize(dp2px(mContext, 30)); // 设置要绘制的文字大小
        textPaint.setTextAlign(Paint.Align.CENTER); // 设置文字居中，文字的x坐标要注意
        textPaint.setColor(Color.WHITE); // 设置文字颜色

        textPaint.setStrokeWidth(0); // 注意此处一定要重新设置宽度为0,否则绘制的文字会重叠
        // 获得绘制文字的边界矩形
        Rect bounds = new Rect(); // 文字边框
        textPaint.getTextBounds("200", 0, "200".length(), bounds); // 获得绘制文字的边界矩形
        Paint.FontMetricsInt fontMetrics = textPaint.getFontMetricsInt(); // 获取绘制Text时的四条线
        float bgCenter = center - dp2px(mContext, 3);
        float baseline = center + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom; // 计算文字的基线,方法见http://blog.csdn.net/harvic880925/article/details/50423762
        canvas.drawText(String.valueOf(progress), bgCenter, baseline - dp2px(mContext, 20), textPaint); // 绘制表示进度的文字
    }

    /**
     * 绘制进度圆弧
     * @param canvas
     *         画布对象
     * @param center
     *         圆心的x和y坐标
     * @param radius
     *         圆的半径
     */

    private void drawCircle(Canvas canvas, float center, float radius) {

        circlePaint.setStyle(Paint.Style.FILL); // 设置绘制的圆为空心
        circlePaint.setColor(Color.parseColor("#1F1F27"));// Set default background color to Gray
        circlePaint.setStrokeWidth(1);//画笔宽度
        float bgCenter = center - dp2px(mContext, 3);
        canvas.drawCircle(bgCenter, bgCenter, (float) (radius + circleWidth / 1.3), circlePaint); // 画底部的空心圆

        circlePaint.setStyle(Paint.Style.FILL); // 设置绘制的圆为空心
        circlePaint.setColor(Color.parseColor("#525061"));
        circlePaint.setStrokeWidth(1);//画笔宽度
        canvas.drawCircle(bgCenter, bgCenter, radius - (circleWidth / 10), circlePaint); //

        circlePaint.setStyle(Paint.Style.FILL); // 设置绘制的圆为空心
        circlePaint.setColor(Color.parseColor("#35343E"));
        canvas.drawCircle(bgCenter, bgCenter, radius - circleWidth, circlePaint); //

    }

    /**
     * 画progressMark(seek)在圆环上的位置.
     * @param canvas
     */
    public void drawMarkerAtProgress(Canvas canvas) {
        canvas.drawCircle(dx, dy, (float) (circleWidth / 1.5), progressMark);
    }

    /**
     * 获取seek点X坐标
     * @return
     */
    public float getXFromAngle() {
        int adjust = circleWidth / 2;
        float x = markPointX - (adjust / 2);
        return x;
    }

    /**
     * 获取seek点Y坐标
     * @return
     */
    public float getYFromAngle() {
        int adjust = circleWidth / 2;
        float y = markPointY - (adjust / 2);
        return y;
    }


    /**
     * 设置圆弧的角度
     * @param lastAngle
     */
    public void setAngle(int lastAngle) {
        this.lastAngle = lastAngle;
        float donePercent = (((float) this.lastAngle) / 360) * maxProgress;
        float progress = donePercent / maxProgress * getMaxProgress() + 50;
        setProgressPercent(Math.round(donePercent));
        setProgress(Math.round(progress));
    }

    /**
     * 设置seekbar变化的监听
     * @param listener
     */
    public void setSeekBarChangeListener(OnSeekChangeListener listener) {
        mListener = listener;
    }

    /**
     * 获取seekbar变化的监听
     * @return the seek bar change listener
     */
    public OnSeekChangeListener getSeekBarChangeListener() {
        return mListener;
    }


    /**
     * 定义seekbar变化监听接口
     */
    public interface OnSeekChangeListener {
        /**
         * On progress change.
         * @param view
         * @param newProgress
         */
        public void onProgressChange(MCircleSeekBar view, int newProgress);

        public void onRhythm(MCircleSeekBar view, String rhythm);
    }

    /**
     * Gets the max progress.
     * @return the max progress
     */
    public int getMaxProgress() {
        return maxProgress;
    }

    /**
     * @param maxProgress
     */
    public void setMaxProgress(int maxProgress) {
        this.maxProgress = maxProgress;
    }

    /**
     * @return the progress
     */
    public int getProgress() {
        return progress;
    }

    /**
     * @param progress
     */
    public void setProgress(int progress) {
        this.progress = progress;
        if (!IS_PRESSED) {
            markPointX = getXByProgress(progress);
            markPointY = getYByProgress(progress);
            float degrees = (float) ((float) ((Math.toDegrees(Math.atan2(
                    markPointX - center, center - markPointY)) + 360.0)) % 360.0);
            lastAngle = Math.round(degrees);
            invalidate();
        }
        mListener.onProgressChange(this, progress);
    }


    /**
     * @return
     */
    public int getProgressPercent() {
        return progressPercent;
    }

    /**
     * @param progressPercent
     */
    public void setProgressPercent(int progressPercent) {
        this.progressPercent = progressPercent;
    }


    int i = 0;

    /**
     * 重写onTouch方法
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        boolean up;
        if (Math.abs(markPointX - x) > circleWidth / 1.5 && Math.abs(markPointY - y) > circleWidth / 1.5) {
            up = true;
        } else {
            up = false;
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                moved(x, y, up);
                break;
            case MotionEvent.ACTION_MOVE:
                moved(x, y, up);
                break;
            case MotionEvent.ACTION_UP:
                up = true;
                moved(x, y, up);
                break;
        }
        return true;
    }

    /**
     * seek点移动方法
     * @param x
     *         the x
     * @param y
     *         the y
     * @param up
     *         the up
     */
    private void moved(float x, float y, boolean up) {
        float distance = (float) Math.sqrt(Math.pow((x - center), 2)
                + Math.pow((y - center), 2));
        if (distance > radius - circleWidth * 3 && distance < radius + circleWidth * 3 && !up) {
            IS_PRESSED = true;
            float degrees = (float) ((float) ((Math.toDegrees(Math.atan2(
                    x - center, center - y)) + 360.0)) % 360.0);
            if (degrees < 0) {
                degrees += 2 * Math.PI;
            }
            int angle = Math.round(degrees);
            if (Math.abs(lastAngle - angle) < 100) {
                lastAngle = angle;
                /*
                 * 根据三角函数整切定理计算得到X.Y的坐标
                 */
                markPointX = (float) (center + radius
                        * Math.cos(Math.atan2(x - center, center - y) - (Math.PI / 2)));
                markPointY = (float) (center + radius
                        * Math.sin(Math.atan2(x - center, center - y) - (Math.PI / 2)));

                setAngle(lastAngle);
                invalidate();
            }
        } else {
            IS_PRESSED = false;
            invalidate();
        }
    }

    public float getXByProgress(int progress) {
        float x = 0;
        float lastAngle = (float) (2 * (progress - 50) * Math.PI / 150);
        x = (float) (center + radius * Math.cos(lastAngle - Math.PI / 2));
        return x;
    }

    public float getYByProgress(int progress) {
        float y = 0;
        float lastAngle = (float) (2 * (progress - 50) * Math.PI / 150);
        y = (float) (center + radius * Math.sin(lastAngle - Math.PI / 2));
        return y;
    }


    /**
     * dp转px
     */
    public static int dp2px(Context context, float dpVal) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpVal, context.getResources().getDisplayMetrics());
    }

}
