/*
 * 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 android.util;

import android.app.ActivityThread;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.DrawableWrapper;
import android.graphics.drawable.LayerDrawable;

/**
 * Utility class to handle icon treatments (e.g., shadow generation) for the Launcher icons.
 * @hide
 */
public final class LauncherIcons {

    // Percent of actual icon size
    private static final float ICON_SIZE_BLUR_FACTOR = 0.5f/48;
    // Percent of actual icon size
    private static final float ICON_SIZE_KEY_SHADOW_DELTA_FACTOR = 1f/48;

    private static final int KEY_SHADOW_ALPHA = 61;
    private static final int AMBIENT_SHADOW_ALPHA = 30;

    private final SparseArray<Bitmap> mShadowCache = new SparseArray<>();
    private final int mIconSize;
    private final Resources mRes;

    public LauncherIcons(Context context) {
        mRes = context.getResources();
        mIconSize = mRes.getDimensionPixelSize(android.R.dimen.app_icon_size);
    }

    public Drawable wrapIconDrawableWithShadow(Drawable drawable) {
        if (!(drawable instanceof AdaptiveIconDrawable)) {
            return drawable;
        }
        Bitmap shadow = getShadowBitmap((AdaptiveIconDrawable) drawable);
        return new ShadowDrawable(shadow, drawable);
    }

    private Bitmap getShadowBitmap(AdaptiveIconDrawable d) {
        int shadowSize = Math.max(mIconSize, d.getIntrinsicHeight());
        synchronized (mShadowCache) {
            Bitmap shadow = mShadowCache.get(shadowSize);
            if (shadow != null) {
                return shadow;
            }
        }

        d.setBounds(0, 0, shadowSize, shadowSize);

        float blur = ICON_SIZE_BLUR_FACTOR * shadowSize;
        float keyShadowDistance = ICON_SIZE_KEY_SHADOW_DELTA_FACTOR * shadowSize;

        int bitmapSize = (int) (shadowSize + 2 * blur + keyShadowDistance);
        Bitmap shadow = Bitmap.createBitmap(bitmapSize, bitmapSize, Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(shadow);
        canvas.translate(blur + keyShadowDistance / 2, blur);

        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.TRANSPARENT);

        // Draw ambient shadow
        paint.setShadowLayer(blur, 0, 0, AMBIENT_SHADOW_ALPHA << 24);
        canvas.drawPath(d.getIconMask(), paint);

        // Draw key shadow
        canvas.translate(0, keyShadowDistance);
        paint.setShadowLayer(blur, 0, 0, KEY_SHADOW_ALPHA << 24);
        canvas.drawPath(d.getIconMask(), paint);

        canvas.setBitmap(null);
        synchronized (mShadowCache) {
            mShadowCache.put(shadowSize, shadow);
        }
        return shadow;
    }

    public Drawable getBadgeDrawable(int foregroundRes, int backgroundColor) {
        return getBadgedDrawable(null, foregroundRes, backgroundColor);
    }

    public Drawable getBadgedDrawable(Drawable base, int foregroundRes, int backgroundColor) {
        Resources overlayableRes =
                ActivityThread.currentActivityThread().getApplication().getResources();

        // ic_corp_icon_badge_shadow is not work-profile-specific.
        Drawable badgeShadow = overlayableRes.getDrawable(
                com.android.internal.R.drawable.ic_corp_icon_badge_shadow);

        // ic_corp_icon_badge_color is not work-profile-specific.
        Drawable badgeColor = overlayableRes.getDrawable(
                com.android.internal.R.drawable.ic_corp_icon_badge_color)
                .getConstantState().newDrawable().mutate();

        Drawable badgeForeground = overlayableRes.getDrawable(foregroundRes);
        badgeForeground.setTint(backgroundColor);

        Drawable[] drawables = base == null
                ? new Drawable[] {badgeShadow, badgeColor, badgeForeground }
                : new Drawable[] {base, badgeShadow, badgeColor, badgeForeground };
        return new LayerDrawable(drawables);
    }

    /**
     * A drawable which draws a shadow bitmap behind a drawable
     */
    private static class ShadowDrawable extends DrawableWrapper {

        final MyConstantState mState;

        public ShadowDrawable(Bitmap shadow, Drawable dr) {
            super(dr);
            mState = new MyConstantState(shadow, dr.getConstantState());
        }

        ShadowDrawable(MyConstantState state) {
            super(state.mChildState.newDrawable());
            mState = state;
        }

        @Override
        public ConstantState getConstantState() {
            return mState;
        }

        @Override
        public void draw(Canvas canvas) {
            Rect bounds = getBounds();
            canvas.drawBitmap(mState.mShadow, null, bounds, mState.mPaint);
            canvas.save();
            // Ratio of child drawable size to shadow bitmap size
            float factor = 1 / (1 + 2 * ICON_SIZE_BLUR_FACTOR + ICON_SIZE_KEY_SHADOW_DELTA_FACTOR);

            canvas.translate(
                    bounds.width() * factor *
                            (ICON_SIZE_BLUR_FACTOR + ICON_SIZE_KEY_SHADOW_DELTA_FACTOR / 2),
                    bounds.height() * factor * ICON_SIZE_BLUR_FACTOR);
            canvas.scale(factor, factor);
            super.draw(canvas);
            canvas.restore();
        }

        private static class MyConstantState extends ConstantState {

            final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
            final Bitmap mShadow;
            final ConstantState mChildState;

            MyConstantState(Bitmap shadow, ConstantState childState) {
                mShadow = shadow;
                mChildState = childState;
            }

            @Override
            public Drawable newDrawable() {
                return new ShadowDrawable(this);
            }

            @Override
            public int getChangingConfigurations() {
                return mChildState.getChangingConfigurations();
            }
        }
    }
}
