package com.ydl.ydlcommon.view;

import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.OvershootInterpolator;

import com.ydl.ydlcommon.R;


/**
 * Created by harvie on 2017/6/10 0010.
 */

public class MyToggleButton extends View{
    private float radius;
    // 开启颜色

    private int onColor;
    // 关闭颜色

    private int offColor;
    // 灰色带颜色

    private int offBorderColor;
    // 手柄颜色

    private int spotColor;
    // 边框颜色

    private int borderColor;
    // 画笔

    private Paint paint ;
    // 开关状态

    private boolean toggleOn = false;
    // 边框大小 默认为2px

    private int borderWidth = 1;
    // 垂直中心

    private float centerY;
    // 按钮的开始和结束位置

    private float startX, endX;
    // 手柄X位置的最小和最大值

    private float spotMinX, spotMaxX;
    // 手柄大小

    private int spotSize ;
    ///  手柄X位置

    private float spotX;
    // 关闭时内部灰色带高度

    private float offLineWidth;

    private RectF rect = new RectF();

    //开关切换监听器

    private OnToggleChanged listener;

    //属性动画

    private ValueAnimator animation;

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

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

    public MyToggleButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }


    public void init() {
        initPaint();
        initColor();
        initAnimation();
        this.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                toggle();
            }
        });
    }

    private void initPaint() {
        //初始化画笔(抗抖动)

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //绘制风格为填充

        paint.setStyle(Style.FILL);
        //笔触风格为圆角

        paint.setStrokeCap(Cap.ROUND);
    }

    private void initColor() {
        onColor = getResources().getColor(R.color.platform_google_green);
        offColor = getResources().getColor(R.color.platform_gray7);
        offBorderColor = getResources().getColor(R.color.platform_gray7);
        spotColor = getResources().getColor(R.color.platform_white);
        //因为开始为关闭状态,所以这里边框背景色初始化为关闭状态颜色

        borderColor = offColor;
    }

    @SuppressLint("NewApi")
    private void initAnimation() {
        animation = new ValueAnimator();
        animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                calculateToggleEffect(Double.parseDouble(animation.getAnimatedValue().toString()));
            }
        });
        //OvershootInterpolator : 结束时会超过给定数值,但是最后一定返回给定值

        animation.setInterpolator(new OvershootInterpolator(1.5f));
        animation.setDuration(500);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        Resources r = Resources.getSystem();
        if(widthMode == MeasureSpec.UNSPECIFIED || widthMode == MeasureSpec.AT_MOST){
            widthSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 55, r.getDisplayMetrics());
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
        }

        if(heightMode == MeasureSpec.UNSPECIFIED || heightMode == MeasureSpec.AT_MOST){
            heightSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, r.getDisplayMetrics());
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }


    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

        final int width = getWidth();
        final int height = getHeight();
        //由宽高计算圆角的半径

        radius = Math.min(width, height) * 0.5f;
        centerY = radius;
        startX = radius;
        endX = width - radius;
        spotMinX = startX + borderWidth;
        spotMaxX = endX - borderWidth;
        spotSize = height - 4 * borderWidth;
        spotX = toggleOn ? spotMaxX : spotMinX;
        offLineWidth = 0;
    }

    private int clamp(int value, int low, int high) {
        return Math.min(Math.max(value, low), high);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //1.绘制最外层边框背景-圆角矩形

        //绘制圆角矩形背景大小为测量的宽高

        rect.set(0, 0, getWidth(), getHeight());
        paint.setColor(borderColor);
        canvas.drawRoundRect(rect, radius, radius, paint);

        if(offLineWidth > 0){
            //1.1绘制整个开关区域中除手柄外的白色区域带

            final float cy = offLineWidth * 0.5f;
            rect.set(spotX - cy, centerY - cy, endX + cy, centerY + cy);
            paint.setColor(offBorderColor);
            canvas.drawRoundRect(rect, cy, cy, paint);
        }

        //2.绘制圆形手柄边框区域

        rect.set(spotX - 1 - radius, centerY - radius, spotX + 1.1f + radius, centerY + radius);
        paint.setColor(borderColor);
        canvas.drawRoundRect(rect, radius, radius, paint);

        //3.绘制圆形手柄区域

        //圆形手柄的半径大小(不包含边框)

        final float spotR = spotSize * 0.5f;
        rect.set(spotX - spotR, centerY - spotR, spotX + spotR, centerY + spotR);
        paint.setColor(spotColor);
        canvas.drawRoundRect(rect, spotR, spotR, paint);
    }

    private double mapValueFromRangeToRange(double value, double fromLow,
                                            double fromHigh, double toLow, double toHigh) {
        double fromRangeSize = fromHigh - fromLow;
        double toRangeSize = toHigh - toLow;
        double valueScale = (value - fromLow) / fromRangeSize;
        return toLow + (valueScale * toRangeSize);
    }

    /**

     * @param value

     */
    private void calculateToggleEffect(final double value) {
        final float mapToggleX = (float) mapValueFromRangeToRange(value, 0, 1, spotMinX, spotMaxX);
        spotX = mapToggleX;

        float mapOffLineWidth = (float) mapValueFromRangeToRange(1 - value, 0, 1, 10, spotSize);

        offLineWidth = mapOffLineWidth;

        //开启时候的背景色

        final int fr = Color.red(onColor);
        final int fg = Color.green(onColor);
        final int fb = Color.blue(onColor);

        //关闭后的背景色

        final int tr = Color.red(offColor);
        final int tg = Color.green(offColor);
        final int tb = Color.blue(offColor);

        //border颜色渐变

        int sr = (int) mapValueFromRangeToRange(1 - value, 0, 1, fr, tr);
        int sg = (int) mapValueFromRangeToRange(1 - value, 0, 1, fg, tg);
        int sb = (int) mapValueFromRangeToRange(1 - value, 0, 1, fb, tb);

        sr = clamp(sr, 0, 255);
        sg = clamp(sg, 0, 255);
        sb = clamp(sb, 0, 255);

        borderColor = Color.rgb(sr, sg, sb);
        //重绘

        if (Looper.myLooper() == Looper.getMainLooper()) {
            invalidate();
        } else {
            postInvalidate();
        }
    }

    @SuppressLint("NewApi")
    private void takeToggleAction(boolean isOn){
        if(isOn) {
            animation.setFloatValues(0.f, 1.f);
        } else {
            animation.setFloatValues(1.f, 0.f);
        }
        animation.start();
    }

    /**

     * 切换开关

     */
    public void toggle() {
        toggleOn = !toggleOn;
        takeToggleAction(toggleOn);
        if(listener != null){//触发toggle事件

            listener.onToggle(toggleOn);
        }
    }

    /**

     * 切换为打开状态

     */
    public void toggleOn() {
        toggleOn = true;
        takeToggleAction(toggleOn);
        if(listener != null){//触发toggle事件

            listener.onToggle(toggleOn);
        }
    }

    /**

     * 切换为关闭状态

     */
    public void toggleOff() {
        toggleOn = false;
        takeToggleAction(toggleOn);
        if(listener != null){//触发toggle事件

            listener.onToggle(toggleOn);
        }
    }

    /**

     * 设置显示成打开样式,不会触发toggle事件

     */
    public void setToggleOn(){
        toggleOn = true;
        calculateToggleEffect(1.0f);
    }

    /**

     * 设置显示成关闭样式,不会触发toggle事件

     */
    public void setToggleOff() {
        toggleOn = false;
        calculateToggleEffect(0.0f);
    }

    /**

     * 状态切换监听器

     */
    public interface OnToggleChanged{
         void onToggle(boolean on);
    }

    public void setOnToggleChanged(OnToggleChanged onToggleChanged) {
        listener = onToggleChanged;
    }

}