package com.seatel.mobilehall.util.circleprogress;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;

import com.seatel.mobilehall.R;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;

/**
 * Created by bruce on 11/6/14.
 */
public class ArcProgress extends View {
    private Paint paint;
    protected Paint textPaint;
    protected Paint textPaintSuffix;
    protected Paint textPaintPrefix;
    protected Paint textPaintDataLeft;
    protected Paint textPaintExpire;

    private RectF rectF = new RectF();

    private float strokeWidth;
    private float suffixTextSize;
    private float dataLeftTextSize;
    private float bottomTextSize;
    private String bottomText;
    private float textSize;
    private float textSizeDeduct = 37f;
    private float unlimitedTextSize;
    private int textColor;
    private int textSuffixColor;
    private int textDataLeftColor;
    private float progress = 0;
    private float max;
    private int finishedStrokeColor;
    private int unfinishedStrokeColor;
    private float arcAngle;
    private String unlimtedText = "";
    private String suffixText = "";
    private String prefixText = "";
    private String suffixTextCacth = "";
    private String fontNameText = "source-sans-pro-regular.ttf";
    private String fontNameNumber = "source-sans-pro-bold.ttf";
    private String dataLeftText = "Internet Left";
    private String expireText = "Expire on:";
    private boolean isShowDollar = false;
    private float suffixTextPadding;

    private float arcBottomHeight;

    private final int default_finished_color = Color.WHITE;
    private final int default_unfinished_color = Color.rgb(72, 106, 176);
    private final int default_text_color = Color.rgb(66, 145, 241);
    private final int default_suffix_text_color = Color.rgb(77, 74, 75);
    private final int default_dataleft_text_color = Color.rgb(77, 74, 75);
    private final float default_suffix_text_size;
    private final float default_dataleft_text_size;
    private final float default_suffix_padding;
    private final float default_bottom_text_size;
    private final float default_stroke_width;
    private final String default_suffix_text;
    private final String default_FontName_text = "source-sans-pro-regular.ttf";
    private final String default_FontName_number = "source-sans-pro-bold.ttf";
    private final float default_max = 100f;
    private final float default_arc_angle = 360 * 0.8f;
    private float default_text_size;
    private float default_text_unlimited_size;
    private final int min_size;

    private static final String INSTANCE_STATE = "saved_instance";
    private static final String INSTANCE_STROKE_WIDTH = "stroke_width";
    private static final String INSTANCE_SUFFIX_TEXT_SIZE = "suffix_text_size";
    private static final String INSTANCE_DATALEFT_TEXT_SIZE = "dataleft_text_size";
    private static final String INSTANCE_SUFFIX_TEXT_PADDING = "suffix_text_padding";
    private static final String INSTANCE_BOTTOM_TEXT_SIZE = "bottom_text_size";
    private static final String INSTANCE_BOTTOM_TEXT = "bottom_text";
    private static final String INSTANCE_TEXT_SIZE = "text_size";
    private static final String INSTANCE_TEXT_COLOR = "text_color";
    private static final String INSTANCE_TEXT_SUFFIX_COLOR = "text_suffix_color";
    private static final String INSTANCE_TEXT_DATALEFT_COLOR = "text_dataleft_color";
    private static final String INSTANCE_PROGRESS = "progress";
    private static final String INSTANCE_MAX = "max";
    private static final String INSTANCE_FINISHED_STROKE_COLOR = "finished_stroke_color";
    private static final String INSTANCE_UNFINISHED_STROKE_COLOR = "unfinished_stroke_color";
    private static final String INSTANCE_ARC_ANGLE = "arc_angle";
    private static final String INSTANCE_SUFFIX = "suffix";

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

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

    public ArcProgress(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        default_text_size = Utils.sp2px(getResources(), 18);
        min_size = (int) Utils.dp2px(getResources(), 100);
        default_text_size = Utils.sp2px(getResources(), 40);
        default_text_unlimited_size = Utils.sp2px(getResources(), 15);
        default_suffix_text_size = Utils.sp2px(getResources(), 15);
        default_dataleft_text_size = Utils.sp2px(getResources(), 15);
        default_suffix_padding = Utils.dp2px(getResources(), -20);
        default_suffix_text = "MB";
        default_bottom_text_size = Utils.sp2px(getResources(), 10);
        default_stroke_width = Utils.dp2px(getResources(), 4);

        TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ArcProgress, defStyleAttr, 0);
        initByAttributes(attributes);
        attributes.recycle();

        initPainters();
    }

    protected void initByAttributes(TypedArray attributes) {
        finishedStrokeColor = attributes.getColor(R.styleable.ArcProgress_arc_finished_color, default_finished_color);
        unfinishedStrokeColor = attributes.getColor(R.styleable.ArcProgress_arc_unfinished_color, default_unfinished_color);
        textColor = attributes.getColor(R.styleable.ArcProgress_arc_text_color, default_text_color);
        textSuffixColor = attributes.getColor(R.styleable.ArcProgress_arc_suffix_text_color, default_suffix_text_color);
        textDataLeftColor = attributes.getColor(R.styleable.ArcProgress_arc_dataleft_text_color, default_dataleft_text_color);
        textSize = attributes.getDimension(R.styleable.ArcProgress_arc_text_size, default_text_size);
        unlimitedTextSize = attributes.getDimension(R.styleable.ArcProgress_arc_text_unlimited_size, default_text_unlimited_size);
        arcAngle = attributes.getFloat(R.styleable.ArcProgress_arc_angle, default_arc_angle);
        setMax(attributes.getFloat(R.styleable.ArcProgress_arc_max, default_max));
        setProgress(attributes.getFloat(R.styleable.ArcProgress_arc_progress, 0));
        strokeWidth = attributes.getDimension(R.styleable.ArcProgress_arc_stroke_width, default_stroke_width);
        suffixTextSize = attributes.getDimension(R.styleable.ArcProgress_arc_suffix_text_size, default_suffix_text_size);
        dataLeftTextSize = attributes.getDimension(R.styleable.ArcProgress_arc_dataleft_text_size, default_dataleft_text_size);
        dataLeftText = attributes.getString(R.styleable.ArcProgress_arc_dataleft_text);
        expireText = attributes.getString(R.styleable.ArcProgress_arc_expire_text);
        isShowDollar = attributes.getBoolean(R.styleable.ArcProgress_arc_show_dollar, false);
        fontNameText = TextUtils.isEmpty(attributes.getString(R.styleable.ArcProgress_arc_fontname_text)) ? default_FontName_text : attributes.getString(R.styleable.ArcProgress_arc_fontname_text);
        fontNameNumber = TextUtils.isEmpty(attributes.getString(R.styleable.ArcProgress_arc_fontname_number)) ? default_FontName_number : attributes.getString(R.styleable.ArcProgress_arc_fontname_number);
        prefixText = TextUtils.isEmpty(attributes.getString(R.styleable.ArcProgress_arc_prefix_text)) ? "" : attributes.getString(R.styleable.ArcProgress_arc_prefix_text);
        unlimtedText = TextUtils.isEmpty(attributes.getString(R.styleable.ArcProgress_arc_unlimited_text)) ? "" : attributes.getString(R.styleable.ArcProgress_arc_unlimited_text);
        suffixText = TextUtils.isEmpty(attributes.getString(R.styleable.ArcProgress_arc_suffix_text)) ? default_suffix_text : attributes.getString(R.styleable.ArcProgress_arc_suffix_text);
        suffixTextPadding = attributes.getDimension(R.styleable.ArcProgress_arc_suffix_text_padding, default_suffix_padding);
        bottomTextSize = attributes.getDimension(R.styleable.ArcProgress_arc_bottom_text_size, default_bottom_text_size);
        bottomText = attributes.getString(R.styleable.ArcProgress_arc_bottom_text);
    }

    protected void initPainters() {
        Typeface plain = Typeface.createFromAsset(getContext().getAssets(), "fonts/" + getFontNameNumber());
        Typeface bold = Typeface.create(plain, Typeface.BOLD);
        textPaint = new TextPaint();
        textPaint.setColor(textColor);
        textPaint.setTypeface(bold);
        textPaint.setTextSize(unlimtedText.isEmpty() ? getTextSize() : unlimitedTextSize);
        textPaint.setAntiAlias(true);

        Typeface plainSuffix = Typeface.createFromAsset(getContext().getAssets(), "fonts/" + getFontNameText());
        Typeface normal = Typeface.create(plainSuffix, Typeface.NORMAL);
        Typeface preFixBold = Typeface.create(plainSuffix, Typeface.BOLD);
        textPaintSuffix = new TextPaint();
        textPaintSuffix.setColor(textSuffixColor);
        textPaintSuffix.setTextSize(suffixTextSize);
        textPaintSuffix.setTypeface(normal);
        textPaintSuffix.setAntiAlias(true);

        textPaintPrefix = new TextPaint();
        textPaintPrefix.setColor(textSuffixColor);
        textPaintPrefix.setTextSize(getTextSize());
        textPaintPrefix.setTypeface(preFixBold);
        textPaintPrefix.setAntiAlias(true);

        textPaintDataLeft = new TextPaint();
        textPaintDataLeft.setColor(textDataLeftColor);
        textPaintDataLeft.setTextSize(getDataLeftTextSize());
        textPaintDataLeft.setTypeface(normal);
        textPaintDataLeft.setAntiAlias(true);

        textPaintExpire = new TextPaint();
        textPaintExpire.setColor(textDataLeftColor);
        textPaintExpire.setTextSize(getDataLeftTextSize());
        textPaintExpire.setTypeface(normal);
        textPaintExpire.setAntiAlias(true);


        paint = new Paint();
        paint.setColor(default_unfinished_color);
        paint.setAntiAlias(true);
        paint.setStrokeWidth(strokeWidth);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeCap(Paint.Cap.BUTT);

    }

    @Override
    public void invalidate() {
        initPainters();
        super.invalidate();
    }

    public float getStrokeWidth() {
        return strokeWidth;
    }

    public void setStrokeWidth(float strokeWidth) {
        this.strokeWidth = strokeWidth;
        this.invalidate();
    }

    public float getSuffixTextSize() {
        return suffixTextSize;
    }

    public void setSuffixTextSize(float suffixTextSize) {
        this.suffixTextSize = suffixTextSize;
        this.invalidate();
    }

    public float getDataLeftTextSize() {
        if (getIsShowDollar())
            return dataLeftTextSize - 5f;
        else return dataLeftTextSize;
    }

    public void setDataLeftTextSize(float dataLeftTextSize) {
        this.dataLeftTextSize = dataLeftTextSize;
        this.invalidate();
    }

    public String getBottomText() {
        return bottomText;
    }

    public void setBottomText(String bottomText) {
        this.bottomText = bottomText;
        this.invalidate();
    }

    public float getProgress() {
        return progress;
    }

    public void setProgress(float progress) {
        String valFormat;
        if (isShowDollar) {
            valFormat = new DecimalFormat("#.##").format(progress);
            valFormat = valFormat.replace(",", ".");
        } else {
            valFormat = new DecimalFormat("#.#").format(progress);
            valFormat = valFormat.replace(",", ".");
        }
        this.progress = Float.valueOf(valFormat);
        if (this.progress > getMax()) {
            this.progress %= getMax();
        }
        invalidate();
    }

    public float getMax() {
        return max;
    }

    public void setMax(float max) {
        if (max > 0) {
            this.max = max;
            invalidate();
        }
    }

    public float getBottomTextSize() {
        return bottomTextSize;
    }

    public void setBottomTextSize(float bottomTextSize) {
        this.bottomTextSize = bottomTextSize;
        this.invalidate();
    }

    public void setTextSizeDeduct(float textSizeDeduct) {
        this.textSizeDeduct = textSizeDeduct;
        this.invalidate();
    }

    public float getTextSize() {
        if (isShowDollar)
            return textSize - textSizeDeduct;
        else return textSize;
    }

    public void setTextSize(float textSize) {
        this.textSize = textSize;
        this.invalidate();
    }

    public void setUnlimitedTextSize(float unlimitedTextSize) {
        this.unlimitedTextSize = unlimitedTextSize;
        this.invalidate();
    }

    public int getTextColor() {
        return textColor;
    }

    public void setTextColor(int textColor) {
        this.textColor = textColor;
        this.invalidate();
    }

    public void setUnlimtedText(String unlimtedText) {
        this.unlimtedText = unlimtedText;
        this.invalidate();
    }

    public int getFinishedStrokeColor() {
        return finishedStrokeColor;
    }

    public void setFinishedStrokeColor(int finishedStrokeColor) {
        this.finishedStrokeColor = finishedStrokeColor;
        this.invalidate();
    }

    public int getUnfinishedStrokeColor() {
        return unfinishedStrokeColor;
    }

    public void setUnfinishedStrokeColor(int unfinishedStrokeColor) {
        this.unfinishedStrokeColor = unfinishedStrokeColor;
        this.invalidate();
    }

    public float getArcAngle() {
        return arcAngle;
    }

    public void setArcAngle(float arcAngle) {
        this.arcAngle = arcAngle;
        this.invalidate();
    }

    public String getDataLeftText() {
        return dataLeftText;
    }

    public void setDataLeftText(String dataLeftText) {
        this.dataLeftText = dataLeftText;
        this.invalidate();
    }

    public boolean getIsShowDollar() {
        return isShowDollar;
    }

    public void setIsShowDollar(boolean show) {
        this.isShowDollar = show;
        this.invalidate();
    }

    public String getExpireText() {
        return expireText;
    }

    public void setExpireText(String expireText) {
        this.expireText = expireText;
        this.invalidate();
    }

    public String getFontNameText() {
        return fontNameText;
    }

    public void setFontNameText(String fontNameText) {
        this.fontNameText = fontNameText;
        this.invalidate();
    }

    public String getFontNameNumber() {
        return fontNameNumber;
    }

    public void setFontNameNumber(String fontNameNumber) {
        this.fontNameNumber = fontNameNumber;
        this.invalidate();
    }

    public String getPrefixText() {
        return prefixText;
    }

    public void setPrefixText(String prefixText) {
        this.prefixText = prefixText;
        this.invalidate();
    }

    public String getSuffixText() {
        return suffixText;
    }

    public void setSuffixText(String suffixText) {
        this.suffixText = suffixText;
        this.suffixTextCacth = suffixText;
        this.invalidate();
    }

    public float getSuffixTextPadding() {
        return suffixTextPadding;
    }

    public void setSuffixTextPadding(float suffixTextPadding) {
        this.suffixTextPadding = suffixTextPadding;
        this.invalidate();
    }

    @Override
    protected int getSuggestedMinimumHeight() {
        return min_size;
    }

    @Override
    protected int getSuggestedMinimumWidth() {
        return min_size;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        rectF.set(strokeWidth / 2f, strokeWidth / 2f, width - strokeWidth / 2f, MeasureSpec.getSize(heightMeasureSpec) - strokeWidth / 2f);
        float radius = width / 2f;
        float angle = (360 - arcAngle) / 2f; //360
        arcBottomHeight = radius * (float) (1 - Math.cos(angle / 180 * Math.PI));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        float startAngle = 270 - arcAngle / 2f; //270
        float finishedSweepAngle = progress / getMax() * arcAngle;
        float finishedStartAngle = startAngle;
        float textHeightTop = 0;
        if (progress == 0) finishedStartAngle = 0.01f;

        //For clip view bottom edge of chart
        canvas.clipRect(0, 0, rectF.width() + rectF.height(), rectF.height() - strokeWidth);

        paint.setColor(unfinishedStrokeColor);
        canvas.drawArc(rectF, startAngle, arcAngle, false, paint);
        paint.setColor(finishedStrokeColor);
        canvas.drawArc(rectF, finishedStartAngle, finishedSweepAngle, false, paint);

        String text = String.valueOf(getProgress());

        if (!TextUtils.isEmpty(unlimtedText)) {
            text = unlimtedText;
            if (!TextUtils.isEmpty(text) && TextUtils.isEmpty(getPrefixText())) {
                float textHeightBottom = 0;
                int space = 0;
                if (!TextUtils.isEmpty(getDataLeftText())) {
                    textPaintDataLeft.setColor(textDataLeftColor);
                    textPaintDataLeft.setTextSize(getDataLeftTextSize());
                    textHeightBottom = textPaintDataLeft.descent() + textPaintDataLeft.ascent();
                    space = 15;
                }
                // Unlimited Text
                textPaint.setColor(textColor);
                textPaint.setTextSize(unlimitedTextSize);
                textHeightTop = textPaint.descent() + textPaint.ascent();
                float textBaselineTop = (getHeight() - textHeightTop + textHeightBottom - Utils.sp2px(getResources(), space)) / 2.0f;
                canvas.drawText(text, (getWidth() - textPaint.measureText(text)) / 2.0f, textBaselineTop, textPaint);
            }

            if (!TextUtils.isEmpty(getDataLeftText())) {
                textPaintDataLeft.setColor(textDataLeftColor);
                textPaintDataLeft.setTextSize(getDataLeftTextSize());
                float textHeight = textPaintDataLeft.descent() + textPaintDataLeft.ascent();
                float textBaseline = ((getHeight() - textHeight) / 2.0f) - ((textHeightTop - textHeight / 2 - Utils.sp2px(getResources(), 5)) / 2.0f); // 70 - Utils.sp2px(getResources(), 25)
                canvas.drawText(getDataLeftText(), (getWidth() - textPaintDataLeft.measureText(getDataLeftText())) / 2.0f, textBaseline, textPaintDataLeft);
                textPaint.setTextSize(getDataLeftTextSize());
                textPaint.setColor(textDataLeftColor);
            }
        } else {
            if (TextUtils.equals(getSuffixText().toLowerCase(), "gb") || TextUtils.equals(getSuffixText().toLowerCase(), "tb")) {
                if (TextUtils.equals(getSuffixText().toLowerCase(), "tb"))
                    if (getProgress() < 1.0f) {
                        float valGb = getProgress() * 1024;
                        text = String.format("%.1f", valGb);
                        text = text.replace(",", ".");
                        suffixTextCacth = "GB";
                    } else {
                        text = String.format("%.1f", getProgress());
                        text = text.replace(",", ".");
                        suffixTextCacth = "TB";
                    }
                else {
                    if (getProgress() < 1.0f) {
                        float valGb = getProgress() * 1024;
                        text = "" + (int) valGb;
                        text = text.replace(",", ".");
                        suffixTextCacth = "MB";
                    } else {
                        text = String.format("%.1f", getProgress());
                        text = text.replace(",", ".");
                        String str = text.substring(text.length() - 2);
                        if (TextUtils.equals(str, ".0"))
                            text = String.valueOf((int) getProgress());
                        suffixTextCacth = "GB";
                    }
                }
            } else {
                if (getIsShowDollar()) {
                    DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(Locale.getDefault());
                    otherSymbols.setDecimalSeparator('.');
                    otherSymbols.setGroupingSeparator(',');

                    DecimalFormat df = new DecimalFormat("$###,###.##", otherSymbols);
                    text = df.format(getProgress());
                } else {
                    text = String.valueOf((int) getProgress());
                }
            }

            if (!TextUtils.isEmpty(text) && TextUtils.isEmpty(getPrefixText())) {
                float textHeightBottom = 70;
                if (!TextUtils.isEmpty(getDataLeftText())) {
                    textPaintDataLeft.setColor(textDataLeftColor);
                    textPaintDataLeft.setTextSize(getDataLeftTextSize());
                    textHeightBottom = textPaintDataLeft.descent() + textPaintDataLeft.ascent();
                }
                if (!TextUtils.isEmpty(getExpireText())) {
                    textPaintExpire.setColor(textDataLeftColor);
                    textPaintExpire.setTextSize(getDataLeftTextSize());
                    textHeightBottom = textHeightBottom - (textPaintExpire.descent() + textPaintExpire.ascent());
                }
                textPaint.setColor(textColor);
                textPaint.setTextSize(getTextSize());
                textHeightTop = textPaint.descent() + textPaint.ascent();
                float textBaselineTop = (getHeight() - textHeightTop + textHeightBottom - Utils.sp2px(getResources(), 15)) / 2.0f; //70
                if (!TextUtils.isEmpty(getExpireText())) {
                    textBaselineTop = (getHeight() - textHeightTop + textHeightBottom - Utils.sp2px(getResources(), 65)) / 2.0f;
                }
                canvas.drawText(text, (getWidth() - textPaint.measureText(text) - textPaintSuffix.measureText(suffixTextCacth)) / 2.0f, textBaselineTop, textPaint);
                float wid = (getWidth() - textPaint.measureText(text) - textPaintSuffix.measureText(suffixText)) / 2.0f;
                wid = wid + textPaint.measureText(text);
                textPaint.setTextSize(suffixTextSize);
                textPaint.setColor(textSuffixColor);
                canvas.drawText(suffixTextCacth, wid + suffixTextPadding, textBaselineTop, textPaintSuffix);

            }

            if (!TextUtils.isEmpty(getPrefixText())) {
                DecimalFormat df = new DecimalFormat("###.##");
                text = df.format(getProgress());
                float textHeightBottom = 0;
                if (!TextUtils.isEmpty(getDataLeftText())) {
                    textPaintDataLeft.setColor(textDataLeftColor);
                    textPaintDataLeft.setTextSize(getDataLeftTextSize());
                    textHeightBottom = textPaintDataLeft.descent() + textPaintDataLeft.ascent();
                }
                if (!TextUtils.isEmpty(getExpireText())) {
                    textPaintExpire.setColor(textDataLeftColor);
                    textPaintExpire.setTextSize(getDataLeftTextSize());
                    textHeightBottom = textHeightBottom + textPaintExpire.descent() + textPaintExpire.ascent();
                }

                textPaint.setColor(textColor);
                textPaint.setTextSize(getTextSize());
                textHeightTop = textPaint.descent() + textPaint.ascent();
                float textBaselineTop = (getHeight() - textHeightTop + textHeightBottom - Utils.sp2px(getResources(), 15)) / 2.0f;
                canvas.drawText(text, (getWidth() + textPaintPrefix.measureText(getPrefixText()) - textPaint.measureText(text)) / 2.0f, textBaselineTop, textPaint);
                float wid = (getWidth() - textPaintPrefix.measureText(getPrefixText()) - textPaint.measureText(text)) / 2.0f;
                textPaint.setTextSize(suffixTextSize);
                textPaint.setColor(textSuffixColor);
                canvas.drawText(getPrefixText(), wid, textBaselineTop, textPaintPrefix);
            }

            if (!TextUtils.isEmpty(getDataLeftText())) {
                textPaintDataLeft.setColor(textDataLeftColor);
                textPaintDataLeft.setTextSize(getDataLeftTextSize());
                float textHeight = textPaintDataLeft.descent() + textPaintDataLeft.ascent();
                float textBaseline = ((getHeight() - textHeight) / 2.0f) - ((textHeightTop - textHeight / 2 - Utils.sp2px(getResources(), 5)) / 2.0f); // 70 - Utils.sp2px(getResources(), 25)
                if (!TextUtils.isEmpty(getExpireText())) {
                    textPaintExpire.setColor(textDataLeftColor);
                    textPaintExpire.setTextSize(getDataLeftTextSize());
                    textHeight = textPaintDataLeft.descent() + textPaintDataLeft.ascent() - (textPaintExpire.descent() + textPaintExpire.ascent());
                    textBaseline = ((getHeight() - textHeight) / 2.0f) - ((textHeightTop - textHeight / 2 + Utils.sp2px(getResources(), 25)) / 2.0f);
                }

                canvas.drawText(getDataLeftText(), (getWidth() - textPaintDataLeft.measureText(getDataLeftText())) / 2.0f, textBaseline, textPaintDataLeft);
                textPaint.setTextSize(getDataLeftTextSize());
                textPaint.setColor(textDataLeftColor);
            }

            if (!TextUtils.isEmpty(getExpireText())) {
                textPaintDataLeft.setColor(textDataLeftColor);
                textPaintDataLeft.setTextSize(getDataLeftTextSize());
                textPaintExpire.setColor(textDataLeftColor);
                textPaintExpire.setTextSize(getDataLeftTextSize());
                float textHeight = (textPaintDataLeft.descent() + textPaintDataLeft.ascent()) + (textPaintExpire.descent() + textPaintExpire.ascent());
                float textBaseline = ((getHeight() - textHeight) / 2.0f) - ((textHeightTop - textHeight / 2 - Utils.sp2px(getResources(), 35)) / 2.0f); // 70 - Utils.sp2px(getResources(), 25)
                canvas.drawText(getExpireText(), (getWidth() - textPaintExpire.measureText(getExpireText())) / 2.0f, textBaseline, textPaintExpire);
                textPaint.setTextSize(getDataLeftTextSize());
                textPaint.setColor(textDataLeftColor);
            }

            if (arcBottomHeight == 0) {
                float radius = getWidth() / 2f;
                float angle = (360 - arcAngle) / 2f;
                arcBottomHeight = radius * (float) (1 - Math.cos(angle / 180 * Math.PI));
            }
            if (!TextUtils.isEmpty(getBottomText())) {
                textPaint.setTextSize(bottomTextSize);
                float bottomTextBaseline = getHeight() - arcBottomHeight - (textPaint.descent() + textPaint.ascent()) / 2;
                canvas.drawText(getBottomText(), (getWidth() - textPaint.measureText(getBottomText())) / 2.0f, bottomTextBaseline, textPaint);
            }
        }
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        final Bundle bundle = new Bundle();
        bundle.putParcelable(INSTANCE_STATE, super.onSaveInstanceState());
        bundle.putFloat(INSTANCE_STROKE_WIDTH, getStrokeWidth());
        bundle.putFloat(INSTANCE_SUFFIX_TEXT_SIZE, getSuffixTextSize());
        bundle.putFloat(INSTANCE_DATALEFT_TEXT_SIZE, getDataLeftTextSize());
        bundle.putFloat(INSTANCE_SUFFIX_TEXT_PADDING, getSuffixTextPadding());
        bundle.putFloat(INSTANCE_BOTTOM_TEXT_SIZE, getBottomTextSize());
        bundle.putString(INSTANCE_BOTTOM_TEXT, getBottomText());
        bundle.putFloat(INSTANCE_TEXT_SIZE, getTextSize());
        bundle.putInt(INSTANCE_TEXT_COLOR, getTextColor());
        bundle.putInt(INSTANCE_TEXT_SUFFIX_COLOR, getTextSuffixColor());
        bundle.putInt(INSTANCE_TEXT_DATALEFT_COLOR, getTextSuffixColor());
        bundle.putFloat(INSTANCE_PROGRESS, getProgress());
        bundle.putFloat(INSTANCE_MAX, getMax());
        bundle.putInt(INSTANCE_FINISHED_STROKE_COLOR, getFinishedStrokeColor());
        bundle.putInt(INSTANCE_UNFINISHED_STROKE_COLOR, getUnfinishedStrokeColor());
        bundle.putFloat(INSTANCE_ARC_ANGLE, getArcAngle());
        bundle.putString(INSTANCE_SUFFIX, getSuffixText());
        return bundle;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state instanceof Bundle) {
            final Bundle bundle = (Bundle) state;
            strokeWidth = bundle.getFloat(INSTANCE_STROKE_WIDTH);
            suffixTextSize = bundle.getFloat(INSTANCE_SUFFIX_TEXT_SIZE);
            dataLeftTextSize = bundle.getFloat(INSTANCE_DATALEFT_TEXT_SIZE);
            suffixTextPadding = bundle.getFloat(INSTANCE_SUFFIX_TEXT_PADDING);
            bottomTextSize = bundle.getFloat(INSTANCE_BOTTOM_TEXT_SIZE);
            bottomText = bundle.getString(INSTANCE_BOTTOM_TEXT);
            textSize = bundle.getFloat(INSTANCE_TEXT_SIZE);
            textColor = bundle.getInt(INSTANCE_TEXT_COLOR);
            textSuffixColor = bundle.getInt(INSTANCE_TEXT_SUFFIX_COLOR);
            setMax(bundle.getFloat(INSTANCE_MAX));
            setProgress(bundle.getFloat(INSTANCE_PROGRESS));
            finishedStrokeColor = bundle.getInt(INSTANCE_FINISHED_STROKE_COLOR);
            unfinishedStrokeColor = bundle.getInt(INSTANCE_UNFINISHED_STROKE_COLOR);
            suffixText = bundle.getString(INSTANCE_SUFFIX);
            initPainters();
            super.onRestoreInstanceState(bundle.getParcelable(INSTANCE_STATE));
            return;
        }
        super.onRestoreInstanceState(state);
    }

    public int getTextDataLeftColor() {
        return textDataLeftColor;
    }

    public void setTextDataLeftColor(int textDataLeftColor) {
        this.textDataLeftColor = textDataLeftColor;
        this.invalidate();
    }

    public int getTextSuffixColor() {
        return textSuffixColor;
    }

    public void setTextSuffixColor(int textSuffixColor) {
        this.textSuffixColor = textSuffixColor;
    }
}
