// Path: decor/src/main/java/com/mounacheikhna/decor/AttrsDecorator.java
// public abstract class AttrsDecorator<T extends View> implements Decorator {
// 
//     TypedArray values;
// 
//     @Override
//     public void apply(View view, View parent, String name, Context context, AttributeSet attributeSet) {
//         if (!clazz().isAssignableFrom(view.getClass())) {
//             return;
//         }
// 
//         values = obtainAttributes(context, attributeSet);
//         if(values == null || values.length() == 0) return;
// 
//         try {
//             for (int i = 0; i < values.length(); i++) {
//                 TypedValue buf = new TypedValue();
//                 if (values.hasValue(i) && values.getValue(i, buf)) {
//                     apply((T) view, values);
//                     break;
//                 }
//             }
//         } finally {
//             values.recycle();
//         }
//     }
// 
//     TypedArray obtainAttributes(Context context, AttributeSet attributeSet) {
//         //TODO: instead of always passing 0 here for defStyleAttr : make it accept theme setted attribute
//         return context.getTheme().obtainStyledAttributes(attributeSet, styleable(), defStyleAttr(), 0);
//     }
// 
//     protected abstract int[] styleable();
// 
//     protected int defStyleAttr() {
//         return 0;
//     }
// 
//     /**
//      * The class for the given viewtype. Please be kind and just return the right class here :)
//      *
//      * @return The class/typetoken for T
//      */
//     protected abstract Class<T> clazz();
// 
//     /**
//      * This method will be called if a View of type T was inflated and it had one of the attributes
//      * specified by {@link AttrsDecorator#styleable()} set.
//      * @param view  The view object that is being decorated.
//      * @param typedArray A {@link TypedArray} for attributes.
//      *
//      */
//     protected abstract void apply(T view, TypedArray typedArray);
// 
// }
// 
// Path: decorators/src/main/java/com/mounacheikhna/decorators/utils/BlurUtils.java
// public class BlurUtils {
//     private static final float SCALE_RATIO = 5f;
//     private static final float DEFAULT_BLUR_RADIUS = 5.f;
// 
//     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
//     public static Bitmap blurBitmap(Bitmap bitmap, Context context){
//         int width = bitmap.getWidth(), height = bitmap.getHeight();
//         Bitmap b = Bitmap.createScaledBitmap(Bitmap.createScaledBitmap(bitmap,(int)(width/SCALE_RATIO), (int)(height/SCALE_RATIO), false), width, height, false);
//         return blurBitmap(b, DEFAULT_BLUR_RADIUS, context);
//     }
// 
// 
//     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
//     private static Bitmap blurBitmap(Bitmap src, float blurRadius, Context context) {
//         RenderScript rs = RenderScript.create(context);
//         Bitmap.Config conf = Bitmap.Config.ARGB_8888;
//         Bitmap blurredBitmap = Bitmap.createBitmap(src.getWidth(), src.getHeight(), conf);
// 
//         final Allocation input = Allocation.createFromBitmap(rs, src, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
//         final Allocation output = Allocation.createTyped(rs, input.getType());
// 
//         final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
//         script.setRadius(blurRadius);
//         script.setInput(input);
//         script.forEach(output);
//         output.copyTo(blurredBitmap);
//         return blurredBitmap;
//     }
// 
// }


import android.content.res.TypedArray;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.mounacheikhna.decor.AttrsDecorator;
import com.mounacheikhna.decorators.utils.BlurUtils;
package com.mounacheikhna.decorators;



/**
 * Created by cheikhna on 03/04/2015.
 */
public class BlurDecorator extends AttrsDecorator<View> {

    @Override
    protected int[] styleable() {
        return R.styleable.BlurDecorator;
    }

    @Override
    protected Class<View> clazz() {
        return View.class;
    }

    @Override
    protected void apply(View view, TypedArray typedArray) {
        boolean isBlur = typedArray.getBoolean(R.styleable.BlurDecorator_decorBlur, false);
        if(!isBlur || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) return;

        //i'm guessing this part here doesn't work because i'm using the same blur as ngAndroid and they are
        //doing their injection in a different point in the inflation
        ViewGroup parent = (ViewGroup) view.getParent();
        FrameLayout layout = new FrameLayout(view.getContext());
        layout.setLayoutParams(view.getLayoutParams());
        int index = parent.indexOfChild(view);
        parent.removeViewAt(index);
        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        view.setLayoutParams(layoutParams);
        layout.addView(view);
        parent.addView(layout, index);

        final ImageView imageView = new ImageView(view.getContext());
        imageView.setLayoutParams(layoutParams);
        imageView.setVisibility(View.GONE);
        layout.addView(imageView);

        view.setVisibility(View.GONE);
        view.setDrawingCacheEnabled(true);
// Path: decor/src/main/java/com/mounacheikhna/decor/AttrsDecorator.java
// public abstract class AttrsDecorator<T extends View> implements Decorator {
// 
//     TypedArray values;
// 
//     @Override
//     public void apply(View view, View parent, String name, Context context, AttributeSet attributeSet) {
//         if (!clazz().isAssignableFrom(view.getClass())) {
//             return;
//         }
// 
//         values = obtainAttributes(context, attributeSet);
//         if(values == null || values.length() == 0) return;
// 
//         try {
//             for (int i = 0; i < values.length(); i++) {
//                 TypedValue buf = new TypedValue();
//                 if (values.hasValue(i) && values.getValue(i, buf)) {
//                     apply((T) view, values);
//                     break;
//                 }
//             }
//         } finally {
//             values.recycle();
//         }
//     }
// 
//     TypedArray obtainAttributes(Context context, AttributeSet attributeSet) {
//         //TODO: instead of always passing 0 here for defStyleAttr : make it accept theme setted attribute
//         return context.getTheme().obtainStyledAttributes(attributeSet, styleable(), defStyleAttr(), 0);
//     }
// 
//     protected abstract int[] styleable();
// 
//     protected int defStyleAttr() {
//         return 0;
//     }
// 
//     /**
//      * The class for the given viewtype. Please be kind and just return the right class here :)
//      *
//      * @return The class/typetoken for T
//      */
//     protected abstract Class<T> clazz();
// 
//     /**
//      * This method will be called if a View of type T was inflated and it had one of the attributes
//      * specified by {@link AttrsDecorator#styleable()} set.
//      * @param view  The view object that is being decorated.
//      * @param typedArray A {@link TypedArray} for attributes.
//      *
//      */
//     protected abstract void apply(T view, TypedArray typedArray);
// 
// }
// 
// Path: decorators/src/main/java/com/mounacheikhna/decorators/utils/BlurUtils.java
// public class BlurUtils {
//     private static final float SCALE_RATIO = 5f;
//     private static final float DEFAULT_BLUR_RADIUS = 5.f;
// 
//     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
//     public static Bitmap blurBitmap(Bitmap bitmap, Context context){
//         int width = bitmap.getWidth(), height = bitmap.getHeight();
//         Bitmap b = Bitmap.createScaledBitmap(Bitmap.createScaledBitmap(bitmap,(int)(width/SCALE_RATIO), (int)(height/SCALE_RATIO), false), width, height, false);
//         return blurBitmap(b, DEFAULT_BLUR_RADIUS, context);
//     }
// 
// 
//     @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
//     private static Bitmap blurBitmap(Bitmap src, float blurRadius, Context context) {
//         RenderScript rs = RenderScript.create(context);
//         Bitmap.Config conf = Bitmap.Config.ARGB_8888;
//         Bitmap blurredBitmap = Bitmap.createBitmap(src.getWidth(), src.getHeight(), conf);
// 
//         final Allocation input = Allocation.createFromBitmap(rs, src, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
//         final Allocation output = Allocation.createTyped(rs, input.getType());
// 
//         final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
//         script.setRadius(blurRadius);
//         script.setInput(input);
//         script.forEach(output);
//         output.copyTo(blurredBitmap);
//         return blurredBitmap;
//     }
// 
// }


// Path: decorators/src/main/java/com/mounacheikhna/decorators/BlurDecorator.java
import android.content.res.TypedArray;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.mounacheikhna.decor.AttrsDecorator;
import com.mounacheikhna.decorators.utils.BlurUtils;

package com.mounacheikhna.decorators;



/**
 * Created by cheikhna on 03/04/2015.
 */
public class BlurDecorator extends AttrsDecorator<View> {

    @Override
    protected int[] styleable() {
        return R.styleable.BlurDecorator;
    }

    @Override
    protected Class<View> clazz() {
        return View.class;
    }

    @Override
    protected void apply(View view, TypedArray typedArray) {
        boolean isBlur = typedArray.getBoolean(R.styleable.BlurDecorator_decorBlur, false);
        if(!isBlur || Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) return;

        //i'm guessing this part here doesn't work because i'm using the same blur as ngAndroid and they are
        //doing their injection in a different point in the inflation
        ViewGroup parent = (ViewGroup) view.getParent();
        FrameLayout layout = new FrameLayout(view.getContext());
        layout.setLayoutParams(view.getLayoutParams());
        int index = parent.indexOfChild(view);
        parent.removeViewAt(index);
        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        view.setLayoutParams(layoutParams);
        layout.addView(view);
        parent.addView(layout, index);

        final ImageView imageView = new ImageView(view.getContext());
        imageView.setLayoutParams(layoutParams);
        imageView.setVisibility(View.GONE);
        layout.addView(imageView);

        view.setVisibility(View.GONE);
        view.setDrawingCacheEnabled(true);
        imageView.setImageBitmap(BlurUtils.blurBitmap(view.getDrawingCache(), view.getContext()));