package com.snowble.android.verticalstepper;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.ViewGroup;

import java.util.Locale;

public class VerticalStepper extends ViewGroup {

    private Context context;
    private Resources resources;

    private int outerHorizontalMargin;
    private int outerVerticalMargin;

    private int iconDimension;
    private Paint iconBackgroundPaint;
    private RectF iconRect;
    private TextPaint iconTextPaint;
    private int iconTextHeight;


    public VerticalStepper(Context context) {
        super(context);
        init();
    }

    public VerticalStepper(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

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

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public VerticalStepper(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init();
    }

    private void init() {
        setWillNotDraw(false);

        context = getContext();
        resources = getResources();

        initMargins();
        initIconProperties();
    }

    private void initMargins() {
        outerHorizontalMargin = resources.getDimensionPixelSize(R.dimen.outer_margin_horizontal);
        outerVerticalMargin = resources.getDimensionPixelSize(R.dimen.outer_margin_vertical);
    }

    private void initIconProperties() {
        initIconDimension();
        initIconBackground();
        initIconTextPaint();
    }

    private void initIconDimension() {
        iconDimension = resources.getDimensionPixelSize(R.dimen.icon_diameter);
        iconRect = new RectF(0, 0, iconDimension, iconDimension);
    }

    private void initIconBackground() {
        TypedValue value = new TypedValue();
        context.getTheme().resolveAttribute(R.attr.colorPrimary, value, true);
        int iconBackground;
        if (value.type != TypedValue.TYPE_NULL) {
            iconBackground = value.data;
        } else {
            //noinspection deprecation
            iconBackground = resources.getColor(R.color.bg_icon);
        }
        iconBackgroundPaint = new Paint();
        iconBackgroundPaint.setColor(iconBackground);
        iconBackgroundPaint.setAntiAlias(true);
    }

    private void initIconTextPaint() {
        iconTextPaint = new TextPaint();
        iconTextPaint.setColor(Color.WHITE);
        iconTextPaint.setAntiAlias(true);
        int iconTextSize = resources.getDimensionPixelSize(R.dimen.icon_font_size);
        iconTextPaint.setTextSize(iconTextSize);

        final Rect bounds = new Rect();
        iconTextPaint.getTextBounds("1", 0, 1, bounds);
        // TODO This height needs to be updated for each child
        iconTextHeight = bounds.height();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // TODO respect measure specs
        int width = outerHorizontalMargin;
        int height = outerVerticalMargin;

        width += iconDimension;
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            height += iconDimension;
            // TODO Measure child and add that to our height
        }

        int xPadding = getPaddingLeft() + getPaddingRight();
        int yPadding = getPaddingTop() + getPaddingBottom();
        width += xPadding;
        height += yPadding;
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            // TODO Update l,t,r,b based on translations
            getChildAt(i).layout(left, top, right, bottom);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            boolean isFirstChild = i == 0;
            if (isFirstChild) {
                canvas.translate(outerHorizontalMargin, outerVerticalMargin);
            }
            int stepNumber = i + 1;
            String stepNumberString = String.format(Locale.getDefault(), "%d", stepNumber);
            drawIcon(canvas, stepNumberString);
        }
    }

    private void drawIcon(Canvas canvas, String iconNumber) {
        drawIconBackground(canvas);
        drawIconText(canvas, iconNumber);
    }

    private void drawIconBackground(Canvas canvas) {
        canvas.drawArc(iconRect, 0f, 360f, true, iconBackgroundPaint);
    }

    private void drawIconText(Canvas canvas, String iconNumber) {
        float width = iconTextPaint.measureText(iconNumber);
        float centeredTextX = iconDimension / 2 - (width / 2);
        int centeredTextY = iconDimension / 2 + iconTextHeight / 2;
        canvas.drawText(iconNumber, centeredTextX, centeredTextY, iconTextPaint);
    }

    @Override
    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    }

    @Override
    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new LayoutParams(context, attrs);
    }

    @Override
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return new LayoutParams(p);
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof LayoutParams;
    }

    public static class LayoutParams extends MarginLayoutParams {
        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
        }

        public LayoutParams(int width, int height) {
            super(width, height);
        }

        public LayoutParams(ViewGroup.LayoutParams source) {
            super(source);
        }
    }
}

@@ -763,22 +763,32 @@
 ctF icon
+Background
 Rect;%0A
-
     priv
@@ -824,26 +824,27 @@
     private 
-in
+Rec
 t iconTextHe
@@ -841,21 +841,19 @@
 iconText
-Heigh
+Rec
 t;%0A%0A%0A   
@@ -1984,24 +1984,218 @@
 extPaint();%0A
+        initIconRectsForReuse();%0A    %7D%0A%0A    private void initIconRectsForReuse() %7B%0A        iconBackgroundRect = new RectF(0, 0, iconDimension, iconDimension);%0A        iconTextRect = new Rect();%0A
     %7D%0A%0A    p
@@ -2312,74 +2312,8 @@
 r);%0A
-        iconRect = new RectF(0, 0, iconDimension, iconDimension);%0A
     
@@ -3185,210 +3185,8 @@
 ze);
-%0A%0A        final Rect bounds = new Rect();%0A        iconTextPaint.getTextBounds(%221%22, 0, 1, bounds);%0A        // TODO This height needs to be updated for each child%0A        iconTextHeight = bounds.height();
 %0A   
@@ -5013,16 +5013,26 @@
 Arc(icon
+Background
 Rect, 0f
@@ -5231,16 +5231,17 @@
 TextX = 
+(
 iconDime
@@ -5249,16 +5249,17 @@
 sion / 2
+)
  - (widt
@@ -5266,16 +5266,85 @@
 h / 2);%0A
+        iconTextPaint.getTextBounds(iconNumber, 0, 1, iconTextRect);%0A
         
@@ -5363,16 +5363,17 @@
 TextY = 
+(
 iconDime
@@ -5385,19 +5385,21 @@
  / 2
+)
  + 
+(
 iconText
 Heig
@@ -5398,18 +5398,26 @@
 Text
-H
+Rect.h
 eight
+()
  / 2
+)
 ;%0A  

Make text measurement independent of step #