package com.gensee.rtdemo.view;


import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.gensee.demo.R;
import com.gensee.utils.GenseeLog;

import java.util.Timer;
import java.util.TimerTask;

/**
 * 简单的条形颜色选择器，可以使用xml设置宽和高
 * 圆形滑块
 * 其中的高为滑块的高，颜色条的高为滑块高的1/2
 */
public class ColorBar extends View {
    private static final String TAG = "ColorBar";
    private int CORNER_RADIUS = 16;
    /**
     * Colors to construct the color wheel using {@link android.graphics.SweepGradient}.
     * 用于构造色条的颜色数组，利用android的LinearGradient类
     */
    private int[] COLORS = new int[8];
    //, 0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFFFFFF, 0xFF000000

    /**
     * 长条宽度
     */
    private int barHeight = 30;
    /**
     * 长条的高度
     */
    private int barWidth;//长度

    /**
     * 滑块的半径
     */
    private int thumbWidthRadius = 0;
    private int thumbHeigthRadius = 0;

    /**
     * 滑块当前的位置
     */
    private int currentThumbOffset = thumbWidthRadius;
    private int thumbPopRadius = 0;

    /**
     * 长条开始位置
     */
    private int barStartX, barStartY;

    private static int STATUS;
    private static final int STATUS_INIT = 0;
    /**
     * 移动了action bar
     */
    private static final int STATUS_SEEK = 1;
    /**
     * 释放了action bar
     */
    private static final int STATUS_UP = 2;

    Paint thumbPaint = new Paint();

    private int currentColor;

    private Timer timer = null;
    private int mOrientation = Configuration.ORIENTATION_PORTRAIT;

    public interface ColorChangeListener {
        void colorChange(int color, int position, boolean bShowPopView);
    }

    ColorChangeListener colorChangeListener;

    public ColorBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        CORNER_RADIUS = getContext().getResources().getDimensionPixelSize(R.dimen.doc_color_bar_radius);
        COLORS[0] = getContext().getResources().getColor(R.color.pen_black);
        COLORS[1] = getContext().getResources().getColor(R.color.pen_red);
        COLORS[2] = getContext().getResources().getColor(R.color.pen_green);
        COLORS[3] = getContext().getResources().getColor(R.color.pen_rose_red);
        COLORS[4] = getContext().getResources().getColor(R.color.pen_blue);
        COLORS[5] = getContext().getResources().getColor(R.color.pen_yellow);
        COLORS[6] = getContext().getResources().getColor(R.color.pen_orange);
        COLORS[7] = getContext().getResources().getColor(R.color.pen_coffee);
        resetValue();
        invalidate();
    }

    public void resetValue()
    {
        currentColor = COLORS[0];
        STATUS = STATUS_INIT;
        thumbPopRadius = getContext().getResources().getDimensionPixelSize(R.dimen.doc_color_bar_pop_radius);
        initValue();
        if(mOrientation == Configuration.ORIENTATION_PORTRAIT) {
            currentThumbOffset = thumbWidthRadius;
        }
        else
        {
            currentThumbOffset = thumbHeigthRadius;
        }
    }

    private void initValue()
    {
        if(mOrientation == Configuration.ORIENTATION_PORTRAIT) {
            thumbWidthRadius = getContext().getResources().getDimensionPixelSize(R.dimen.doc_color_bar_thumb_width_radius);
            thumbHeigthRadius = getContext().getResources().getDimensionPixelSize(R.dimen.doc_color_bar_thumb_height_radius);
            barHeight = getContext().getResources().getDimensionPixelSize(R.dimen.doc_color_bar_height);
            barStartX = thumbPopRadius;//thumbWidthRadius;//不从0开始，左右边缘用于显示滑块
            barStartY = thumbHeigthRadius - barHeight / 2;
        }else
        {
            thumbWidthRadius = getContext().getResources().getDimensionPixelSize(R.dimen.doc_color_bar_thumb_height_radius);
            thumbHeigthRadius = getContext().getResources().getDimensionPixelSize(R.dimen.doc_color_bar_thumb_width_radius);
            barWidth = getContext().getResources().getDimensionPixelSize(R.dimen.doc_color_bar_height);
            barStartX = thumbWidthRadius - barWidth / 2;//不从0开始，左右边缘用于显示滑块
            barStartY = thumbPopRadius;
        }
    }

    private int index = 0;
    private void initTimer()
    {
        int barLength = 0;
        int thumbRadius = 0;
        if(mOrientation == Configuration.ORIENTATION_PORTRAIT) {
            barLength = barWidth;
            thumbRadius = thumbPopRadius;
        }else
        {
            barLength = barHeight;
            thumbRadius = thumbPopRadius;
        }
        float unit = (float)barLength / COLORS.length;//barWidth / (COLORS.length - 1);
        int position = (int)((currentThumbOffset - thumbRadius) / unit);
        if(position > COLORS.length - 1)
        {
            position = COLORS.length - 1;
        }

        final int center = (int)(thumbRadius + position * unit + unit / 2);
        final int centerAbs = Math.abs(center - currentThumbOffset);
        final int sep = 10;
        final int currentPosition = currentThumbOffset;

        if(null != timer)
        {
            timer.cancel();
            timer = null;
        }
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if(currentPosition > center)
                {
                    index++;
                    if(index > sep)
                    {
                        cancelTimer();
                        return;
                    }
                    currentThumbOffset = currentPosition - centerAbs * index / sep;
                    postInvalidate();
                }else if(currentPosition < center)
                {
                    index++;
                    if(index > sep)
                    {
                        cancelTimer();
                        return;
                    }
                    currentThumbOffset = currentPosition + centerAbs * index / sep;
                    postInvalidate();
                }
            }
        }, 10, 10);
    }

    private void cancelTimer()
    {
        if(null != timer)
        {
            index = 0;
            timer.cancel();
            timer = null;
        }
    }

    /**
     * onsizechanged时获取组件的长和宽，后面ondraw时就利用它们进行绘图
     *
     * @param w
     * @param h
     * @param oldw
     * @param oldh
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        GenseeLog.d(TAG, "onSizeChanged w = " + w + " h = " + h + " mOrientation = " + mOrientation);
        if(mOrientation == Configuration.ORIENTATION_PORTRAIT) {
            barWidth = w - thumbPopRadius * 2;
        }else
        {
            barHeight = h - thumbPopRadius * 2;
        }
        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        if(mOrientation == Configuration.ORIENTATION_PORTRAIT) {
            barWidth = width - thumbPopRadius * 2;
        }else
        {
            barHeight = height - thumbPopRadius * 2;
        }
        setMeasuredDimension(width, height);
    }
    private int measureWidth(int measureSpec) {

        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        return specSize;
    }


    private int measureHeight(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        return specSize;
    }

    public void setOrientation(int orientation) {
        this.mOrientation = orientation;
        GenseeLog.d(TAG, "setOrientation" + " mOrientation = " + mOrientation);
        initValue();
        invalidate();
    }

    public void setOnColorChangerListener(ColorChangeListener colorChangerListener) {
        this.colorChangeListener = colorChangerListener;
    }
    /**
     * 绘制底部颜色条
     *
     * @param canvas
     */
    private void drawBar(Canvas canvas) {
        Paint barPaint = new Paint();
        barPaint.setAntiAlias(true);
        barPaint.setFilterBitmap(false);
        barPaint.setStyle(Paint.Style.FILL);
        canvas.drawRoundRect(new RectF(barStartX, barStartY,
                barStartX + barWidth, barStartY + barHeight), CORNER_RADIUS, CORNER_RADIUS, barPaint);
        int nColorCount = COLORS.length;
        if(mOrientation == Configuration.ORIENTATION_PORTRAIT)
        {
            float nLengthPer = (float)barWidth / nColorCount;
            for(int i = 0; i < nColorCount; i++)
            {
                canvas.save();
                float nClipLeft = barStartX + i * nLengthPer;
                float nClipTop = barStartY;
                float nClipRight = barStartX + (i + 1) * nLengthPer;
                float nClipBottom = barStartY + barHeight;
                RectF clipRectF = new RectF(nClipLeft, nClipTop, nClipRight, nClipBottom);
                canvas.clipRect(clipRectF);
                barPaint.setColor(COLORS[i]);
                canvas.drawRoundRect(new RectF(barStartX, barStartY,
                        barStartX + barWidth, barStartY + barHeight), CORNER_RADIUS, CORNER_RADIUS, barPaint);
                canvas.restore();
            }
        }else
        {
            float nLengthPer = (float)barHeight / nColorCount;
            for(int i = 0; i < nColorCount; i++)
            {
                canvas.save();
                float nClipLeft = barStartX ;
                float nClipTop = barStartY + i * nLengthPer;
                float nClipRight = barStartX + barWidth;
                float nClipBottom = barStartY + (i + 1) * nLengthPer;
                RectF clipRectF = new RectF(nClipLeft, nClipTop, nClipRight, nClipBottom);
                canvas.clipRect(clipRectF);
                barPaint.setColor(COLORS[i]);
                canvas.drawRoundRect(new RectF(barStartX, barStartY,
                        barStartX + barWidth, barStartY + barHeight), CORNER_RADIUS, CORNER_RADIUS, barPaint);
                canvas.restore();
            }
        }


//        barPaint.setShader(
//                new LinearGradient(barStartX, barStartY + barHeight / 2,
//                        barStartX + barWidth, barStartY + barHeight / 2,
//                        COLORS, null, Shader.TileMode.CLAMP));
//        canvas.drawRect(
//                new Rect(barStartX, barStartY,
//                        barStartX + barWidth, barStartY + barHeight),
//                barPaint);
    }

    /**
     * 处理点击和滑动事件
     *
     * @param event
     * @return
     */

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {//点击时
            case MotionEvent.ACTION_DOWN:
                cancelTimer();
                if(mOrientation == Configuration.ORIENTATION_PORTRAIT) {
                    currentThumbOffset = (int) event.getX();
                    if (currentThumbOffset <= thumbPopRadius) currentThumbOffset = thumbPopRadius;
                    if (currentThumbOffset >= barWidth + thumbPopRadius)
                        currentThumbOffset = barWidth + thumbPopRadius;
                }else
                {
                    currentThumbOffset = (int) event.getY();
                    if (currentThumbOffset <= thumbPopRadius) currentThumbOffset = thumbPopRadius;
                    if (currentThumbOffset >= barHeight + thumbPopRadius)
                        currentThumbOffset = barHeight + thumbPopRadius;
                }
                STATUS = STATUS_SEEK;
                break;
            //滑动时
            case MotionEvent.ACTION_MOVE:
                if(mOrientation == Configuration.ORIENTATION_PORTRAIT) {
                    currentThumbOffset = (int) event.getX();
                    if (currentThumbOffset <= thumbPopRadius) currentThumbOffset = thumbPopRadius;
                    if (currentThumbOffset >= barWidth + thumbPopRadius)
                        currentThumbOffset = barWidth + thumbPopRadius;
                }else
                {
                    currentThumbOffset = (int) event.getY();
                    if (currentThumbOffset <= thumbPopRadius) currentThumbOffset = thumbPopRadius;
                    if (currentThumbOffset >= barHeight + thumbPopRadius)
                        currentThumbOffset = barHeight + thumbPopRadius;
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                STATUS = STATUS_UP;
                initTimer();
                break;
        }
        GenseeLog.i("onTouchEvent", "event.getAction() = " + event.getAction() + " currentThumbOffset = " + currentThumbOffset);
        invalidate();
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        switch (STATUS) {
            case STATUS_INIT:
                currentThumbOffset = thumbPopRadius + barWidth / COLORS.length / 2;
                drawBar(canvas);
                drawThumb(canvas);
                break;
            case STATUS_SEEK:
                drawBar(canvas);
                currentColor = getCurrentColor();
                drawThumb(canvas);
                if (colorChangeListener != null)
                    colorChangeListener.colorChange(currentColor, currentThumbOffset, true);
                break;
            case STATUS_UP:
                currentColor = getCurrentColor();
                drawBar(canvas);
                drawThumb(canvas);
                if (colorChangeListener != null)
                    colorChangeListener.colorChange(currentColor, currentThumbOffset, false);
                break;
        }
        GenseeLog.i("onDraw", "event.getAction() = " + STATUS + " currentThumbOffset = " + currentThumbOffset);
        super.onDraw(canvas);
    }

    private int ave(int s, int t, int unit, int step) {
        return s + (t - s) * step / unit;
    }

    /**
     * 获取当前所在区间，再根据颜色变换算法获取颜色值
     */

    private int getCurrentColor() {
        int barLength = 0;
        int thumbRadius = 0;
        if(mOrientation == Configuration.ORIENTATION_PORTRAIT) {
            barLength = barWidth;
            thumbRadius = thumbPopRadius;
        }else
        {
            barLength = barHeight;
            thumbRadius = thumbPopRadius;
        }
        float unit = (float)barLength / COLORS.length;//barWidth / (COLORS.length - 1);
        int position = (int)((currentThumbOffset - thumbRadius) / unit);
        if(position > COLORS.length - 1)
        {
            position = COLORS.length - 1;
        }
        return COLORS[position];//Color.argb(a, r, g, b);
    }

    private void drawThumb(Canvas canvas) {

        thumbPaint.setColor(currentColor);
        thumbPaint.setStrokeWidth(2);
        thumbPaint.setStyle(Paint.Style.FILL);
        canvas.drawRoundRect(getThumbRect(), CORNER_RADIUS, CORNER_RADIUS, thumbPaint);

        Paint emptyPaint = new Paint();
        emptyPaint.setStyle(Paint.Style.STROKE);
        emptyPaint.setStrokeWidth(2);
        emptyPaint.setColor(Color.WHITE);
        canvas.drawRoundRect(getThumbRect(), CORNER_RADIUS, CORNER_RADIUS, emptyPaint);
//        canvas.drawOval(getThumbRect(), thumbPaint);
    }

    /**
     * 获取滑块所在的矩形区域
     */
    private RectF getThumbRect() {
//        return new RectF(currentThumbOffset - thumbRadius, barStartY + barHeight / 2 - thumbRadius,
//                currentThumbOffset + thumbRadius, barStartY + barHeight / 2 + thumbRadius);
        if(mOrientation == Configuration.ORIENTATION_PORTRAIT) {
            return new RectF(currentThumbOffset - thumbWidthRadius, barStartY + barHeight / 2 - thumbHeigthRadius,
                    currentThumbOffset + thumbWidthRadius, barStartY + barHeight / 2 + thumbHeigthRadius);
        }else
        {
            return new RectF(barStartX + barWidth / 2 - thumbWidthRadius, currentThumbOffset - thumbHeigthRadius,
                    barStartX + barWidth / 2 + thumbWidthRadius, currentThumbOffset + thumbHeigthRadius);
        }
    }
}
