package com.xunao.effectdemo.view;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;

import androidx.annotation.Nullable;


/**
 * Created
 * by jaren on 2017/5/26.
 */

public class FireworkView extends View{
    String TAG = "FireworkView";

    /**
     * 圆最大半径
     */
    private float mRadius;
    /**
     * View变化用时
     */
    private int mCycleTime;
    /**
     * Bézier曲线画圆的近似常数
     */
    private static final float c = 0.551915024494f;
    /**
     * 环绕圆点的颜色
     */
    private static final int[] dotColors = {0xffdaa9fa, 0xfff2bf4b, 0xffe3bca6, 0xff329aed,
            0xffb1eb99, 0xff67c9ad, 0xffde6bac};
    /**
     * 4.圆环减消失、周围环绕十四圆点
     */
    private static final int RING_DOT__HEART_VIEW = 3;
    /**
     * 5.环绕的十四圆点向外移动并缩小、透明度渐变、渐隐
     */
    private static final int DOT__HEART_VIEW = 4;

    private float mCenterX;
    private float mCenterY;
    private Paint mPaint;
    private ValueAnimator animatorTime;
    private int mCurrentRadius;
    private int mCurrentState;
    private float mCurrentPercent;

    private float rDotL;
    private float offL;
    private boolean isMax;
    private float dotR;


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

    public FireworkView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FireworkView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mRadius = dp2px(30);
        mCycleTime = 1800;
        mCenterX = mRadius;
        mCenterY = mRadius;
        mPaint = new Paint();
        mCurrentRadius = (int) mRadius;
        dotR = mRadius / 6;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(mCenterX, mCenterY);//使坐标原点在canvas中心位置
        switch (mCurrentState) {
            case RING_DOT__HEART_VIEW:
                drawDotWithRing(canvas, mCurrentRadius);
                break;
            case DOT__HEART_VIEW:
                drawDot(canvas);
                break;
        }
    }

    //绘制圆点
    private void drawDotWithRing(Canvas canvas, int radius) {
        mPaint.setAntiAlias(true);

        mCurrentPercent = (1f - mCurrentPercent > 1f ? 1f : 1f - mCurrentPercent) * 1f;

        float innerR = radius - mRadius * mCurrentPercent + dotR;
        double angleB = -Math.PI / 20;

        offL += dotR / 14;
        rDotL = innerR + offL;

        mPaint.setStyle(Paint.Style.FILL);
        for (int i = 0; i < 14; i++) {
            mPaint.setColor(dotColors[i % 7]);
            float cx = (float) (rDotL * Math.sin(angleB));
            float cy = (float) (rDotL * Math.cos(angleB));
            if(i % 3 == 0){
                canvas.drawCircle(cx, cy, dotR, mPaint);
            }else if(i % 3 == 1){
                mPaint.setTextSize(60);
                canvas.drawText("÷", cx, cy, mPaint);
            }else{
                canvas.drawRect(cx - 20, cy - 20, cx + 20, cy + 20, mPaint);
            }

            angleB += 2 * Math.PI / 14;
        }
        mCurrentRadius = (int) (mRadius / 3 + offL * 4);

    }

    //绘制圆点
    private void drawDot(Canvas canvas) {
        mPaint.setAntiAlias(true);

        double angleB = -Math.PI / 20;
        float dotRL;
        if (rDotL < 2.6 * mRadius) {  // 限制圆点的扩散范围
            rDotL += dotR / 14;
        }
        if (!isMax && mCurrentRadius <= 1.1 * mRadius) {
            offL += dotR / 14;
            mCurrentRadius = (int) (mRadius / 3 + offL * 4);

        } else {
            isMax = true;
        }

        dotRL = (dotR * (1 - mCurrentPercent) * 4) > dotR ? dotR :
                (dotR * (1 - mCurrentPercent) * 3);
        mPaint.setStyle(Paint.Style.FILL);
        for (int i = 0; i < 14; i++) {
            mPaint.setColor(dotColors[i % 7]);
            // 逐渐透明，setColor自带Alpha值，所以要放在setColor之后才会生效
            mPaint.setAlpha((int) (255 * (1 - mCurrentPercent)));
            float cx = (float) (rDotL * Math.sin(angleB));
            float cy = (float) (rDotL * Math.cos(angleB));
            if(i % 3 == 0){
                canvas.drawCircle(cx, cy, dotRL, mPaint);
            }else if(i % 3 == 1){
                mPaint.setTextSize(60);
                canvas.drawText("÷", cx, cy, mPaint);
            }else{
                canvas.drawRect(cx - 20, cy - 20, cx + 20, cy + 20, mPaint);
            }

            angleB += 2 * Math.PI / 14;
        }

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mCenterX = w / 2;
        mCenterY = h / 2;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int mWidth, mHeight;
        mWidth = (int) (5.2 * mRadius + 2 * dotR);
        mHeight = (int) (5.2 * mRadius + 2 * dotR);
        setMeasuredDimension(mWidth, mHeight);

    }

    /**
     * 烟花的变化效果
     */
    public void like() {
        if (animatorTime != null && animatorTime.isRunning()) {
            return;
        }
        resetState();
        animatorTime = ValueAnimator.ofInt(0, 1200);
        animatorTime.setDuration(mCycleTime);
        animatorTime.setInterpolator(new DecelerateInterpolator());  // 减速变化
        animatorTime.start();
        animatorTime.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int animatedValue = (int) animation.getAnimatedValue();

                if (animatedValue <= 480) {
                    float percent = calcPercent(1f, 480f, animatedValue);//内环半径增大直至消亡
                    mCurrentPercent = percent;
                    mCurrentRadius = (int) (2 * mRadius);//外环半径不再改变
                    mCurrentState = RING_DOT__HEART_VIEW;
                    invalidate();
                }
                  else if (animatedValue <= 1200) {
                    float percent = calcPercent(480f, 1200f, animatedValue);
                    mCurrentPercent = percent;
                    mCurrentState = DOT__HEART_VIEW;
                    invalidate();
                }
            }
        });

    }

    /**
     * 重置为初始状态
     */
    private void resetState() {
        mCurrentPercent = 0;
        mCurrentRadius = 0;
        isMax = false;
        rDotL = 0;
        offL = 0;
    }

    private float calcPercent(float start, float end, float current) {
        return (current - start) / (end - start);
    }

    // 转换为dp单位
    private float dp2px(int value) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value,
                getResources().getDisplayMetrics());
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (animatorTime != null) {
            animatorTime.removeAllListeners();
        }
    }
}
