/*
 * Copyright (C) 2006 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.graphics.drawable;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BlendMode;
import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.ImageDecoder;
import android.graphics.Insets;
import android.graphics.NinePatch;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.LayoutDirection;
import android.util.TypedValue;

import com.android.internal.R;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.io.InputStream;

/**
 *
 * A resizeable bitmap, with stretchable areas that you define. This type of image
 * is defined in a .png file with a special format.
 *
 * <div class="special reference">
 * <h3>Developer Guides</h3>
 * <p>For more information about how to use a NinePatchDrawable, read the
 * <a href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">
 * Canvas and Drawables</a> developer guide. For information about creating a NinePatch image
 * file using the draw9patch tool, see the
 * <a href="{@docRoot}guide/developing/tools/draw9patch.html">Draw 9-patch</a> tool guide.</p></div>
 */
public class NinePatchDrawable extends Drawable {
    // dithering helps a lot, and is pretty cheap, so default is true
    private static final boolean DEFAULT_DITHER = false;

    /** Temporary rect used for density scaling. */
    private Rect mTempRect;

    @UnsupportedAppUsage
    private NinePatchState mNinePatchState;
    private BlendModeColorFilter mBlendModeFilter;
    private Rect mPadding;
    private Insets mOpticalInsets = Insets.NONE;
    private Rect mOutlineInsets;
    private float mOutlineRadius;
    private Paint mPaint;
    private boolean mMutated;

    private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;

    // These are scaled to match the target density.
    private int mBitmapWidth = -1;
    private int mBitmapHeight = -1;

    NinePatchDrawable() {
        mNinePatchState = new NinePatchState();
    }

    /**
     * Create drawable from raw nine-patch data, not dealing with density.
     *
     * @deprecated Use {@link #NinePatchDrawable(Resources, Bitmap, byte[], Rect, String)}
     *             to ensure that the drawable has correctly set its target density.
     */
    @Deprecated
    public NinePatchDrawable(Bitmap bitmap, byte[] chunk, Rect padding, String srcName) {
        this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), null);
    }

    /**
     * Create drawable from raw nine-patch data, setting initial target density
     * based on the display metrics of the resources.
     */
    public NinePatchDrawable(Resources res, Bitmap bitmap, byte[] chunk,
            Rect padding, String srcName) {
        this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding), res);
    }

    /**
     * Create drawable from raw nine-patch data, setting initial target density
     * based on the display metrics of the resources.
     *
     * @hide
     */
    public NinePatchDrawable(Resources res, Bitmap bitmap, byte[] chunk,
            Rect padding, Rect opticalInsets, String srcName) {
        this(new NinePatchState(new NinePatch(bitmap, chunk, srcName), padding, opticalInsets),
                res);
    }

    /**
     * Create drawable from existing nine-patch, not dealing with density.
     *
     * @deprecated Use {@link #NinePatchDrawable(Resources, NinePatch)}
     *             to ensure that the drawable has correctly set its target
     *             density.
     */
    @Deprecated
    public NinePatchDrawable(@NonNull NinePatch patch) {
        this(new NinePatchState(patch, new Rect()), null);
    }

    /**
     * Create drawable from existing nine-patch, setting initial target density
     * based on the display metrics of the resources.
     */
    public NinePatchDrawable(@Nullable Resources res, @NonNull NinePatch patch) {
        this(new NinePatchState(patch, new Rect()), res);
    }

    /**
     * Set the density scale at which this drawable will be rendered. This
     * method assumes the drawable will be rendered at the same density as the
     * specified canvas.
     *
     * @param canvas The Canvas from which the density scale must be obtained.
     *
     * @see android.graphics.Bitmap#setDensity(int)
     * @see android.graphics.Bitmap#getDensity()
     */
    public void setTargetDensity(@NonNull Canvas canvas) {
        setTargetDensity(canvas.getDensity());
    }

    /**
     * Set the density scale at which this drawable will be rendered.
     *
     * @param metrics The DisplayMetrics indicating the density scale for this drawable.
     *
     * @see android.graphics.Bitmap#setDensity(int)
     * @see android.graphics.Bitmap#getDensity()
     */
    public void setTargetDensity(@NonNull DisplayMetrics metrics) {
        setTargetDensity(metrics.densityDpi);
    }

    /**
     * Set the density at which this drawable will be rendered.
     *
     * @param density The density scale for this drawable.
     *
     * @see android.graphics.Bitmap#setDensity(int)
     * @see android.graphics.Bitmap#getDensity()
     */
    public void setTargetDensity(int density) {
        if (density == 0) {
            density = DisplayMetrics.DENSITY_DEFAULT;
        }

        if (mTargetDensity != density) {
            mTargetDensity = density;

            computeBitmapSize();
            invalidateSelf();
        }
    }

    @Override
    public void draw(Canvas canvas) {
        final NinePatchState state = mNinePatchState;

        Rect bounds = getBounds();
        int restoreToCount = -1;

        final boolean clearColorFilter;
        if (mBlendModeFilter != null && getPaint().getColorFilter() == null) {
            mPaint.setColorFilter(mBlendModeFilter);
            clearColorFilter = true;
        } else {
            clearColorFilter = false;
        }

        final int restoreAlpha;
        if (state.mBaseAlpha != 1.0f) {
            restoreAlpha = getPaint().getAlpha();
            mPaint.setAlpha((int) (restoreAlpha * state.mBaseAlpha + 0.5f));
        } else {
            restoreAlpha = -1;
        }

        final boolean needsDensityScaling = canvas.getDensity() == 0
                && Bitmap.DENSITY_NONE != state.mNinePatch.getDensity();
        if (needsDensityScaling) {
            restoreToCount = restoreToCount >= 0 ? restoreToCount : canvas.save();

            // Apply density scaling.
            final float scale = mTargetDensity / (float) state.mNinePatch.getDensity();
            final float px = bounds.left;
            final float py = bounds.top;
            canvas.scale(scale, scale, px, py);

            if (mTempRect == null) {
                mTempRect = new Rect();
            }

            // Scale the bounds to match.
            final Rect scaledBounds = mTempRect;
            scaledBounds.left = bounds.left;
            scaledBounds.top = bounds.top;
            scaledBounds.right = bounds.left + Math.round(bounds.width() / scale);
            scaledBounds.bottom = bounds.top + Math.round(bounds.height() / scale);
            bounds = scaledBounds;
        }

        final boolean needsMirroring = needsMirroring();
        if (needsMirroring) {
            restoreToCount = restoreToCount >= 0 ? restoreToCount : canvas.save();

            // Mirror the 9patch.
            final float cx = (bounds.left + bounds.right) / 2.0f;
            final float cy = (bounds.top + bounds.bottom) / 2.0f;
            canvas.scale(-1.0f, 1.0f, cx, cy);
        }

        state.mNinePatch.draw(canvas, bounds, mPaint);

        if (restoreToCount >= 0) {
            canvas.restoreToCount(restoreToCount);
        }

        if (clearColorFilter) {
            mPaint.setColorFilter(null);
        }

        if (restoreAlpha >= 0) {
            mPaint.setAlpha(restoreAlpha);
        }
    }

    @Override
    public @Config int getChangingConfigurations() {
        return super.getChangingConfigurations() | mNinePatchState.getChangingConfigurations();
    }

    @Override
    public boolean getPadding(@NonNull Rect padding) {
        if (mPadding != null) {
            padding.set(mPadding);
            return (padding.left | padding.top | padding.right | padding.bottom) != 0;
        } else {
            return super.getPadding(padding);
        }
    }

    @Override
    public void getOutline(@NonNull Outline outline) {
        final Rect bounds = getBounds();
        if (bounds.isEmpty()) {
            return;
        }

        if (mNinePatchState != null && mOutlineInsets != null) {
            final NinePatch.InsetStruct insets =
                    mNinePatchState.mNinePatch.getBitmap().getNinePatchInsets();
            if (insets != null) {
                outline.setRoundRect(bounds.left + mOutlineInsets.left,
                        bounds.top + mOutlineInsets.top,
                        bounds.right - mOutlineInsets.right,
                        bounds.bottom - mOutlineInsets.bottom,
                        mOutlineRadius);
                outline.setAlpha(insets.outlineAlpha * (getAlpha() / 255.0f));
                return;
            }
        }

        super.getOutline(outline);
    }

    @Override
    public Insets getOpticalInsets() {
        final Insets opticalInsets = mOpticalInsets;
        if (needsMirroring()) {
            return Insets.of(opticalInsets.right, opticalInsets.top,
                    opticalInsets.left, opticalInsets.bottom);
        } else {
            return opticalInsets;
        }
    }

    @Override
    public void setAlpha(int alpha) {
        if (mPaint == null && alpha == 0xFF) {
            // Fast common case -- leave at normal alpha.
            return;
        }
        getPaint().setAlpha(alpha);
        invalidateSelf();
    }

    @Override
    public int getAlpha() {
        if (mPaint == null) {
            // Fast common case -- normal alpha.
            return 0xFF;
        }
        return getPaint().getAlpha();
    }

    @Override
    public void setColorFilter(@Nullable ColorFilter colorFilter) {
        if (mPaint == null && colorFilter == null) {
            // Fast common case -- leave at no color filter.
            return;
        }
        getPaint().setColorFilter(colorFilter);
        invalidateSelf();
    }

    @Override
    public void setTintList(@Nullable ColorStateList tint) {
        mNinePatchState.mTint = tint;
        mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, tint,
                mNinePatchState.mBlendMode);
        invalidateSelf();
    }

    @Override
    public void setTintBlendMode(@Nullable BlendMode blendMode) {
        mNinePatchState.mBlendMode = blendMode;
        mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, mNinePatchState.mTint,
                blendMode);
        invalidateSelf();
    }

    @Override
    public void setDither(boolean dither) {
        //noinspection PointlessBooleanExpression
        if (mPaint == null && dither == DEFAULT_DITHER) {
            // Fast common case -- leave at default dither.
            return;
        }

        getPaint().setDither(dither);
        invalidateSelf();
    }

    @Override
    public void setAutoMirrored(boolean mirrored) {
        mNinePatchState.mAutoMirrored = mirrored;
    }

    private boolean needsMirroring() {
        return isAutoMirrored() && getLayoutDirection() == LayoutDirection.RTL;
    }

    @Override
    public boolean isAutoMirrored() {
        return mNinePatchState.mAutoMirrored;
    }

    @Override
    public void setFilterBitmap(boolean filter) {
        getPaint().setFilterBitmap(filter);
        invalidateSelf();
    }

    @Override
    public boolean isFilterBitmap() {
        return mPaint != null && getPaint().isFilterBitmap();
    }

    @Override
    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
            throws XmlPullParserException, IOException {
        super.inflate(r, parser, attrs, theme);

        final TypedArray a = obtainAttributes(r, theme, attrs, R.styleable.NinePatchDrawable);
        updateStateFromTypedArray(a);
        a.recycle();

        updateLocalState(r);
    }

    /**
     * Updates the constant state from the values in the typed array.
     */
    private void updateStateFromTypedArray(@NonNull TypedArray a) throws XmlPullParserException {
        final Resources r = a.getResources();
        final NinePatchState state = mNinePatchState;

        // Account for any configuration changes.
        state.mChangingConfigurations |= a.getChangingConfigurations();

        // Extract the theme attributes, if any.
        state.mThemeAttrs = a.extractThemeAttrs();

        state.mDither = a.getBoolean(R.styleable.NinePatchDrawable_dither, state.mDither);

        final int srcResId = a.getResourceId(R.styleable.NinePatchDrawable_src, 0);
        if (srcResId != 0) {
            final Rect padding = new Rect();
            final Rect opticalInsets = new Rect();
            Bitmap bitmap = null;

            try {
                final TypedValue value = new TypedValue();
                final InputStream is = r.openRawResource(srcResId, value);

                int density = Bitmap.DENSITY_NONE;
                if (value.density == TypedValue.DENSITY_DEFAULT) {
                    density = DisplayMetrics.DENSITY_DEFAULT;
                } else if (value.density != TypedValue.DENSITY_NONE) {
                    density = value.density;
                }
                ImageDecoder.Source source = ImageDecoder.createSource(r, is, density);
                bitmap = ImageDecoder.decodeBitmap(source, (decoder, info, src) -> {
                    decoder.setOutPaddingRect(padding);
                    decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE);
                });

                is.close();
            } catch (IOException e) {
                // Ignore
            }

            if (bitmap == null) {
                throw new XmlPullParserException(a.getPositionDescription() +
                        ": <nine-patch> requires a valid src attribute");
            } else if (bitmap.getNinePatchChunk() == null) {
                throw new XmlPullParserException(a.getPositionDescription() +
                        ": <nine-patch> requires a valid 9-patch source image");
            }

            bitmap.getOpticalInsets(opticalInsets);

            state.mNinePatch = new NinePatch(bitmap, bitmap.getNinePatchChunk());
            state.mPadding = padding;
            state.mOpticalInsets = Insets.of(opticalInsets);
        }

        state.mAutoMirrored = a.getBoolean(
                R.styleable.NinePatchDrawable_autoMirrored, state.mAutoMirrored);
        state.mBaseAlpha = a.getFloat(R.styleable.NinePatchDrawable_alpha, state.mBaseAlpha);

        final int tintMode = a.getInt(R.styleable.NinePatchDrawable_tintMode, -1);
        if (tintMode != -1) {
            state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
        }

        final ColorStateList tint = a.getColorStateList(R.styleable.NinePatchDrawable_tint);
        if (tint != null) {
            state.mTint = tint;
        }
    }

    @Override
    public void applyTheme(@NonNull Theme t) {
        super.applyTheme(t);

        final NinePatchState state = mNinePatchState;
        if (state == null) {
            return;
        }

        if (state.mThemeAttrs != null) {
            final TypedArray a = t.resolveAttributes(
                    state.mThemeAttrs, R.styleable.NinePatchDrawable);
            try {
                updateStateFromTypedArray(a);
            } catch (XmlPullParserException e) {
                rethrowAsRuntimeException(e);
            } finally {
                a.recycle();
            }
        }

        if (state.mTint != null && state.mTint.canApplyTheme()) {
            state.mTint = state.mTint.obtainForTheme(t);
        }

        updateLocalState(t.getResources());
    }

    @Override
    public boolean canApplyTheme() {
        return mNinePatchState != null && mNinePatchState.canApplyTheme();
    }

    @NonNull
    public Paint getPaint() {
        if (mPaint == null) {
            mPaint = new Paint();
            mPaint.setDither(DEFAULT_DITHER);
        }
        return mPaint;
    }

    @Override
    public int getIntrinsicWidth() {
        return mBitmapWidth;
    }

    @Override
    public int getIntrinsicHeight() {
        return mBitmapHeight;
    }

    @Override
    public int getOpacity() {
        return mNinePatchState.mNinePatch.hasAlpha()
                || (mPaint != null && mPaint.getAlpha() < 255) ?
                        PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE;
    }

    @Override
    public Region getTransparentRegion() {
        return mNinePatchState.mNinePatch.getTransparentRegion(getBounds());
    }

    @Override
    public ConstantState getConstantState() {
        mNinePatchState.mChangingConfigurations = getChangingConfigurations();
        return mNinePatchState;
    }

    @Override
    public Drawable mutate() {
        if (!mMutated && super.mutate() == this) {
            mNinePatchState = new NinePatchState(mNinePatchState);
            mMutated = true;
        }
        return this;
    }

    /**
     * @hide
     */
    public void clearMutated() {
        super.clearMutated();
        mMutated = false;
    }

    @Override
    protected boolean onStateChange(int[] stateSet) {
        final NinePatchState state = mNinePatchState;
        if (state.mTint != null && state.mBlendMode != null) {
            mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, state.mTint,
                    state.mBlendMode);
            return true;
        }

        return false;
    }

    @Override
    public boolean isStateful() {
        final NinePatchState s = mNinePatchState;
        return super.isStateful() || (s.mTint != null && s.mTint.isStateful());
    }

    /** @hide */
    @Override
    public boolean hasFocusStateSpecified() {
        return mNinePatchState.mTint != null && mNinePatchState.mTint.hasFocusStateSpecified();
    }

    final static class NinePatchState extends ConstantState {
        @Config int mChangingConfigurations;

        // Values loaded during inflation.
        @UnsupportedAppUsage
        NinePatch mNinePatch = null;
        ColorStateList mTint = null;
        BlendMode mBlendMode = DEFAULT_BLEND_MODE;
        Rect mPadding = null;
        Insets mOpticalInsets = Insets.NONE;
        float mBaseAlpha = 1.0f;
        boolean mDither = DEFAULT_DITHER;
        boolean mAutoMirrored = false;

        int[] mThemeAttrs;

        NinePatchState() {
            // Empty constructor.
        }

        NinePatchState(@NonNull NinePatch ninePatch, @Nullable Rect padding) {
            this(ninePatch, padding, null, DEFAULT_DITHER, false);
        }

        NinePatchState(@NonNull NinePatch ninePatch, @Nullable Rect padding,
                @Nullable Rect opticalInsets) {
            this(ninePatch, padding, opticalInsets, DEFAULT_DITHER, false);
        }

        NinePatchState(@NonNull NinePatch ninePatch, @Nullable Rect padding,
                @Nullable Rect opticalInsets, boolean dither, boolean autoMirror) {
            mNinePatch = ninePatch;
            mPadding = padding;
            mOpticalInsets = Insets.of(opticalInsets);
            mDither = dither;
            mAutoMirrored = autoMirror;
        }

        NinePatchState(@NonNull NinePatchState orig) {
            mChangingConfigurations = orig.mChangingConfigurations;
            mNinePatch = orig.mNinePatch;
            mTint = orig.mTint;
            mBlendMode = orig.mBlendMode;
            mPadding = orig.mPadding;
            mOpticalInsets = orig.mOpticalInsets;
            mBaseAlpha = orig.mBaseAlpha;
            mDither = orig.mDither;
            mAutoMirrored = orig.mAutoMirrored;
            mThemeAttrs = orig.mThemeAttrs;
        }

        @Override
        public boolean canApplyTheme() {
            return mThemeAttrs != null
                    || (mTint != null && mTint.canApplyTheme())
                    || super.canApplyTheme();
        }

        @Override
        public Drawable newDrawable() {
            return new NinePatchDrawable(this, null);
        }

        @Override
        public Drawable newDrawable(Resources res) {
            return new NinePatchDrawable(this, res);
        }

        @Override
        public @Config int getChangingConfigurations() {
            return mChangingConfigurations
                    | (mTint != null ? mTint.getChangingConfigurations() : 0);
        }
    }

    private void computeBitmapSize() {
        final NinePatch ninePatch = mNinePatchState.mNinePatch;
        if (ninePatch == null) {
            return;
        }

        final int targetDensity = mTargetDensity;
        final int sourceDensity = ninePatch.getDensity() == Bitmap.DENSITY_NONE ?
            targetDensity : ninePatch.getDensity();

        final Insets sourceOpticalInsets = mNinePatchState.mOpticalInsets;
        if (sourceOpticalInsets != Insets.NONE) {
            final int left = Drawable.scaleFromDensity(
                    sourceOpticalInsets.left, sourceDensity, targetDensity, true);
            final int top = Drawable.scaleFromDensity(
                    sourceOpticalInsets.top, sourceDensity, targetDensity, true);
            final int right = Drawable.scaleFromDensity(
                    sourceOpticalInsets.right, sourceDensity, targetDensity, true);
            final int bottom = Drawable.scaleFromDensity(
                    sourceOpticalInsets.bottom, sourceDensity, targetDensity, true);
            mOpticalInsets = Insets.of(left, top, right, bottom);
        } else {
            mOpticalInsets = Insets.NONE;
        }

        final Rect sourcePadding = mNinePatchState.mPadding;
        if (sourcePadding != null) {
            if (mPadding == null) {
                mPadding = new Rect();
            }
            mPadding.left = Drawable.scaleFromDensity(
                    sourcePadding.left, sourceDensity, targetDensity, true);
            mPadding.top = Drawable.scaleFromDensity(
                    sourcePadding.top, sourceDensity, targetDensity, true);
            mPadding.right = Drawable.scaleFromDensity(
                    sourcePadding.right, sourceDensity, targetDensity, true);
            mPadding.bottom = Drawable.scaleFromDensity(
                    sourcePadding.bottom, sourceDensity, targetDensity, true);
        } else {
            mPadding = null;
        }

        mBitmapHeight = Drawable.scaleFromDensity(
                ninePatch.getHeight(), sourceDensity, targetDensity, true);
        mBitmapWidth = Drawable.scaleFromDensity(
                ninePatch.getWidth(), sourceDensity, targetDensity, true);

        final NinePatch.InsetStruct insets = ninePatch.getBitmap().getNinePatchInsets();
        if (insets != null) {
            Rect outlineRect = insets.outlineRect;
            mOutlineInsets = NinePatch.InsetStruct.scaleInsets(outlineRect.left, outlineRect.top,
                    outlineRect.right, outlineRect.bottom, targetDensity / (float) sourceDensity);
            mOutlineRadius = Drawable.scaleFromDensity(
                    insets.outlineRadius, sourceDensity, targetDensity);
        } else {
            mOutlineInsets = null;
        }
    }

    /**
     * The one constructor to rule them all. This is called by all public
     * constructors to set the state and initialize local properties.
     *
     * @param state constant state to assign to the new drawable
     */
    private NinePatchDrawable(@NonNull NinePatchState state, @Nullable Resources res) {
        mNinePatchState = state;

        updateLocalState(res);
    }

    /**
     * Initializes local dynamic properties from state.
     */
    private void updateLocalState(@Nullable Resources res) {
        final NinePatchState state = mNinePatchState;

        // If we can, avoid calling any methods that initialize Paint.
        if (state.mDither != DEFAULT_DITHER) {
            setDither(state.mDither);
        }

        // The nine-patch may have been created without a Resources object, in
        // which case we should try to match the density of the nine patch (if
        // available).
        if (res == null && state.mNinePatch != null) {
            mTargetDensity = state.mNinePatch.getDensity();
        } else {
            mTargetDensity = Drawable.resolveDensity(res, mTargetDensity);
        }
        mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, state.mTint, state.mBlendMode);
        computeBitmapSize();
    }
}
