package com.yidianling.common.view;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.text.TextPaint;

import java.util.ArrayList;

/**
 * Created by DeanGuo on 12/24/15.
 */
public class RxRotateBarBasic {

    private static final int ITEM_OFFSET = 1;

    private static final int SHADOW_ALPHA = (int) (255 * 0.2); // 20%

    private static final int UN_RATING_ALPHA = (int) (255 * 0.3); // 30%

    private static final int RATING_ALPHA = (int) (255 * 1.0); // 100%

    private static final int OUTLINE_ALPHA = (int) (255 * 0.4); // 40%

    private boolean isSingle = false;

    private boolean isShowTitle = true;

    private int outlineWidth, ratingBarWidth, shadowWidth, textWidth;

    private float mStartAngle;

    private float mSweepAngle;

    private int maxRate = 10;

    private int mCurRate;

    private ArrayList<Rate> rates;

    private Paint ratedPaint, unRatedPaint, shadowPaint, outlinePaint;
    private TextPaint titlePaint;

    private int mRadius;

    private String mTitle;

    private int mCenterX, mCenterY;

    private RectF outlineOval, ratingOval, shadowOval;

    public RxRotateBarBasic(int curRate, String title) {
        this.mCurRate = curRate;
        this.mTitle = title;

        outlinePaint = new Paint();
        ratedPaint = new Paint();
        unRatedPaint = new Paint();
        shadowPaint = new Paint();
        titlePaint = new TextPaint();
        // set default color
        setRatingBarColor(Color.WHITE);
    }

    protected void init() {
        // in this order to init
        initRatingBar();
        initOval();
        initPaint();
    }

    private void initOval() {
        mRadius = mCenterX > mCenterY ? mCenterY : mCenterX;

        // text bar : 1/10 of radius
        textWidth = mRadius / 10;
        // rating bar : 1/10 of radius
        ratingBarWidth = mRadius / 10;
        // shadow : 1/3 of rating bar
        shadowWidth = ratingBarWidth / 3;
        // outline : 1/3 of shadow
        outlineWidth = shadowWidth / 3;

        int outlineRadius = mRadius - (textWidth / 2); // outline include text and outline, radius is base on textWidth

        int paddingRadius = outlineRadius - (textWidth / 2); // padding space draw nothing, radius is base on textWidth

        int ratingBarRadius = paddingRadius - (textWidth / 2) - (ratingBarWidth / 2);

        int shadowRadius = ratingBarRadius - (ratingBarWidth / 2) - (shadowWidth / 2);

        outlineOval = new RectF();
        ratingOval = new RectF();
        shadowOval = new RectF();

        outlineOval.left = mCenterX - outlineRadius;
        outlineOval.top = mCenterY - outlineRadius;
        outlineOval.right = mCenterX + outlineRadius;
        outlineOval.bottom = mCenterY + outlineRadius;

        ratingOval.left = mCenterX - ratingBarRadius;
        ratingOval.top = mCenterY - ratingBarRadius;
        ratingOval.right = mCenterX + ratingBarRadius;
        ratingOval.bottom = mCenterY + ratingBarRadius;

        shadowOval.left = mCenterX - shadowRadius;
        shadowOval.top = mCenterY - shadowRadius;
        shadowOval.right = mCenterX + shadowRadius;
        shadowOval.bottom = mCenterY + shadowRadius;
    }

    private void initPaint() {

        outlinePaint.setAntiAlias(true);
        outlinePaint.setStyle(Paint.Style.STROKE);
        outlinePaint.setStrokeWidth(outlineWidth);
        outlinePaint.setAlpha(OUTLINE_ALPHA);

        ratedPaint.setAntiAlias(true);
        ratedPaint.setStyle(Paint.Style.STROKE);
        ratedPaint.setStrokeWidth(ratingBarWidth);
        ratedPaint.setAlpha(RATING_ALPHA);

        unRatedPaint.setAntiAlias(true);
        unRatedPaint.setStyle(Paint.Style.STROKE);
        unRatedPaint.setStrokeWidth(ratingBarWidth);
        unRatedPaint.setAlpha(UN_RATING_ALPHA);

        shadowPaint.setAntiAlias(true);
        shadowPaint.setStyle(Paint.Style.STROKE);
        shadowPaint.setStrokeWidth(shadowWidth);
        shadowPaint.setAlpha(SHADOW_ALPHA);

        titlePaint.setAntiAlias(true);
        titlePaint.setTextSize(textWidth);
        titlePaint.setAlpha(RATING_ALPHA);
    }

    private void initRatingBar() {
        rates = new ArrayList<>();

        float itemSweepAngle;
        if (isSingle) {
            itemSweepAngle = (mSweepAngle - (ITEM_OFFSET * (maxRate))) / maxRate;
        } else {
            itemSweepAngle = (mSweepAngle - (ITEM_OFFSET * (maxRate - 1))) / maxRate;
        }

        for (int i = 0; i < maxRate; i++) {
            float itemStartAngle = mStartAngle + i * (itemSweepAngle + ITEM_OFFSET);
            rates.add(new Rate(itemStartAngle, itemSweepAngle));
        }
    }

    protected void drawUnRate(Canvas canvas) {
        for (Rate arc : rates) {
            arc.drawArc(canvas, ratingOval, unRatedPaint);
        }
    }

    protected void drawRate(Canvas canvas, int index) {
        if (index >= maxRate) {
            return;
        }
        Rate arc = rates.get(index);
        arc.drawArc(canvas, ratingOval, ratedPaint);
    }

    protected void drawShadow(Canvas canvas) {
        for (Rate arc : rates) {
            arc.drawArc(canvas, shadowOval, shadowPaint);
        }
    }

    protected void drawTitle(Canvas canvas, int alpha) {
        if (alpha > 0 && isShowTitle) {
            Path path = new Path();
            float circumference = (float) (Math.PI * (outlineOval.right - outlineOval.left));
            float textAngle = (360 / circumference) * titlePaint.measureText(getTitle());

            float startAngle = mStartAngle + mSweepAngle / 2 - textAngle / 2;

            if (isSingle) {
                // when single, draw 360 the path will be a circle
                path.addArc(outlineOval, startAngle - mSweepAngle / 2, mSweepAngle / 2);
            } else {
                path.addArc(outlineOval, startAngle, mSweepAngle);
            }

            titlePaint.setAlpha(alpha);
            canvas.drawTextOnPath(mTitle, path, 0, textWidth / 3, titlePaint);
        }
    }

    protected void drawOutLine(Canvas canvas) {

        float circumference = (float) (Math.PI * (outlineOval.right - outlineOval.left));
        float textAngle = (360 / circumference) * titlePaint.measureText(getTitle());

        float sweepAngle = (mSweepAngle - textAngle - 1 - 1) / 2;

        if (isShowTitle) {
            // text left
            float leftStartAngle = mStartAngle;
            canvas.drawArc(outlineOval, leftStartAngle, sweepAngle, false, outlinePaint);
            // text right
            float rightStartAngle = mStartAngle + mSweepAngle - sweepAngle;
            canvas.drawArc(outlineOval, rightStartAngle, sweepAngle, false, outlinePaint);
        } else {
            canvas.drawArc(outlineOval, mStartAngle, mSweepAngle, false, outlinePaint);
        }


    }

    public void setMaxRate(int maxRate) {
        this.maxRate = maxRate;
    }

    public int getRate() {
        return mCurRate;
    }

    public void setRate(int curRate) {
        this.mCurRate = curRate;
    }

    protected void setStartAngle(float mStartAngle) {
        this.mStartAngle = mStartAngle;
    }

    protected void setSweepAngle(float mSweepAngle) {
        this.mSweepAngle = mSweepAngle;
    }

    protected void setCenterX(int mCenterX) {
        this.mCenterX = mCenterX;
    }

    protected void setCenterY(int mCenterY) {
        this.mCenterY = mCenterY;
    }

    protected void setIsSingle(boolean isSingle) {
        this.isSingle = isSingle;
    }

    public String getTitle() {
        return mTitle;
    }

    public void setTitle(String title) {
        this.mTitle = title;
    }

    public void setRatedColor(int color) {
        ratedPaint.setColor(color);
    }

    public void setUnRatedColor(int color) {
        unRatedPaint.setColor(color);
    }

    public void setTitleColor(int color) {
        titlePaint.setColor(color);
    }

    public void setOutlineColor(int color) {
        outlinePaint.setColor(color);
    }

    public void setShadowColor(int color) {
        shadowPaint.setColor(color);
    }

    public void isShowTitle(boolean isShow) {
        isShowTitle = isShow;
    }

    public void setRatingBarColor(int color) {
        ratedPaint.setColor(color);
        unRatedPaint.setColor(color);
        titlePaint.setColor(color);
        outlinePaint.setColor(color);
        shadowPaint.setColor(color);
    }

    /**
     * Rate class
     */
    public class Rate {
        private float startAngle, sweepAngle;

        public Rate(float startAngle, float sweepAngle) {
            this.startAngle = startAngle;
            this.sweepAngle = sweepAngle;
        }

        public void drawArc(Canvas canvas, RectF oval, Paint paint) {
            canvas.drawArc(oval, startAngle, sweepAngle, false, paint);
        }
    }

}
