/*
 * 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;
    private final Context mContext;

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

    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(Drawable badgeForeground, int backgroundColor) {
        return getBadgedDrawable(null, badgeForeground, backgroundColor);
    }

    public Drawable getBadgedDrawable(
            Drawable base, Drawable badgeForeground, 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();

        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();
            }
        }
    }
}
