package com.matthias.android.amginori;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.support.v8.renderscript.Allocation;
import android.support.v8.renderscript.Element;
import android.support.v8.renderscript.RenderScript;
import android.support.v8.renderscript.ScriptIntrinsicBlur;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import java.util.ArrayList;
import java.util.List;

public class CustomLayout extends RelativeLayout {

    public final List<Point> mPoints = new ArrayList<>();
    public View mView0;
    public View mView1;

    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final RenderScript mRenderScript;
    private final ScriptIntrinsicBlur mIntrinsicBlur;
    private Bitmap mOriginal = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);

    public CustomLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        //setWillNotDraw(false);
        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(getResources().getDimensionPixelSize(R.dimen.stroke_width));
        mRenderScript = RenderScript.create(context);
        mIntrinsicBlur = ScriptIntrinsicBlur.create(mRenderScript, Element.U8_4(mRenderScript));
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        if (mPoints.isEmpty() && mView0.getHeight() > 0 && mView1.getHeight() > 0) {
            int width = Math.max(mView0.getWidth(), mView1.getWidth());
            Bitmap original = Bitmap.createBitmap(width, mView0.getHeight() + mView1.getHeight(), Bitmap.Config.ARGB_8888);
            Rect rect0 = new Rect(0, 0, width, mView0.getHeight());
            Rect rect1 = new Rect(0, mView0.getHeight(), width, mView0.getHeight() + mView1.getHeight());

            Canvas c = new Canvas(original);
            Bitmap bitmap = loadBitmapFromView(mView0);
            c.drawBitmap(bitmap, null, rect0, null);
            bitmap.recycle();
            bitmap = loadBitmapFromView(mView1);
            c.drawBitmap(bitmap, null, rect1, null);
            bitmap.recycle();

            Allocation input = Allocation.createFromBitmap(mRenderScript, original);
            Allocation output = Allocation.createTyped(mRenderScript, input.getType());
            mIntrinsicBlur.setRadius(25f);
            mIntrinsicBlur.setInput(input);
            mIntrinsicBlur.forEach(output);
            output.copyTo(original);
            input.destroy();
            output.destroy();

            BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(), original);
            drawable.setAlpha(63);
            this.setBackground(drawable);
            mOriginal.recycle();
            mOriginal = original;
        }
        quadTo(canvas);
    }

    private void quadTo(Canvas canvas) {
        Path path = new Path();
        boolean first = true;
        // TODO 20 may mean more or less on other devices
        for (int i = Math.max(mPoints.size() - 20, 0); i < mPoints.size(); i += 2) {
            Point point = mPoints.get(i);
            if (first) {
                first = false;
                path.moveTo(point.x, point.y);
            } else if (i < mPoints.size() - 1) {
                Point next = mPoints.get(i + 1);
                path.quadTo(point.x, point.y, next.x, next.y);
            } else {
                path.lineTo(point.x, point.y);
            }
        }
        canvas.drawPath(path, mPaint);
    }

    @SuppressWarnings("unused")
    private void lineTo(Canvas canvas) {
        Path path = new Path();
        boolean first = true;
        for (Point point : mPoints) {
            if (first) {
                first = false;
                path.moveTo(point.x, point.y);
            } else {
                path.lineTo(point.x, point.y);
            }
        }
        canvas.drawPath(path, mPaint);
    }

    /*@Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return false;
    }*/

    private static Bitmap loadBitmapFromView(View view) {
        View v = ((ViewGroup) view).getChildAt(0);
        Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
        v.draw(canvas);
        return bitmap;
    }
}

@@ -1051,16 +1051,17 @@
 icBlur;%0A
+%0A
     priv
@@ -1072,24 +1072,23 @@
 Bitmap m
-Original
+Current
  = Bitma
@@ -1133,16 +1133,51 @@
 B_8888);
+%0A    private long mLastUpdate = 0l;
 %0A%0A    pu
@@ -1740,29 +1740,84 @@
     
-if (mPoints.isEmpty()
+long time = System.currentTimeMillis();%0A        if (time - mLastUpdate %3E= 16
  && 
@@ -1864,24 +1864,57 @@
 ht() %3E 0) %7B%0A
+            mLastUpdate = time;%0A%0A
             
@@ -3177,24 +3177,23 @@
        m
-Original
+Current
 .recycle
@@ -3213,16 +3213,15 @@
    m
-Original
+Current
  = o

Enhance blurred background