/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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.
 */
package com.android.wallpaper.asset;

import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;

/**
 * Collection of static utility methods for decoding and processing Bitmaps.
 */
public class BitmapUtils {
    private static final float DEFAULT_CENTER_ALIGNMENT = 0.5f;

    // Suppress default constructor for noninstantiability.
    private BitmapUtils() {
        throw new AssertionError();
    }

    /**
     * Calculates the highest subsampling factor to scale the source image to the target view without
     * losing visible quality. Final result is based on powers of 2 because it should be set as
     * BitmapOptions#inSampleSize.
     *
     * @param srcWidth     Width of source image.
     * @param srcHeight    Height of source image.
     * @param targetWidth  Width of target view.
     * @param targetHeight Height of target view.
     * @return Highest subsampling factor as a power of 2.
     */
    public static int calculateInSampleSize(
            int srcWidth, int srcHeight, int targetWidth, int targetHeight) {
        int shift = 0;
        int halfHeight = srcHeight / 2;
        int halfWidth = srcWidth / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both the result
        // bitmap's height and width at least as large as the target height and width.
        while (((halfHeight >> shift) >= targetHeight) && ((halfWidth >> shift) >= targetWidth)) {
            shift++;
        }

        return 1 << shift;
    }

    /**
     * Generates a hash code for the given bitmap. Computation starts with a nonzero prime number,
     * then for the integer values of height, width, and a selection of pixel colors, multiplies the
     * result by 31 and adds said integer value. Multiply by 31 because it is prime and conveniently 1
     * less than 32 which is 2 ^ 5, allowing the VM to replace multiplication by a bit shift and
     * subtraction for performance.
     * <p>
     * This method should be called off the UI thread.
     */
    public static long generateHashCode(Bitmap bitmap) {
        long result = 17;
        if (bitmap == null) {
            return result;
        }
        int width = bitmap.getWidth();
        int height = bitmap.getHeight();

        result = 31 * result + width;
        result = 31 * result + height;

        // Traverse pixels exponentially so that hash code generation scales well with large images.
        for (int x = 0; x < width; x = x * 2 + 1) {
            for (int y = 0; y < height; y = y * 2 + 1) {
                result = 31 * result + bitmap.getPixel(x, y);
            }
        }

        return result;
    }

    /**
     * Calculates horizontal alignment of the rect within the supplied dimensions.
     *
     * @return A float value between 0 and 1 specifying horizontal alignment; 0 for left-aligned, 0.5
     * for horizontal center-aligned, and 1 for right-aligned.
     */
    public static float calculateHorizontalAlignment(Point dimensions, Rect rect) {
        int paddingLeft = rect.left;
        int paddingRight = dimensions.x - rect.right;
        int totalHorizontalPadding = paddingLeft + paddingRight;
        // Zero horizontal padding means that there is no room to crop horizontally so we just fall
        // back to a default center-alignment value.
        return (totalHorizontalPadding == 0)
                ? DEFAULT_CENTER_ALIGNMENT
                : paddingLeft / ((float) paddingLeft + paddingRight);
    }

    /**
     * Calculates vertical alignment of the rect within the supplied dimensions.
     *
     * @return A float value between 0 and 1 specifying vertical alignment; 0 for top-aligned, 0.5 for
     * vertical center-aligned, and 1 for bottom-aligned.
     */
    public static float calculateVerticalAlignment(Point dimensions, Rect rect) {
        int paddingTop = rect.top;
        int paddingBottom = dimensions.y - rect.bottom;
        int totalVerticalPadding = paddingTop + paddingBottom;
        // Zero vertical padding means that there is no room to crop vertically so we just fall back to
        // a default center-alignment value.
        return (totalVerticalPadding == 0)
                ? DEFAULT_CENTER_ALIGNMENT
                : paddingTop / ((float) paddingTop + paddingBottom);
    }
}
