package com.iangclifton.woodworkingtools;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.support.annotation.DrawableRes;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;


/**
 * FrameLayout that displays a square image and a caption over it.
 *
 * The text for the caption has a blurred background to make it more readable.
 *
 * @author Ian G. Clifton
 */
public class CaptionedImageView extends FrameLayout implements View.OnLayoutChangeListener {

    private Drawable mDrawable;
    private TextView mTextView;
    private SquareImageView mImageView;
    private int mScrimColor;

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

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

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

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

    public SquareImageView getImageView() {
        return mImageView;
    }

    public TextView getTextView() {
        return mTextView;
    }

    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
        if (v.getVisibility() != VISIBLE) {
            return;
        }
        final int height = bottom - top;
        final int width = right - left;
        if (height == 0 || width == 0) {
            return;
        }
        updateBlur();
    }

    public void setImageResource(@DrawableRes int drawableResourceId) {
        mDrawable = getResources().getDrawable(drawableResourceId);
        mImageView.setImageResource(drawableResourceId);
        updateBlur();
    }

    private void updateBlur() {
        if (!(mDrawable instanceof BitmapDrawable)) {
            return;
        }
        final int textViewHeight = mTextView.getHeight();
        if (textViewHeight == 0) {
            return;
        }

        // Determine the size of the TextView compared to the height of the ImageView
        final float ratio = (float) textViewHeight / mImageView.getHeight();

        // Get the Bitmap
        final BitmapDrawable bitmapDrawable = (BitmapDrawable) mDrawable;
        final Bitmap originalBitmap = bitmapDrawable.getBitmap();

        // Calculate the height as a ratio of the Bitmap
        int height = (int) (ratio * originalBitmap.getHeight());

        // The y position is the number of pixels height represents from the bottom of the Bitmap
        final int y = originalBitmap.getHeight() - height;

        final Bitmap portionToBlur = Bitmap.createBitmap(originalBitmap, 0, y, originalBitmap.getWidth(), height);
        final Bitmap blurredBitmap = portionToBlur.copy(Bitmap.Config.ARGB_8888, true);

        // Use RenderScript to blur the pixels
        RenderScript rs = RenderScript.create(getContext());
        ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        Allocation tmpIn = Allocation.createFromBitmap(rs, portionToBlur);
        Allocation tmpOut = Allocation.createFromBitmap(rs, blurredBitmap);
        theIntrinsic.setRadius(25f);
        theIntrinsic.setInput(tmpIn);
        theIntrinsic.forEach(tmpOut);
        tmpOut.copyTo(blurredBitmap);
        new Canvas(blurredBitmap).drawColor(mScrimColor);

        // Create the new bitmap using the old plus the blurred portion and display itwww
        final Bitmap newBitmap = originalBitmap.copy(Bitmap.Config.ARGB_8888, true);
        final Canvas canvas = new Canvas(newBitmap);
        canvas.drawBitmap(blurredBitmap, 0, y, new Paint());
        mImageView.setImageBitmap(newBitmap);
    }

    private void init(Context context) {
        inflate(context, R.layout.captioned_image_view, this);
        mTextView = (TextView) findViewById(R.id.text);
        mImageView = (SquareImageView) findViewById(R.id.image);
        mScrimColor = getResources().getColor(R.color.grid_item_scrim);
        mTextView.addOnLayoutChangeListener(this);
    }
}