package cn.modificator.waterwave_progress;

import java.lang.ref.WeakReference;
import java.text.DecimalFormat;
import java.util.Locale;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Path.Direction;
import android.graphics.Region.Op;
import android.os.Handler;
import android.os.Message;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ProgressBar;

/**
 * @author Administrator
 */
public class WaterWaveProgress extends View {
    // 水的画笔 // 画圆环的画笔// 进度百分比的画笔
    private Paint mPaintWater = null, mRingPaint = null, mTextPaint = null;

    // 圆环颜色 // 圆环背景颜色 // 当前进度 //水波颜色 // 水波背景色 //进度条和水波之间的距离 //进度百分比字体大小
    // //进度百分比字体颜色
    private int mRingColor, mRingBgColor, mWaterColor, mWaterBgColor,
            mFontSize, mTextColor;
    // 进度 //浪峰个数
    float crestCount = 1.5f;

    int mProgress = 10, mMaxProgress = 100;

    // 画布中心点
    private Point mCenterPoint;
    // 圆环宽度
    private float mRingWidth, mProgress2WaterWidth;
    // 是否显示进度条 //是否显示进度百分比
    private boolean mShowProgress = false, mShowNumerical = true;

    /**
     * 产生波浪效果的因子
     */
    private long mWaveFactor = 0L;
    /**
     * 正在执行波浪动画
     */
    private boolean isWaving = false;
    /**
     * 振幅
     */
    private float mAmplitude = 30.0F; // 20F
    /**
     * 波浪的速度
     */
    private float mWaveSpeed = 0.070F; // 0.020F
    /**
     * 水的透明度
     */
    private int mWaterAlpha = 255; // 255
    WaterWaveAttrInit attrInit;

    private MyHandler mHandler = null;

    private static class MyHandler extends Handler {
        private WeakReference<WaterWaveProgress> mWeakRef = null;

        private int refreshPeriod = 100;

        public MyHandler(WaterWaveProgress host) {
            mWeakRef = new WeakReference<WaterWaveProgress>(host);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mWeakRef.get() != null) {
                mWeakRef.get().invalidate();
                sendEmptyMessageDelayed(0, refreshPeriod);
            }
        }
    }

    public WaterWaveProgress(Context paramContext) {
        super(paramContext);
    }

    public WaterWaveProgress(Context context, AttributeSet attributeSet) {
        this(context, attributeSet, 0);
    }

    public WaterWaveProgress(Context context, AttributeSet attrs,
                             int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        attrInit = new WaterWaveAttrInit(context, attrs, defStyleAttr);
        init(context);
    }

    @SuppressLint("NewApi")
    private void init(Context context) {
        mCenterPoint = new Point();
        mRingColor = attrInit.getProgressColor();
        mRingBgColor = attrInit.getProgressBgColor();
        mWaterColor = attrInit.getWaterWaveColor();
        mWaterBgColor = attrInit.getWaterWaveBgColor();
        mRingWidth = attrInit.getProgressWidth();
        mProgress2WaterWidth = attrInit.getProgress2WaterWidth();
        mShowProgress = attrInit.isShowProgress();
        mShowNumerical = attrInit.isShowNumerical();
        mFontSize = attrInit.getFontSize();
        mTextColor = attrInit.getTextColor();
        mProgress = attrInit.getProgress();
        mMaxProgress = attrInit.getMaxProgress();

        // 如果手机版本在4.0以上,则开启硬件加速
        if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) {
            setLayerType(View.LAYER_TYPE_HARDWARE, null);
            // setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
        mRingPaint = new Paint();
        mRingPaint.setAntiAlias(true);
        mRingPaint.setColor(mRingColor); // 圆环颜色
        mRingPaint.setStyle(Paint.Style.STROKE);
        mRingPaint.setStrokeWidth(mRingWidth); // 圆环宽度

        mPaintWater = new Paint();
        mPaintWater.setStrokeWidth(1.0F);
        mPaintWater.setColor(mWaterColor);
        // mPaintWater.setColor(getResources().getColor(mWaterColor));
        mPaintWater.setAlpha(mWaterAlpha);

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(mTextColor);
        mTextPaint.setStyle(Paint.Style.FILL);
        mTextPaint.setTextSize(mFontSize);

        mHandler = new MyHandler(this);

    }

    public void animateWave() {
        if (!isWaving) {
            mWaveFactor = 0L;
            isWaving = true;
            mHandler.sendEmptyMessage(0);
        }
    }

    @SuppressLint({"DrawAllocation", "NewApi"})
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 获取整个View（容器）的宽、高
        int width = getWidth();
        int height = getHeight();
        width = height = (width < height) ? width : height;
        mAmplitude = width / 20f;

        mCenterPoint.x = width / 2;
        mCenterPoint.y = height / 2;
        { // 重新设置进度条的宽度和水波与进度条的距离,,至于为什么写在这,我脑袋抽了可以不
            mRingWidth = mRingWidth == 0 ? width / 20 : mRingWidth;
            mProgress2WaterWidth = mProgress2WaterWidth == 0 ? mRingWidth * 0.6f
                    : mProgress2WaterWidth;
            mRingPaint.setStrokeWidth(mRingWidth);
            mTextPaint.setTextSize(mFontSize == 0 ? width / 5 : mFontSize);
            if (VERSION.SDK_INT == VERSION_CODES.JELLY_BEAN) {
                setLayerType(View.LAYER_TYPE_SOFTWARE, null);
            } else {
                setLayerType(View.LAYER_TYPE_HARDWARE, null);
            }
        }

        RectF oval = new RectF();
        oval.left = mRingWidth / 2;
        oval.top = mRingWidth / 2;
        oval.right = width - mRingWidth / 2;
        oval.bottom = height - mRingWidth / 2;

        if (isInEditMode()) {
            mRingPaint.setColor(mRingBgColor);
            canvas.drawArc(oval, -90, 360, false, mRingPaint);
            mRingPaint.setColor(mRingColor);
            canvas.drawArc(oval, -90, 90, false, mRingPaint);
            canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mCenterPoint.x
                    - mRingWidth - mProgress2WaterWidth, mPaintWater);
            return;
        }

        // 如果没有执行波浪动画，或者也没有指定容器宽高，就画个简单的矩形
        if ((width == 0) || (height == 0) || isInEditMode()) {
            canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, width / 2
                    - mProgress2WaterWidth - mRingWidth, mPaintWater);
            return;
        }

        // 水与边框的距离
        float waterPadding = mShowProgress ? mRingWidth + mProgress2WaterWidth
                : 0;
        // 水最高处
        int waterHeightCount = mShowProgress ? (int) (height - waterPadding * 2)
                : height;

        // 重新生成波浪的形状
        mWaveFactor++;
        if (mWaveFactor >= Integer.MAX_VALUE) {
            mWaveFactor = 0L;
        }

        // 画进度条背景
        mRingPaint.setColor(mRingBgColor);
        // canvas.drawArc(oval, -90, 360, false, mRingPaint);
        // //和下面效果一样,只不过这个是画个360度的弧,下面是画圆环
        canvas.drawCircle(width / 2, width / 2, waterHeightCount / 2
                + waterPadding - mRingWidth / 2, mRingPaint);
        mRingPaint.setColor(mRingColor);
        // 100为 总进度
        canvas.drawArc(oval, -90, (mProgress * 1f) / mMaxProgress * 360f, false,
                mRingPaint);

        // 计算出水的高度
        float waterHeight = waterHeightCount * (1 - (mProgress * 1f) / mMaxProgress)
                + waterPadding;
        int staticHeight = (int) (waterHeight + mAmplitude);
        Path mPath = new Path();
        mPath.reset();
        if (mShowProgress) {
            mPath.addCircle(width / 2, width / 2, waterHeightCount / 2,
                    Direction.CCW);
        } else {
            mPath.addCircle(width / 2, width / 2, waterHeightCount / 2,
                    Direction.CCW);
        }
        // canvas添加限制,让接下来的绘制都在园内
        canvas.clipPath(mPath, Op.INTERSECT);
//		canvas.clipPath(mPath, Op.REPLACE);
        Paint bgPaint = new Paint();
        bgPaint.setColor(mWaterBgColor);
        // 绘制背景
        canvas.drawRect(waterPadding, waterPadding, waterHeightCount
                + waterPadding, waterHeightCount + waterPadding, bgPaint);
        // 绘制静止的水
        canvas.drawRect(waterPadding, staticHeight, waterHeightCount
                + waterPadding, waterHeightCount + waterPadding, mPaintWater);

        // 待绘制的波浪线的x坐标
        int xToBeDrawed = (int) waterPadding;
        int waveHeight = (int) (waterHeight - mAmplitude
                * Math.sin(Math.PI
                * (2.0F * (xToBeDrawed + (mWaveFactor * width)
                * mWaveSpeed)) / width));
        // 波浪线新的高度
        int newWaveHeight = waveHeight;
        while (true) {
            if (xToBeDrawed >= waterHeightCount + waterPadding) {
                break;
            }
            // 根据当前x值计算波浪线新的高度
            newWaveHeight = (int) (waterHeight - mAmplitude
                    * Math.sin(Math.PI
                    * (crestCount * (xToBeDrawed + (mWaveFactor * waterHeightCount)
                    * mWaveSpeed)) / waterHeightCount));

            // 先画出梯形的顶边
            canvas.drawLine(xToBeDrawed, waveHeight, xToBeDrawed + 1,
                    newWaveHeight, mPaintWater);

            // 画出动态变化的柱子部分
            canvas.drawLine(xToBeDrawed, newWaveHeight, xToBeDrawed + 1,
                    staticHeight, mPaintWater);
            xToBeDrawed++;
            waveHeight = newWaveHeight;
        }
        if (mShowNumerical) {
//            String progressTxt = String.format(Locale.CHINA, "%.0f.%%", (mProgress * 1f) / mMaxProgress * 100f);//%进度
            String progressTxt = text != null ? text : new DecimalFormat("0.0").format((mProgress * 10f) / mMaxProgress);//10分满分制
            float mTxtWidth = mTextPaint.measureText(progressTxt, 0, progressTxt.length());
            canvas.drawText(progressTxt, mCenterPoint.x - mTxtWidth / 2,
                    mCenterPoint.x * 1.5f - mFontSize / 2, mTextPaint);
        }
    }
    //要显示的文本
    private String text;

    public void setText(String text) {
        this.text = text;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = widthMeasureSpec;
        int height = heightMeasureSpec;
        width = height = (width < height) ? width : height;
        setMeasuredDimension(width, height);
    }

    /**
     * 设置波浪的振幅
     */
    public void setAmplitude(float amplitude) {
        mAmplitude = amplitude;
    }

    /**
     * 设置水的透明度
     *
     * @param alpha 透明的百分比，值为0到1之间的小数，越接近0越透明
     */
    public void setWaterAlpha(float alpha) {
        mWaterAlpha = (int) (255.0F * alpha);
        mPaintWater.setAlpha(mWaterAlpha);
    }

    /**
     * 设置水的颜色
     */
    public void setWaterColor(int color) {
        mWaterColor = color;
    }

    /**
     * 设置当前进度
     */
    public void setProgress(int progress) {
        progress = progress > 100 ? 100 : progress < 0 ? 0 : progress;
        mProgress = progress;
        invalidate();
    }

    /**
     * 获取进度 动画时会用到
     */
    public int getProgress() {
        return mProgress;
    }

    /**
     * 设置波浪速度
     */
    public void setWaveSpeed(float speed) {
        mWaveSpeed = speed;
    }

    /**
     * 是否显示进度条
     *
     * @param b
     */
    public void setShowProgress(boolean b) {
        mShowProgress = b;
    }

    /**
     * 是否显示进度值
     *
     * @param b
     */
    public void setShowNumerical(boolean b) {
        mShowNumerical = b;
    }

    /**
     * 设置进度条前景色
     *
     * @param mRingColor
     */
    public void setmRingColor(int mRingColor) {
        this.mRingColor = mRingColor;
    }

    /**
     * 设置进度条背景色
     *
     * @param mRingBgColor
     */
    public void setmRingBgColor(int mRingBgColor) {
        this.mRingBgColor = mRingBgColor;
    }

    /**
     * 设置水波颜色
     *
     * @param mWaterColor
     */
    public void setmWaterColor(int mWaterColor) {
        this.mWaterColor = mWaterColor;
    }

    /**
     * 设置水波背景色
     *
     * @param mWaterBgColor
     */
    public void setWaterBgColor(int mWaterBgColor) {
        this.mWaterBgColor = mWaterBgColor;
    }

    /**
     * 设置进度值显示字体大小
     *
     * @param mFontSize
     */
    public void setFontSize(int mFontSize) {
        this.mFontSize = mFontSize;
    }

    /**
     * 设置进度值显示字体颜色
     *
     * @param mTextColor
     */
    public void setTextColor(int mTextColor) {
        this.mTextColor = mTextColor;
    }

    /**
     * 设置进度条最大值
     *
     * @param mMaxProgress
     */
    public void setMaxProgress(int mMaxProgress) {
        this.mMaxProgress = mMaxProgress;
    }

    /**
     * 设置浪峰个数
     *
     * @param crestCount
     */
    public void setCrestCount(float crestCount) {
        this.crestCount = crestCount;
    }

    /**
     * 设置进度条宽度
     *
     * @param mRingWidth
     */
    public void setRingWidth(float mRingWidth) {
        this.mRingWidth = mRingWidth;
    }

    /**
     * 设置水波到进度条之间的距离
     *
     * @param mProgress2WaterWidth
     */
    public void setProgress2WaterWidth(float mProgress2WaterWidth) {
        this.mProgress2WaterWidth = mProgress2WaterWidth;
    }

}