package com.github.anastr.speedviewlib.base;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;

import com.github.anastr.speedviewlib.R;

/**
 * this Library build By Anas Altair
 * see it on <a href="https://github.com/anastr/SpeedView">GitHub</a>
 */
public abstract class LinearGauge extends Gauge {

    /** the shape */
    protected Path path = new Path();

    protected Paint frontPaint = new Paint(Paint.ANTI_ALIAS_FLAG)
            , backPaint = new Paint(Paint.ANTI_ALIAS_FLAG)
            , paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    /** to draw part of bitmap */
    private Rect rect = new Rect();
    private Bitmap foregroundBitmap;

    /** horizontal or vertical direction */
    private Orientation orientation = Orientation.HORIZONTAL;

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

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

    public LinearGauge(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttributeSet(context, attrs);
    }

    /** to reset {@link #path} for horizontal shape. */
    protected abstract void updateHorizontalPath();
    /** to reset {@link #path} for vertical shape. */
    protected abstract void updateVerticalPath();

    private void initAttributeSet(Context context, AttributeSet attrs) {
        if (attrs == null)
            return;
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.LinearGauge, 0, 0);

        int orientation = a.getInt(R.styleable.LinearGauge_sv_orientation, -1);
        if (orientation != -1)
            setOrientation(Orientation.values()[orientation]);
        a.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int w = getMeasuredWidth();
        int h = getMeasuredHeight();
        if (orientation == Orientation.HORIZONTAL) {
            if (h > w/2)
                setMeasuredDimension(w, w/2);
            else
                setMeasuredDimension(h*2, h);
        }
        else {
            if (w > h/2)
                setMeasuredDimension(h/2, h);
            else
                setMeasuredDimension(w, w*2);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldW, int oldH) {
        super.onSizeChanged(w, h, oldW, oldH);

        updateBackgroundBitmap();
    }

    @Override
    protected void updateBackgroundBitmap() {
        Canvas c = createBackgroundBitmapCanvas();
        updateOrientation();
        updateForegroundBitmap();

        c.translate(getPadding(), getPadding());
        c.drawPath(path, backPaint);
    }

    private void updateOrientation() {
        if (getOrientation() == Orientation.HORIZONTAL)
            updateHorizontalPath();
        else
            updateVerticalPath();
    }

    private void updateForegroundBitmap() {
        foregroundBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);

        Canvas c = new Canvas(foregroundBitmap);
        c.drawPath(path, frontPaint);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (orientation == Orientation.HORIZONTAL)
            rect.set(0, 0
                    , (int)(getWidthPa() * getOffsetSpeed()), getHeightPa());
        else
            rect.set(0, getHeightPa() - (int)(getHeightPa() * getOffsetSpeed())
                    , getWidthPa(), getHeightPa());

        canvas.translate(getPadding(), getPadding());
        canvas.drawBitmap(foregroundBitmap, rect, rect, paint);
        canvas.translate(-getPadding(), -getPadding());

        drawSpeedUnitText(canvas);
    }

    public Orientation getOrientation() {
        return orientation;
    }

    /**
     * change fill orientation,
     * this will change view width and height.
     * @param orientation new orientation.
     */
    public void setOrientation(Orientation orientation) {
        this.orientation = orientation;
        if (!isAttachedToWindow())
            return;
        requestLayout();
        updateBackgroundBitmap();
        invalidate();
    }

    public enum Orientation {
        HORIZONTAL, VERTICAL
    }
}

@@ -209,38 +209,8 @@
 nt;%0A
-import android.graphics.Path;%0A
 impo
@@ -486,202 +486,21 @@
     
-/** the shape */%0A    protected Path path = new Path();%0A%0A    protected Paint frontPaint = new Paint(Paint.ANTI_ALIAS_FLAG)%0A            , backPaint = new Paint(Paint.ANTI_ALIAS_FLAG)%0A            ,
+private Paint
  pai
@@ -1118,159 +1118,286 @@
  /**
- to reset %7B@link #path%7D for horizontal shape. */%0A    protected abstract void updateHorizontalPath();%0A    /** to reset %7B@link #path%7D for vertical shape.
+%0A     * update background and foreground bitmap,%0A     * this method called when change size, color, orientation...%0A     * %3Cp%3E%0A     *     must call %7B@link #createBackgroundBitmapCanvas()%7D and%0A     *     %7B@link #createForegroundBitmapCanvas()%7D inside this method.%0A     * %3C/p%3E%0A    
  */%0A
@@ -1426,36 +1426,43 @@
  void update
-VerticalPath
+FrontAndBackBitmaps
 ();%0A%0A    pri
@@ -1885,596 +1885,8 @@
  %7D%0A%0A
-    @Override%0A    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) %7B%0A        super.onMeasure(widthMeasureSpec, heightMeasureSpec);%0A        int w = getMeasuredWidth();%0A        int h = getMeasuredHeight();%0A        if (orientation == Orientation.HORIZONTAL) %7B%0A            if (h %3E w/2)%0A                setMeasuredDimension(w, w/2);%0A            else%0A                setMeasuredDimension(h*2, h);%0A        %7D%0A        else %7B%0A            if (w %3E h/2)%0A                setMeasuredDimension(h/2, h);%0A            else%0A                setMeasuredDimension(w, w*2);%0A        %7D%0A    %7D%0A%0A
     
@@ -2125,46 +2125,32 @@
     
-Canvas c = createBackground
+updateFrontAndBack
 Bitmap
-Canva
 s();
@@ -2158,389 +2158,156 @@
     
+%7D%0A%0A
     
-updateOrientation();%0A        updateForegroundBitmap();%0A%0A        c.translate(getPadding(), getPadding());%0A        c.drawPath(path, backPaint);%0A    %7D%0A%0A    private void updateOrientation() %7B%0A        if (getOrientation() == Orientation.HORIZONTAL)%0A            updateHorizontalPath();%0A        else%0A            updateVerticalPath();%0A    %7D%0A%0A    private void updateForegroundBitmap() %7B
+protected final Canvas createForegroundBitmapCanvas() %7B%0A        if (getWidthPa() == 0 %7C%7C getHeightPa() == 0)%0A            return new Canvas();
 %0A   
@@ -2358,16 +2358,18 @@
 getWidth
+Pa
 (), getH
@@ -2373,16 +2373,18 @@
 etHeight
+Pa
 (), Bitm
@@ -2405,25 +2405,24 @@
 _8888);%0A
-%0A
         
 Canvas c
@@ -2417,18 +2417,14 @@
     
-Canvas c =
+return
  new
@@ -2454,46 +2454,8 @@
 p);%0A
-        c.drawPath(path, frontPaint);%0A
     

update base LinearGauge