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

import android.annotation.ColorInt;
import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;

import com.android.settingslib.R;

/**
 * Converts the user avatar icon to a circularly clipped one with an optional badge and frame
 */
public class UserIconDrawable extends Drawable implements Drawable.Callback {

    private Drawable mUserDrawable;
    private Bitmap mUserIcon;
    private Bitmap mBitmap; // baked representation. Required for transparent border around badge
    private final Paint mIconPaint = new Paint();
    private final Paint mPaint = new Paint();
    private final Matrix mIconMatrix = new Matrix();
    private float mIntrinsicRadius;
    private float mDisplayRadius;
    private float mPadding = 0;
    private int mSize = 0; // custom "intrinsic" size for this drawable if non-zero
    private boolean mInvalidated = true;
    private ColorStateList mTintColor = null;
    private PorterDuff.Mode mTintMode = PorterDuff.Mode.SRC_ATOP;

    private float mFrameWidth;
    private float mFramePadding;
    private ColorStateList mFrameColor = null;
    private Paint mFramePaint;

    private Drawable mBadge;
    private Paint mClearPaint;
    private float mBadgeRadius;
    private float mBadgeMargin;

    /**
     * Gets the system default managed-user badge as a drawable. This drawable is tint-able.
     * For badging purpose, consider
     * {@link android.content.pm.PackageManager#getUserBadgedDrawableForDensity(Drawable, UserHandle, Rect, int)}.
     *
     * @param context
     * @return drawable containing just the badge
     */
    public static Drawable getManagedUserDrawable(Context context) {
        return getDrawableForDisplayDensity
                (context, com.android.internal.R.drawable.ic_corp_user_badge);
    }

    private static Drawable getDrawableForDisplayDensity(
            Context context, @DrawableRes int drawable) {
        int density = context.getResources().getDisplayMetrics().densityDpi;
        return context.getResources().getDrawableForDensity(
                drawable, density, context.getTheme());
    }

    /**
     * Gets the preferred list-item size of this drawable.
     * @param context
     * @return size in pixels
     */
    public static int getSizeForList(Context context) {
        return (int) context.getResources().getDimension(R.dimen.circle_avatar_size);
    }

    public UserIconDrawable() {
        this(0);
    }

    /**
     * Use this constructor if the drawable is intended to be placed in listviews
     * @param intrinsicSize if 0, the intrinsic size will come from the icon itself
     */
    public UserIconDrawable(int intrinsicSize) {
        super();
        mIconPaint.setAntiAlias(true);
        mIconPaint.setFilterBitmap(true);
        mPaint.setFilterBitmap(true);
        mPaint.setAntiAlias(true);
        if (intrinsicSize > 0) {
            setBounds(0, 0, intrinsicSize, intrinsicSize);
            setIntrinsicSize(intrinsicSize);
        }
        setIcon(null);
    }

    public UserIconDrawable setIcon(Bitmap icon) {
        if (mUserDrawable != null) {
            mUserDrawable.setCallback(null);
            mUserDrawable = null;
        }
        mUserIcon = icon;
        if (mUserIcon == null) {
            mIconPaint.setShader(null);
            mBitmap = null;
        } else {
            mIconPaint.setShader(new BitmapShader(icon, Shader.TileMode.CLAMP,
                    Shader.TileMode.CLAMP));
        }
        onBoundsChange(getBounds());
        return this;
    }

    public UserIconDrawable setIconDrawable(Drawable icon) {
        if (mUserDrawable != null) {
            mUserDrawable.setCallback(null);
        }
        mUserIcon = null;
        mUserDrawable = icon;
        if (mUserDrawable == null) {
            mBitmap = null;
        } else {
            mUserDrawable.setCallback(this);
        }
        onBoundsChange(getBounds());
        return this;
    }

    public UserIconDrawable setBadge(Drawable badge) {
        mBadge = badge;
        if (mBadge != null) {
            if (mClearPaint == null) {
                mClearPaint = new Paint();
                mClearPaint.setAntiAlias(true);
                mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
                mClearPaint.setStyle(Paint.Style.FILL);
            }
            // update metrics
            onBoundsChange(getBounds());
        } else {
            invalidateSelf();
        }
        return this;
    }

    public UserIconDrawable setBadgeIfManagedUser(Context context, int userId) {
        Drawable badge = null;
        boolean isManaged = context.getSystemService(DevicePolicyManager.class)
                .getProfileOwnerAsUser(userId) != null;
        if (isManaged) {
            badge = getDrawableForDisplayDensity(
                    context, com.android.internal.R.drawable.ic_corp_badge_case);
        }
        return setBadge(badge);
    }

    public void setBadgeRadius(float radius) {
        mBadgeRadius = radius;
        onBoundsChange(getBounds());
    }

    public void setBadgeMargin(float margin) {
        mBadgeMargin = margin;
        onBoundsChange(getBounds());
    }

    /**
     * Sets global padding of icon/frame. Doesn't effect the badge.
     * @param padding
     */
    public void setPadding(float padding) {
        mPadding = padding;
        onBoundsChange(getBounds());
    }

    private void initFramePaint() {
        if (mFramePaint == null) {
            mFramePaint = new Paint();
            mFramePaint.setStyle(Paint.Style.STROKE);
            mFramePaint.setAntiAlias(true);
        }
    }

    public void setFrameWidth(float width) {
        initFramePaint();
        mFrameWidth = width;
        mFramePaint.setStrokeWidth(width);
        onBoundsChange(getBounds());
    }

    public void setFramePadding(float padding) {
        initFramePaint();
        mFramePadding = padding;
        onBoundsChange(getBounds());
    }

    public void setFrameColor(int color) {
        initFramePaint();
        mFramePaint.setColor(color);
        invalidateSelf();
    }

    public void setFrameColor(ColorStateList colorList) {
        initFramePaint();
        mFrameColor = colorList;
        invalidateSelf();
    }

    /**
     * This sets the "intrinsic" size of this drawable. Useful for views which use the drawable's
     * intrinsic size for layout. It is independent of the bounds.
     * @param size if 0, the intrinsic size will be set to the displayed icon's size
     */
    public void setIntrinsicSize(int size) {
        mSize = size;
    }

    @Override
    public void draw(Canvas canvas) {
        if (mInvalidated) {
            rebake();
        }
        if (mBitmap != null) {
            if (mTintColor == null) {
                mPaint.setColorFilter(null);
            } else {
                int color = mTintColor.getColorForState(getState(), mTintColor.getDefaultColor());
                if (shouldUpdateColorFilter(color, mTintMode)) {
                    mPaint.setColorFilter(new PorterDuffColorFilter(color, mTintMode));
                }
            }

            canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        }
    }

    private boolean shouldUpdateColorFilter(@ColorInt int color, PorterDuff.Mode mode) {
        ColorFilter colorFilter = mPaint.getColorFilter();
        if (colorFilter instanceof PorterDuffColorFilter) {
            PorterDuffColorFilter porterDuffColorFilter = (PorterDuffColorFilter) colorFilter;
            int currentColor = porterDuffColorFilter.getColor();
            PorterDuff.Mode currentMode = porterDuffColorFilter.getMode();
            return currentColor != color || currentMode != mode;
        } else {
            return true;
        }
    }

    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
        super.invalidateSelf();
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
    }

    @Override
    public void setTintList(ColorStateList tintList) {
        mTintColor = tintList;
        super.invalidateSelf();
    }

    @Override
    public void setTintMode(@NonNull PorterDuff.Mode mode) {
        mTintMode = mode;
        super.invalidateSelf();
    }

    @Override
    public ConstantState getConstantState() {
        return new BitmapDrawable(mBitmap).getConstantState();
    }

    /**
     * This 'bakes' the current state of this icon into a bitmap and removes/recycles the source
     * bitmap/drawable. Use this when no more changes will be made and an intrinsic size is set.
     * This effectively turns this into a static drawable.
     */
    public UserIconDrawable bake() {
        if (mSize <= 0) {
            throw new IllegalStateException("Baking requires an explicit intrinsic size");
        }
        onBoundsChange(new Rect(0, 0, mSize, mSize));
        rebake();
        mFrameColor = null;
        mFramePaint = null;
        mClearPaint = null;
        if (mUserDrawable != null) {
            mUserDrawable.setCallback(null);
            mUserDrawable = null;
        } else if (mUserIcon != null) {
            mUserIcon.recycle();
            mUserIcon = null;
        }
        return this;
    }

    private void rebake() {
        mInvalidated = false;

        if (mBitmap == null || (mUserDrawable == null && mUserIcon == null)) {
            return;
        }

        final Canvas canvas = new Canvas(mBitmap);
        canvas.drawColor(0, PorterDuff.Mode.CLEAR);

        if(mUserDrawable != null) {
            mUserDrawable.draw(canvas);
        } else if (mUserIcon != null) {
            int saveId = canvas.save();
            canvas.concat(mIconMatrix);
            canvas.drawCircle(mUserIcon.getWidth() * 0.5f, mUserIcon.getHeight() * 0.5f,
                    mIntrinsicRadius, mIconPaint);
            canvas.restoreToCount(saveId);
        }
        if (mFrameColor != null) {
            mFramePaint.setColor(mFrameColor.getColorForState(getState(), Color.TRANSPARENT));
        }
        if ((mFrameWidth + mFramePadding) > 0.001f) {
            float radius = mDisplayRadius - mPadding - mFrameWidth * 0.5f;
            canvas.drawCircle(getBounds().exactCenterX(), getBounds().exactCenterY(),
                    radius, mFramePaint);
        }

        if ((mBadge != null) && (mBadgeRadius > 0.001f)) {
            final float badgeDiameter = mBadgeRadius * 2f;
            final float badgeTop = mBitmap.getHeight() - badgeDiameter;
            float badgeLeft = mBitmap.getWidth() - badgeDiameter;

            mBadge.setBounds((int) badgeLeft, (int) badgeTop,
                    (int) (badgeLeft + badgeDiameter), (int) (badgeTop + badgeDiameter));

            final float borderRadius = mBadge.getBounds().width() * 0.5f + mBadgeMargin;
            canvas.drawCircle(badgeLeft + mBadgeRadius, badgeTop + mBadgeRadius,
                    borderRadius, mClearPaint);
            mBadge.draw(canvas);
        }
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        if (bounds.isEmpty() || (mUserIcon == null && mUserDrawable == null)) {
            return;
        }

        // re-create bitmap if applicable
        float newDisplayRadius = Math.min(bounds.width(), bounds.height()) * 0.5f;
        int size = (int) (newDisplayRadius * 2);
        if (mBitmap == null || size != ((int) (mDisplayRadius * 2))) {
            mDisplayRadius = newDisplayRadius;
            if (mBitmap != null) {
                mBitmap.recycle();
            }
            mBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
        }

        // update metrics
        mDisplayRadius = Math.min(bounds.width(), bounds.height()) * 0.5f;
        final float iconRadius = mDisplayRadius - mFrameWidth - mFramePadding - mPadding;
        RectF dstRect = new RectF(bounds.exactCenterX() - iconRadius,
                                  bounds.exactCenterY() - iconRadius,
                                  bounds.exactCenterX() + iconRadius,
                                  bounds.exactCenterY() + iconRadius);
        if (mUserDrawable != null) {
            Rect rounded = new Rect();
            dstRect.round(rounded);
            mIntrinsicRadius = Math.min(mUserDrawable.getIntrinsicWidth(),
                                        mUserDrawable.getIntrinsicHeight()) * 0.5f;
            mUserDrawable.setBounds(rounded);
        } else if (mUserIcon != null) {
            // Build square-to-square transformation matrix
            final float iconCX = mUserIcon.getWidth() * 0.5f;
            final float iconCY = mUserIcon.getHeight() * 0.5f;
            mIntrinsicRadius = Math.min(iconCX, iconCY);
            RectF srcRect = new RectF(iconCX - mIntrinsicRadius, iconCY - mIntrinsicRadius,
                                      iconCX + mIntrinsicRadius, iconCY + mIntrinsicRadius);
            mIconMatrix.setRectToRect(srcRect, dstRect, Matrix.ScaleToFit.FILL);
        }

        invalidateSelf();
    }

    @Override
    public void invalidateSelf() {
        super.invalidateSelf();
        mInvalidated = true;
    }

    @Override
    public boolean isStateful() {
        return mFrameColor != null && mFrameColor.isStateful();
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
    }

    @Override
    public int getIntrinsicWidth() {
        return (mSize <= 0 ? (int) mIntrinsicRadius * 2 : mSize);
    }

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

    @Override
    public void invalidateDrawable(@NonNull Drawable who) {
        invalidateSelf();
    }

    @Override
    public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
        scheduleSelf(what, when);
    }

    @Override
    public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
        unscheduleSelf(what);
    }
}
