package moe.codeest.enviews;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.AnticipateInterpolator;

import com.shuyu.gsyvideoplayer.R;

/**
 * Created by codeest on 16/11/7.
 *
 */

public class ENPlayView extends View {

    public static int STATE_PLAY = 0;

    public static int STATE_PAUSE = 1;

    public static int DEFAULT_LINE_COLOR = Color.WHITE;

    public static int DEFAULT_BG_LINE_COLOR = 0xfffafafa;

    public static int DEFAULT_LINE_WIDTH = 4;

    public static int DEFAULT_BG_LINE_WIDTH = 4;

    public static int DEFAULT_DURATION = 1200;

    private int mCurrentState = STATE_PAUSE;

    private Paint mPaint, mBgPaint;

    private int mWidth, mHeight;

    private int mCenterX, mCenterY;

    private int mCircleRadius;

    private RectF mRectF, mBgRectF;

    private float mFraction = 1;

    private Path mPath, mDstPath;

    private PathMeasure mPathMeasure;

    private float mPathLength;

    private int mDuration;

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

    public ENPlayView(Context context, AttributeSet attrs) {
        super(context, attrs);

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.play);
        int lineColor = ta.getColor(R.styleable.play_play_line_color, DEFAULT_LINE_COLOR);
        int bgLineColor = ta.getColor(R.styleable.play_play_bg_line_color, DEFAULT_BG_LINE_COLOR);
        int lineWidth = ta.getInteger(R.styleable.play_play_line_width, dp2px(DEFAULT_LINE_WIDTH));
        int bgLineWidth = ta.getInteger(R.styleable.play_play_bg_line_width, dp2px(DEFAULT_BG_LINE_WIDTH));
        ta.recycle();

        setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setColor(lineColor);
        mPaint.setStrokeWidth(lineWidth);
        mPaint.setPathEffect(new CornerPathEffect(1));

        mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBgPaint.setStyle(Paint.Style.STROKE);
        mBgPaint.setStrokeCap(Paint.Cap.ROUND);
        mBgPaint.setColor(bgLineColor);
        mBgPaint.setStrokeWidth(bgLineWidth);

        mPath = new Path();
        mDstPath = new Path();
        mPathMeasure = new PathMeasure();

        mDuration = DEFAULT_DURATION;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w * 9 / 10;
        mHeight = h * 9 / 10;
        mCircleRadius = mWidth / dp2px(4);
        mCenterX = w / 2;
        mCenterY = h / 2;
        mRectF = new RectF(mCenterX - mCircleRadius, mCenterY + 0.6f * mCircleRadius,
                mCenterX + mCircleRadius, mCenterY + 2.6f * mCircleRadius);
        mBgRectF = new RectF(mCenterX - mWidth / 2 ,mCenterY - mHeight / 2 ,mCenterX + mWidth / 2, mCenterY + mHeight / 2);
        mPath.moveTo(mCenterX - mCircleRadius, mCenterY + 1.8f * mCircleRadius);
        mPath.lineTo(mCenterX - mCircleRadius, mCenterY - 1.8f * mCircleRadius);
        mPath.lineTo(mCenterX + mCircleRadius, mCenterY);
        mPath.close();
        mPathMeasure.setPath(mPath, false);
        mPathLength = mPathMeasure.getLength();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(mCenterX, mCenterY, mWidth / 2, mBgPaint);
        if (mFraction < 0) {    //嗷~~ 弹性部分
            canvas.drawLine(mCenterX + mCircleRadius, mCenterY - 1.6f * mCircleRadius + 10 * mCircleRadius * mFraction,
                    mCenterX + mCircleRadius, mCenterY + 1.6f * mCircleRadius + 10 * mCircleRadius * mFraction, mPaint);

            canvas.drawLine(mCenterX - mCircleRadius, mCenterY - 1.6f * mCircleRadius,
                    mCenterX - mCircleRadius, mCenterY + 1.6f * mCircleRadius, mPaint);

            canvas.drawArc(mBgRectF, -105 , 360 , false, mPaint);
        } else if (mFraction <= 0.3) {  //嗷~~ 右侧直线和下方曲线
            canvas.drawLine(mCenterX + mCircleRadius, mCenterY - 1.6f * mCircleRadius + mCircleRadius * 3.2f / 0.3f * mFraction,
                    mCenterX + mCircleRadius, mCenterY + 1.6f * mCircleRadius, mPaint);

            canvas.drawLine(mCenterX - mCircleRadius, mCenterY - 1.6f * mCircleRadius,
                    mCenterX - mCircleRadius, mCenterY + 1.6f * mCircleRadius, mPaint);

            if (mFraction != 0)
                canvas.drawArc(mRectF, 0f, 180f / 0.3f * mFraction, false, mPaint);

            canvas.drawArc(mBgRectF, -105 + 360 * mFraction, 360 * (1 - mFraction), false, mPaint);
        } else if (mFraction <= 0.6) {  //嗷~~ 下方曲线和三角形
            canvas.drawArc(mRectF, 180f / 0.3f * (mFraction - 0.3f), 180 - 180f / 0.3f * (mFraction - 0.3f), false , mPaint);

            mDstPath.reset();
            //mDstPath.lineTo(0 ,0);
            mPathMeasure.getSegment(0.02f * mPathLength, 0.38f * mPathLength + 0.42f * mPathLength / 0.3f * (mFraction - 0.3f) ,
                    mDstPath, true);
            canvas.drawPath(mDstPath, mPaint);

            canvas.drawArc(mBgRectF, -105 + 360 * mFraction, 360 * (1 - mFraction), false, mPaint);
        } else if (mFraction <= 0.8) {  //嗷~~ 三角形
            mDstPath.reset();
            //mDstPath.lineTo(0 ,0);
            mPathMeasure.getSegment(0.02f * mPathLength + 0.2f * mPathLength / 0.2f * (mFraction - 0.6f)
                    , 0.8f * mPathLength + 0.2f * mPathLength / 0.2f * (mFraction - 0.6f) ,
                    mDstPath, true);
            canvas.drawPath(mDstPath, mPaint);

            canvas.drawArc(mBgRectF, -105 + 360 * mFraction, 360 * (1 - mFraction), false, mPaint);
        } else {    //嗷~~ 弹性部分
            mDstPath.reset();
            //mDstPath.lineTo(0 ,0);
            mPathMeasure.getSegment(10 * mCircleRadius * (mFraction - 1)
                    , mPathLength ,
                    mDstPath, true);
            canvas.drawPath(mDstPath, mPaint);
        }
    }

    public void play() {
        if (mCurrentState == STATE_PLAY) {
            return;
        }
        mCurrentState = STATE_PLAY;
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(1.f, 100.f);
        valueAnimator.setDuration(mDuration);
        valueAnimator.setInterpolator(new AnticipateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mFraction = 1 - valueAnimator.getAnimatedFraction();
                invalidate();
            }
        });
        if (!valueAnimator.isRunning()) {
            valueAnimator.start();
        }
    }

    public void pause() {
        if (mCurrentState == STATE_PAUSE) {
            return;
        }
        mCurrentState = STATE_PAUSE;
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(1.f, 100.f);
        valueAnimator.setDuration(mDuration);
        valueAnimator.setInterpolator(new AnticipateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mFraction = valueAnimator.getAnimatedFraction();
                invalidate();
            }
        });
        if (!valueAnimator.isRunning()) {
            valueAnimator.start();
        }
    }

    public int getCurrentState() {
        return mCurrentState;
    }

    public void setDuration(int duration) {
        mDuration = duration;
    }

    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
                getContext().getResources().getDisplayMetrics());
    }
}
