/*
 * Copyright (C) 2014 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 androidx.appcompat.widget;

import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
import static androidx.appcompat.content.res.AppCompatResources.getColorStateList;
import static androidx.appcompat.widget.ThemeUtils.getDisabledThemeAttrColor;
import static androidx.appcompat.widget.ThemeUtils.getThemeAttrColor;
import static androidx.appcompat.widget.ThemeUtils.getThemeAttrColorStateList;
import static androidx.core.graphics.ColorUtils.compositeColors;

import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.util.Log;

import androidx.annotation.ColorInt;
import androidx.annotation.DimenRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.appcompat.R;
import androidx.core.graphics.drawable.DrawableCompat;

/**
 * @hide
 */
@RestrictTo(LIBRARY_GROUP_PREFIX)
public final class AppCompatDrawableManager {
    private static final String TAG = "AppCompatDrawableManag";
    private static final boolean DEBUG = false;
    private static final PorterDuff.Mode DEFAULT_MODE = PorterDuff.Mode.SRC_IN;

    private static AppCompatDrawableManager INSTANCE;

    public static synchronized void preload() {
        if (INSTANCE == null) {
            INSTANCE = new AppCompatDrawableManager();
            INSTANCE.mResourceManager = ResourceManagerInternal.get();
            INSTANCE.mResourceManager.setHooks(new ResourceManagerInternal.ResourceManagerHooks() {
                /**
                 * Drawables which should be tinted with the value of
                 * {@code R.attr.colorControlNormal}, using the default mode using a raw color
                 * filter.
                 */
                private final int[] COLORFILTER_TINT_COLOR_CONTROL_NORMAL = {
                        R.drawable.abc_textfield_search_default_mtrl_alpha,
                        R.drawable.abc_textfield_default_mtrl_alpha,
                        R.drawable.abc_ab_share_pack_mtrl_alpha
                };

                /**
                 * Drawables which should be tinted with the value of
                 * {@code R.attr.colorControlNormal}, using {@link DrawableCompat}'s tinting
                 * functionality.
                 */
                private final int[] TINT_COLOR_CONTROL_NORMAL = {
                        R.drawable.abc_ic_commit_search_api_mtrl_alpha,
                        R.drawable.abc_seekbar_tick_mark_material,
                        R.drawable.abc_ic_menu_share_mtrl_alpha,
                        R.drawable.abc_ic_menu_copy_mtrl_am_alpha,
                        R.drawable.abc_ic_menu_cut_mtrl_alpha,
                        R.drawable.abc_ic_menu_selectall_mtrl_alpha,
                        R.drawable.abc_ic_menu_paste_mtrl_am_alpha
                };

                /**
                 * Drawables which should be tinted with the value of
                 * {@code R.attr.colorControlActivated}, using a color filter.
                 */
                private final int[] COLORFILTER_COLOR_CONTROL_ACTIVATED = {
                        R.drawable.abc_textfield_activated_mtrl_alpha,
                        R.drawable.abc_textfield_search_activated_mtrl_alpha,
                        R.drawable.abc_cab_background_top_mtrl_alpha,
                        R.drawable.abc_text_cursor_material,
                        R.drawable.abc_text_select_handle_left_mtrl,
                        R.drawable.abc_text_select_handle_middle_mtrl,
                        R.drawable.abc_text_select_handle_right_mtrl
                };

                /**
                 * Drawables which should be tinted with the value of
                 * {@code android.R.attr.colorBackground}, using the
                 * {@link android.graphics.PorterDuff.Mode#MULTIPLY} mode and a color filter.
                 */
                private final int[] COLORFILTER_COLOR_BACKGROUND_MULTIPLY = {
                        R.drawable.abc_popup_background_mtrl_mult,
                        R.drawable.abc_cab_background_internal_bg,
                        R.drawable.abc_menu_hardkey_panel_mtrl_mult
                };

                /**
                 * Drawables which should be tinted using a state list containing values of
                 * {@code R.attr.colorControlNormal} and {@code R.attr.colorControlActivated}
                 */
                private final int[] TINT_COLOR_CONTROL_STATE_LIST = {
                        R.drawable.abc_tab_indicator_material,
                        R.drawable.abc_textfield_search_material
                };

                /**
                 * Drawables which should be tinted using a state list containing values of
                 * {@code R.attr.colorControlNormal} and {@code R.attr.colorControlActivated}
                 * for the checked state.
                 */
                private final int[] TINT_CHECKABLE_BUTTON_LIST = {
                        R.drawable.abc_btn_check_material,
                        R.drawable.abc_btn_radio_material,
                        R.drawable.abc_btn_check_material_anim,
                        R.drawable.abc_btn_radio_material_anim
                };

                private ColorStateList createDefaultButtonColorStateList(@NonNull Context context) {
                    return createButtonColorStateList(context,
                            getThemeAttrColor(context, R.attr.colorButtonNormal));
                }

                private ColorStateList createBorderlessButtonColorStateList(
                        @NonNull Context context) {
                    // We ignore the custom tint for borderless buttons
                    return createButtonColorStateList(context, Color.TRANSPARENT);
                }

                private ColorStateList createColoredButtonColorStateList(
                        @NonNull Context context) {
                    return createButtonColorStateList(context,
                            getThemeAttrColor(context, R.attr.colorAccent));
                }

                private ColorStateList createButtonColorStateList(@NonNull final Context context,
                        @ColorInt final int baseColor) {
                    final int[][] states = new int[4][];
                    final int[] colors = new int[4];
                    int i = 0;

                    final int colorControlHighlight = getThemeAttrColor(context,
                            R.attr.colorControlHighlight);
                    final int disabledColor = getDisabledThemeAttrColor(context,
                            R.attr.colorButtonNormal);

                    // Disabled state
                    states[i] = ThemeUtils.DISABLED_STATE_SET;
                    colors[i] = disabledColor;
                    i++;

                    states[i] = ThemeUtils.PRESSED_STATE_SET;
                    colors[i] = compositeColors(colorControlHighlight, baseColor);
                    i++;

                    states[i] = ThemeUtils.FOCUSED_STATE_SET;
                    colors[i] = compositeColors(colorControlHighlight, baseColor);
                    i++;

                    // Default enabled state
                    states[i] = ThemeUtils.EMPTY_STATE_SET;
                    colors[i] = baseColor;
                    i++;

                    return new ColorStateList(states, colors);
                }

                private ColorStateList createSwitchThumbColorStateList(Context context) {
                    final int[][] states = new int[3][];
                    final int[] colors = new int[3];
                    int i = 0;

                    final ColorStateList thumbColor = getThemeAttrColorStateList(context,
                            R.attr.colorSwitchThumbNormal);

                    if (thumbColor != null && thumbColor.isStateful()) {
                        // If colorSwitchThumbNormal is a valid ColorStateList, extract the
                        // default and disabled colors from it

                        // Disabled state
                        states[i] = ThemeUtils.DISABLED_STATE_SET;
                        colors[i] = thumbColor.getColorForState(states[i], 0);
                        i++;

                        states[i] = ThemeUtils.CHECKED_STATE_SET;
                        colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated);
                        i++;

                        // Default enabled state
                        states[i] = ThemeUtils.EMPTY_STATE_SET;
                        colors[i] = thumbColor.getDefaultColor();
                        i++;
                    } else {
                        // Else we'll use an approximation using the default disabled alpha

                        // Disabled state
                        states[i] = ThemeUtils.DISABLED_STATE_SET;
                        colors[i] = getDisabledThemeAttrColor(context,
                                R.attr.colorSwitchThumbNormal);
                        i++;

                        states[i] = ThemeUtils.CHECKED_STATE_SET;
                        colors[i] = getThemeAttrColor(context, R.attr.colorControlActivated);
                        i++;

                        // Default enabled state
                        states[i] = ThemeUtils.EMPTY_STATE_SET;
                        colors[i] = getThemeAttrColor(context, R.attr.colorSwitchThumbNormal);
                        i++;
                    }

                    return new ColorStateList(states, colors);
                }

                @Override
                public Drawable createDrawableFor(@NonNull ResourceManagerInternal resourceManager,
                        @NonNull Context context, int resId) {
                    if (resId == R.drawable.abc_cab_background_top_material) {
                        return new LayerDrawable(new Drawable[]{
                                resourceManager.getDrawable(context,
                                        R.drawable.abc_cab_background_internal_bg),
                                resourceManager.getDrawable(context,
                                        R.drawable.abc_cab_background_top_mtrl_alpha)
                        });
                    }
                    if (resId == R.drawable.abc_ratingbar_material) {
                        return getRatingBarLayerDrawable(resourceManager, context,
                                R.dimen.abc_star_big);
                    }
                    if (resId == R.drawable.abc_ratingbar_indicator_material) {
                        return getRatingBarLayerDrawable(resourceManager, context,
                                R.dimen.abc_star_medium);
                    }
                    if (resId == R.drawable.abc_ratingbar_small_material) {
                        return getRatingBarLayerDrawable(resourceManager, context,
                                R.dimen.abc_star_small);
                    }
                    return null;
                }

                private LayerDrawable getRatingBarLayerDrawable(
                        @NonNull ResourceManagerInternal resourceManager,
                        @NonNull Context context, @DimenRes int dimenResId) {
                    int starSize = context.getResources().getDimensionPixelSize(dimenResId);

                    Drawable star = resourceManager.getDrawable(context,
                            R.drawable.abc_star_black_48dp);
                    Drawable halfStar = resourceManager.getDrawable(context,
                            R.drawable.abc_star_half_black_48dp);

                    BitmapDrawable starBitmapDrawable;
                    BitmapDrawable tiledStarBitmapDrawable;
                    if ((star instanceof BitmapDrawable) && (star.getIntrinsicWidth() == starSize)
                            && (star.getIntrinsicHeight() == starSize)) {
                        // no need for extra conversion
                        starBitmapDrawable = (BitmapDrawable) star;

                        tiledStarBitmapDrawable =
                                new BitmapDrawable(starBitmapDrawable.getBitmap());
                    } else {
                        Bitmap bitmapStar = Bitmap.createBitmap(starSize, starSize,
                                Bitmap.Config.ARGB_8888);
                        Canvas canvasStar = new Canvas(bitmapStar);
                        star.setBounds(0, 0, starSize, starSize);
                        star.draw(canvasStar);
                        starBitmapDrawable = new BitmapDrawable(bitmapStar);

                        tiledStarBitmapDrawable = new BitmapDrawable(bitmapStar);
                    }
                    tiledStarBitmapDrawable.setTileModeX(Shader.TileMode.REPEAT);

                    BitmapDrawable halfStarBitmapDrawable;
                    if ((halfStar instanceof BitmapDrawable)
                            && (halfStar.getIntrinsicWidth() == starSize)
                            && (halfStar.getIntrinsicHeight() == starSize)) {
                        // no need for extra conversion
                        halfStarBitmapDrawable = (BitmapDrawable) halfStar;
                    } else {
                        Bitmap bitmapHalfStar = Bitmap.createBitmap(starSize, starSize,
                                Bitmap.Config.ARGB_8888);
                        Canvas canvasHalfStar = new Canvas(bitmapHalfStar);
                        halfStar.setBounds(0, 0, starSize, starSize);
                        halfStar.draw(canvasHalfStar);
                        halfStarBitmapDrawable = new BitmapDrawable(bitmapHalfStar);
                    }

                    LayerDrawable result = new LayerDrawable(new Drawable[]{
                            starBitmapDrawable, halfStarBitmapDrawable, tiledStarBitmapDrawable
                    });
                    result.setId(0, android.R.id.background);
                    result.setId(1, android.R.id.secondaryProgress);
                    result.setId(2, android.R.id.progress);
                    return result;
                }

                private void setPorterDuffColorFilter(Drawable d, int color, PorterDuff.Mode mode) {
                    if (DrawableUtils.canSafelyMutateDrawable(d)) {
                        d = d.mutate();
                    }
                    d.setColorFilter(getPorterDuffColorFilter(color, mode == null ? DEFAULT_MODE
                            : mode));
                }

                @Override
                public boolean tintDrawable(@NonNull Context context, int resId,
                        @NonNull Drawable drawable) {
                    if (resId == R.drawable.abc_seekbar_track_material) {
                        LayerDrawable ld = (LayerDrawable) drawable;
                        setPorterDuffColorFilter(
                                ld.findDrawableByLayerId(android.R.id.background),
                                getThemeAttrColor(context, R.attr.colorControlNormal),
                                DEFAULT_MODE);
                        setPorterDuffColorFilter(
                                ld.findDrawableByLayerId(android.R.id.secondaryProgress),
                                getThemeAttrColor(context, R.attr.colorControlNormal),
                                DEFAULT_MODE);
                        setPorterDuffColorFilter(
                                ld.findDrawableByLayerId(android.R.id.progress),
                                getThemeAttrColor(context, R.attr.colorControlActivated),
                                DEFAULT_MODE);
                        return true;
                    } else if (resId == R.drawable.abc_ratingbar_material
                            || resId == R.drawable.abc_ratingbar_indicator_material
                            || resId == R.drawable.abc_ratingbar_small_material) {
                        LayerDrawable ld = (LayerDrawable) drawable;
                        setPorterDuffColorFilter(
                                ld.findDrawableByLayerId(android.R.id.background),
                                getDisabledThemeAttrColor(context, R.attr.colorControlNormal),
                                DEFAULT_MODE);
                        setPorterDuffColorFilter(
                                ld.findDrawableByLayerId(android.R.id.secondaryProgress),
                                getThemeAttrColor(context, R.attr.colorControlActivated),
                                DEFAULT_MODE);
                        setPorterDuffColorFilter(
                                ld.findDrawableByLayerId(android.R.id.progress),
                                getThemeAttrColor(context, R.attr.colorControlActivated),
                                DEFAULT_MODE);
                        return true;
                    }
                    return false;
                }

                private boolean arrayContains(int[] array, int value) {
                    for (int id : array) {
                        if (id == value) {
                            return true;
                        }
                    }
                    return false;
                }

                @Override
                public ColorStateList getTintListForDrawableRes(@NonNull Context context,
                        int resId) {
                    // ...if the cache did not contain a color state list, try and create one
                    if (resId == R.drawable.abc_edit_text_material) {
                        return getColorStateList(context, R.color.abc_tint_edittext);
                    } else if (resId == R.drawable.abc_switch_track_mtrl_alpha) {
                        return getColorStateList(context, R.color.abc_tint_switch_track);
                    } else if (resId == R.drawable.abc_switch_thumb_material) {
                        return createSwitchThumbColorStateList(context);
                    } else if (resId == R.drawable.abc_btn_default_mtrl_shape) {
                        return createDefaultButtonColorStateList(context);
                    } else if (resId == R.drawable.abc_btn_borderless_material) {
                        return createBorderlessButtonColorStateList(context);
                    } else if (resId == R.drawable.abc_btn_colored_material) {
                        return createColoredButtonColorStateList(context);
                    } else if (resId == R.drawable.abc_spinner_mtrl_am_alpha
                            || resId == R.drawable.abc_spinner_textfield_background_material) {
                        return getColorStateList(context, R.color.abc_tint_spinner);
                    } else if (arrayContains(TINT_COLOR_CONTROL_NORMAL, resId)) {
                        return getThemeAttrColorStateList(context, R.attr.colorControlNormal);
                    } else if (arrayContains(TINT_COLOR_CONTROL_STATE_LIST, resId)) {
                        return getColorStateList(context, R.color.abc_tint_default);
                    } else if (arrayContains(TINT_CHECKABLE_BUTTON_LIST, resId)) {
                        return getColorStateList(context, R.color.abc_tint_btn_checkable);
                    } else if (resId == R.drawable.abc_seekbar_thumb_material) {
                        return getColorStateList(context, R.color.abc_tint_seek_thumb);
                    }
                    return null;
                }

                @Override
                public boolean tintDrawableUsingColorFilter(@NonNull Context context,
                        int resId, @NonNull Drawable drawable) {
                    PorterDuff.Mode tintMode = DEFAULT_MODE;
                    boolean colorAttrSet = false;
                    int colorAttr = 0;
                    int alpha = -1;

                    if (arrayContains(COLORFILTER_TINT_COLOR_CONTROL_NORMAL, resId)) {
                        colorAttr = R.attr.colorControlNormal;
                        colorAttrSet = true;
                    } else if (arrayContains(COLORFILTER_COLOR_CONTROL_ACTIVATED, resId)) {
                        colorAttr = R.attr.colorControlActivated;
                        colorAttrSet = true;
                    } else if (arrayContains(COLORFILTER_COLOR_BACKGROUND_MULTIPLY, resId)) {
                        colorAttr = android.R.attr.colorBackground;
                        colorAttrSet = true;
                        tintMode = PorterDuff.Mode.MULTIPLY;
                    } else if (resId == R.drawable.abc_list_divider_mtrl_alpha) {
                        colorAttr = android.R.attr.colorForeground;
                        colorAttrSet = true;
                        alpha = Math.round(0.16f * 255);
                    } else if (resId == R.drawable.abc_dialog_material_background) {
                        colorAttr = android.R.attr.colorBackground;
                        colorAttrSet = true;
                    }

                    if (colorAttrSet) {
                        if (DrawableUtils.canSafelyMutateDrawable(drawable)) {
                            drawable = drawable.mutate();
                        }

                        final int color = getThemeAttrColor(context, colorAttr);
                        drawable.setColorFilter(getPorterDuffColorFilter(color, tintMode));

                        if (alpha != -1) {
                            drawable.setAlpha(alpha);
                        }

                        if (DEBUG) {
                            Log.d(TAG, "[tintDrawableUsingColorFilter] Tinted "
                                    + context.getResources().getResourceName(resId)
                                    + " with color: #" + Integer.toHexString(color));
                        }
                        return true;
                    }
                    return false;
                }

                @Override
                public PorterDuff.Mode getTintModeForDrawableRes(int resId) {
                    PorterDuff.Mode mode = null;

                    if (resId == R.drawable.abc_switch_thumb_material) {
                        mode = PorterDuff.Mode.MULTIPLY;
                    }

                    return mode;
                }
            });
        }
    }

    /**
     * Returns the singleton instance of this class.
     */
    public static synchronized AppCompatDrawableManager get() {
        if (INSTANCE == null) {
            preload();
        }
        return INSTANCE;
    }

    private ResourceManagerInternal mResourceManager;

    public synchronized Drawable getDrawable(@NonNull Context context, @DrawableRes int resId) {
        return mResourceManager.getDrawable(context, resId);
    }

    synchronized Drawable getDrawable(@NonNull Context context, @DrawableRes int resId,
            boolean failIfNotKnown) {
        return mResourceManager.getDrawable(context, resId, failIfNotKnown);
    }

    public synchronized void onConfigurationChanged(@NonNull Context context) {
        mResourceManager.onConfigurationChanged(context);
    }

    synchronized Drawable onDrawableLoadedFromResources(@NonNull Context context,
            @NonNull VectorEnabledTintResources resources, @DrawableRes final int resId) {
        return mResourceManager.onDrawableLoadedFromResources(context, resources, resId);
    }

    boolean tintDrawableUsingColorFilter(@NonNull Context context,
            @DrawableRes final int resId, @NonNull Drawable drawable) {
        return mResourceManager.tintDrawableUsingColorFilter(context, resId, drawable);
    }

    synchronized ColorStateList getTintList(@NonNull Context context, @DrawableRes int resId) {
        return mResourceManager.getTintList(context, resId);
    }

    static void tintDrawable(Drawable drawable, TintInfo tint, int[] state) {
        ResourceManagerInternal.tintDrawable(drawable, tint, state);
    }

    public static synchronized PorterDuffColorFilter getPorterDuffColorFilter(
            int color, PorterDuff.Mode mode) {
        return ResourceManagerInternal.getPorterDuffColorFilter(color, mode);
    }
}
