package jp.wasabeef.fresco.processors;

/**
 * Copyright (C) 2015 Wasabeef
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
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 com.facebook.cache.common.CacheKey;
import com.facebook.cache.common.SimpleCacheKey;
import com.facebook.imagepipeline.request.BasePostprocessor;

public class BlurPostprocessor extends BasePostprocessor {

  private static int MAX_RADIUS = 25;

  private Context context;
  private int radius;

  public BlurPostprocessor(Context context) {
    this(context, MAX_RADIUS);
  }

  public BlurPostprocessor(Context context, int radius) {
    this.context = context;
    this.radius = radius;
  }

  @Override public void process(Bitmap dest, Bitmap source) {
    Canvas canvas = new Canvas(dest);
    Paint paint = new Paint();
    paint.setFlags(Paint.FILTER_BITMAP_FLAG);
    canvas.drawBitmap(source, 0, 0, paint);

    RenderScript rs = RenderScript.create(context);
    Allocation input = Allocation.createFromBitmap(rs, dest, Allocation.MipmapControl.MIPMAP_NONE,
        Allocation.USAGE_SCRIPT);
    Allocation output = Allocation.createTyped(rs, input.getType());
    ScriptIntrinsicBlur blur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));

    blur.setInput(input);
    blur.setRadius(radius);
    blur.forEach(output);
    output.copyTo(dest);

    rs.destroy();
  }

  @Override public String getName() {
    return getClass().getSimpleName();
  }

  @Override public CacheKey getPostprocessorCacheKey() {
    return new SimpleCacheKey("radius=" + radius);
  }
}

@@ -1217,16 +1217,64 @@
 US = 25;
+%0A  private static int DEFAULT_DOWN_SAMPLING = 1;
 %0A%0A  priv
@@ -1315,16 +1315,40 @@
  radius;
+%0A  private int sampling;
 %0A%0A  publ
@@ -1415,16 +1415,39 @@
 X_RADIUS
+, DEFAULT_DOWN_SAMPLING
 );%0A  %7D%0A%0A
@@ -1500,24 +1500,151 @@
 t radius) %7B%0A
+    this(context, radius, DEFAULT_DOWN_SAMPLING);%0A  %7D%0A%0A  public BlurPostprocessor(Context context, int radius, int sampling) %7B%0A
     this.con
@@ -1685,16 +1685,46 @@
 radius;%0A
+    this.sampling = sampling;%0A
   %7D%0A%0A  @
@@ -1786,43 +1786,371 @@
 ) %7B%0A
-    Canvas canvas = new Canvas(dest
+%0A    int width = source.getWidth();%0A    int height = source.getHeight();%0A    int scaledWidth = width / sampling;%0A    int scaledHeight = height / sampling;%0A%0A    Bitmap blurredBitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);%0A%0A    Canvas canvas = new Canvas(blurredBitmap);%0A    canvas.scale(1 / (float) sampling, 1 / (float) sampling
 );%0A 
@@ -2340,24 +2340,32 @@
 tion input =
+%0A       
  Allocation.
@@ -2385,20 +2385,29 @@
 map(rs, 
-dest
+blurredBitmap
 , Alloca
@@ -2438,16 +2438,20 @@
 P_NONE,%0A
+    
         
@@ -2729,31 +2729,227 @@
 yTo(
-dest);%0A%0A    rs.destroy(
+blurredBitmap);%0A%0A    Bitmap scaledBitmap =%0A        Bitmap.createScaledBitmap(blurredBitmap, dest.getWidth(), dest.getHeight(), true);%0A    blurredBitmap.recycle();%0A%0A    rs.destroy();%0A%0A    super.process(dest, scaledBitmap
 );%0A 
@@ -3135,21 +3135,47 @@
 s=%22 + radius
+ + %22,sampling=%22 + sampling
 );%0A  %7D%0A%7D%0A

fix bug #1 and add sampling property