package be.abyx.aurora;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.support.v4.content.res.ResourcesCompat;

/**
 * An Aurora based upon a blurry image whose hue is shifted to match the hue of a given color.
 *
 * @author Pieter Verschaffelt
 */
public class BlurryAurora implements AuroraType {
    private Context context;

    public BlurryAurora(Context context) {
        this.context = context;
    }

    @Override
    public Bitmap render(int width, int height, int colour) {
        BitmapDrawable drawable = (BitmapDrawable) ResourcesCompat.getDrawable(context.getResources(), R.drawable.fancy, null);
        Bitmap sourceBitmap = drawable.getBitmap();
        int[] pixels = new int[sourceBitmap.getHeight() * sourceBitmap.getWidth()];
        sourceBitmap.getPixels(pixels, 0, sourceBitmap.getWidth(), 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight());

        // We're going to use this pixel as a reference for the hue and to determine the amount of shift that should be applied to the hue.
        int referencePixel = pixels[0];

        float hueShift = getHueShift(pixels[0], colour);

        int[] outputPixels = new int[sourceBitmap.getHeight() * sourceBitmap.getWidth()];

        if (BuildConfig.DEBUG) {
            System.out.print("Progress 0.00%");
        }

        for (int i = 0; i < sourceBitmap.getHeight(); i++) {
            for (int j = 0; j < sourceBitmap.getWidth(); j++) {
                int pixel = pixels[i * sourceBitmap.getWidth() + j];
                float[] hsv = convertColorToHSV(pixel);
                hsv[0] = (hsv[0] + hueShift) % 360;
                outputPixels[i * sourceBitmap.getWidth() + j] = Color.HSVToColor(hsv);
            }

            if (BuildConfig.DEBUG) {
                double progress = ((double) i) / ((double) sourceBitmap.getHeight());
                System.out.print("\rProgress " + String.format("%.2f", progress));
            }
        }

        if (BuildConfig.DEBUG) {
            System.out.println("");
        }

        return Bitmap.createBitmap(outputPixels, sourceBitmap.getWidth(), sourceBitmap.getHeight(), Bitmap.Config.RGB_565);
    }

    /**
     * Calculate the amount of shift that should be applied to the referencePixel to match the
     * destination colour's hue.
     *
     * @param referencePixel Pixel whose hue should be matched to the destinationColour.
     * @param destinationColour The destinationColour that's used for determining the hue shift.
     * @return The difference in hue value between the referencePixel and the destinationColour.
     */
    private float getHueShift(int referencePixel, int destinationColour) {
        float[] referenceHSV = convertColorToHSV(referencePixel);
        float[] destinationHSV = convertColorToHSV(destinationColour);

        return destinationHSV[0] - referenceHSV[0];
    }

    private float[] convertColorToHSV(int colour) {
        float[] referenceHSV = new float[3];

        int referenceRed = Color.red(colour);
        int referenceGreen = Color.green(colour);
        int referenceBlue = Color.blue(colour);

        Color.RGBToHSV(referenceRed, referenceGreen, referenceBlue, referenceHSV);
        return referenceHSV;
    }
}

@@ -1263,58 +1263,22 @@
 int%5B
-sourceBitmap.getH
+h
 eight
-()
  * 
-sourceBitmap.getW
+w
 idth
-()
 %5D;%0A%0A
@@ -1401,32 +1401,14 @@
 i %3C 
-sourceBitmap.getH
+h
 eight
-()
 ; i+
@@ -1444,39 +1444,21 @@
  0; j %3C 
-sourceBitmap.getW
+w
 idth
-()
 ; j++) %7B
@@ -1497,39 +1497,21 @@
 els%5Bi * 
-sourceBitmap.getW
+w
 idth
-()
  + j%5D;%0A 
@@ -1650,39 +1650,21 @@
 els%5Bi * 
-sourceBitmap.getW
+w
 idth
-()
  + j%5D = 
@@ -1801,32 +1801,14 @@
 le) 
-sourceBitmap.getH
+h
 eight
-()
 );%0A 
@@ -1986,32 +1986,33 @@
 %22%22);%0A        %7D%0A%0A
+%0A
         return B
@@ -2048,57 +2048,21 @@
 ls, 
-sourceBitmap.getWidth(), sourceBitmap.getH
+width, h
 eight
-()
 , Bi

Debug progress print in BlurryAurora