/*
 * Copyright (C) 2015 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.wear.ble.view;

import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;

import com.android.permissioncontroller.R;

import java.util.Objects;

/**
 * An image view surrounded by a circle.
 */
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class CircledImageView extends View {

    private static final ArgbEvaluator ARGB_EVALUATOR = new ArgbEvaluator();

    private Drawable mDrawable;

    private final RectF mOval;
    private final Paint mPaint;

    private ColorStateList mCircleColor;

    private float mCircleRadius;
    private float mCircleRadiusPercent;

    private float mCircleRadiusPressed;
    private float mCircleRadiusPressedPercent;

    private float mRadiusInset;

    private int mCircleBorderColor;

    private float mCircleBorderWidth;
    private float mProgress = 1f;
    private final float mShadowWidth;

    private float mShadowVisibility;
    private boolean mCircleHidden = false;

    private float mInitialCircleRadius;

    private boolean mPressed = false;

    private boolean mProgressIndeterminate;
    private ProgressDrawable mIndeterminateDrawable;
    private Rect mIndeterminateBounds = new Rect();
    private long mColorChangeAnimationDurationMs = 0;

    private float mImageCirclePercentage = 1f;
    private float mImageHorizontalOffcenterPercentage = 0f;
    private Integer mImageTint;

    private final Drawable.Callback mDrawableCallback = new Drawable.Callback() {
        @Override
        public void invalidateDrawable(Drawable drawable) {
            invalidate();
        }

        @Override
        public void scheduleDrawable(Drawable drawable, Runnable runnable, long l) {
            // Not needed.
        }

        @Override
        public void unscheduleDrawable(Drawable drawable, Runnable runnable) {
            // Not needed.
        }
    };

    private int mCurrentColor;

    private final AnimatorUpdateListener mAnimationListener = new AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            int color = (int) animation.getAnimatedValue();
            if (color != CircledImageView.this.mCurrentColor) {
                CircledImageView.this.mCurrentColor = color;
                CircledImageView.this.invalidate();
            }
        }
    };

    private ValueAnimator mColorAnimator;

    public CircledImageView(Context context) {
        this(context, null);
    }

    public CircledImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CircledImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CircledImageView);
        mDrawable = a.getDrawable(R.styleable.CircledImageView_android_src);

        mCircleColor = a.getColorStateList(R.styleable.CircledImageView_circle_color);
        if (mCircleColor == null) {
            mCircleColor = ColorStateList.valueOf(android.R.color.darker_gray);
        }

        mCircleRadius = a.getDimension(
                R.styleable.CircledImageView_circle_radius, 0);
        mInitialCircleRadius = mCircleRadius;
        mCircleRadiusPressed = a.getDimension(
                R.styleable.CircledImageView_circle_radius_pressed, mCircleRadius);
        mCircleBorderColor = a.getColor(
                R.styleable.CircledImageView_circle_border_color, Color.BLACK);
        mCircleBorderWidth = a.getDimension(R.styleable.CircledImageView_circle_border_width, 0);

        if (mCircleBorderWidth > 0) {
            mRadiusInset += mCircleBorderWidth;
        }

        float circlePadding = a.getDimension(R.styleable.CircledImageView_circle_padding, 0);
        if (circlePadding > 0) {
            mRadiusInset += circlePadding;
        }
        mShadowWidth = a.getDimension(R.styleable.CircledImageView_shadow_width, 0);

        mImageCirclePercentage = a.getFloat(
                R.styleable.CircledImageView_image_circle_percentage, 0f);

        mImageHorizontalOffcenterPercentage = a.getFloat(
                R.styleable.CircledImageView_image_horizontal_offcenter_percentage, 0f);

        if (a.hasValue(R.styleable.CircledImageView_image_tint)) {
            mImageTint = a.getColor(R.styleable.CircledImageView_image_tint, 0);
        }

        mCircleRadiusPercent = a.getFraction(R.styleable.CircledImageView_circle_radius_percent,
                1, 1, 0f);

        mCircleRadiusPressedPercent = a.getFraction(
                R.styleable.CircledImageView_circle_radius_pressed_percent, 1, 1,
                mCircleRadiusPercent);

        a.recycle();

        mOval = new RectF();
        mPaint = new Paint();
        mPaint.setAntiAlias(true);

        mIndeterminateDrawable = new ProgressDrawable();
        // {@link #mDrawableCallback} must be retained as a member, as Drawable callback
        // is held by weak reference, we must retain it for it to continue to be called.
        mIndeterminateDrawable.setCallback(mDrawableCallback);

        setWillNotDraw(false);

        setColorForCurrentState();
    }

    public void setCircleHidden(boolean circleHidden) {
        if (circleHidden != mCircleHidden) {
            mCircleHidden = circleHidden;
            invalidate();
        }
    }


    @Override
    protected boolean onSetAlpha(int alpha) {
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int paddingLeft = getPaddingLeft();
        int paddingTop = getPaddingTop();


        float circleRadius = mPressed ? getCircleRadiusPressed() : getCircleRadius();
        if (mShadowWidth > 0 && mShadowVisibility > 0) {
            // First let's find the center of the view.
            mOval.set(paddingLeft, paddingTop, getWidth() - getPaddingRight(),
                    getHeight() - getPaddingBottom());
            // Having the center, lets make the shadow start beyond the circled and possibly the
            // border.
            final float radius = circleRadius + mCircleBorderWidth +
                    mShadowWidth * mShadowVisibility;
            mPaint.setColor(Color.BLACK);
            mPaint.setAlpha(Math.round(mPaint.getAlpha() * getAlpha()));
            mPaint.setStyle(Style.FILL);
            // TODO: precalc and pre-allocate this
            mPaint.setShader(new RadialGradient(mOval.centerX(), mOval.centerY(), radius,
                    new int[]{Color.BLACK, Color.TRANSPARENT}, new float[]{0.6f, 1f},
                    Shader.TileMode.MIRROR));
            canvas.drawCircle(mOval.centerX(), mOval.centerY(), radius, mPaint);
            mPaint.setShader(null);
        }
        if (mCircleBorderWidth > 0) {
            // First let's find the center of the view.
            mOval.set(paddingLeft, paddingTop, getWidth() - getPaddingRight(),
                    getHeight() - getPaddingBottom());
            // Having the center, lets make the border meet the circle.
            mOval.set(mOval.centerX() - circleRadius, mOval.centerY() - circleRadius,
                    mOval.centerX() + circleRadius, mOval.centerY() + circleRadius);
            mPaint.setColor(mCircleBorderColor);
            // {@link #Paint.setAlpha} is a helper method that just sets the alpha portion of the
            // color. {@link #Paint.setPaint} will clear any previously set alpha value.
            mPaint.setAlpha(Math.round(mPaint.getAlpha() * getAlpha()));
            mPaint.setStyle(Style.STROKE);
            mPaint.setStrokeWidth(mCircleBorderWidth);

            if (mProgressIndeterminate) {
                mOval.roundOut(mIndeterminateBounds);
                mIndeterminateDrawable.setBounds(mIndeterminateBounds);
                mIndeterminateDrawable.setRingColor(mCircleBorderColor);
                mIndeterminateDrawable.setRingWidth(mCircleBorderWidth);
                mIndeterminateDrawable.draw(canvas);
            } else {
                canvas.drawArc(mOval, -90, 360 * mProgress, false, mPaint);
            }
        }
        if (!mCircleHidden) {
            mOval.set(paddingLeft, paddingTop, getWidth() - getPaddingRight(),
                    getHeight() - getPaddingBottom());
            // {@link #Paint.setAlpha} is a helper method that just sets the alpha portion of the
            // color. {@link #Paint.setPaint} will clear any previously set alpha value.
            mPaint.setColor(mCurrentColor);
            mPaint.setAlpha(Math.round(mPaint.getAlpha() * getAlpha()));

            mPaint.setStyle(Style.FILL);
            float centerX = mOval.centerX();
            float centerY = mOval.centerY();

            canvas.drawCircle(centerX, centerY, circleRadius, mPaint);
        }

        if (mDrawable != null) {
            mDrawable.setAlpha(Math.round(getAlpha() * 255));

            if (mImageTint != null) {
                mDrawable.setTint(mImageTint);
            }
            mDrawable.draw(canvas);
        }

        super.onDraw(canvas);
    }

    private void setColorForCurrentState() {
        int newColor = mCircleColor.getColorForState(getDrawableState(),
                mCircleColor.getDefaultColor());
        if (mColorChangeAnimationDurationMs > 0) {
            if (mColorAnimator != null) {
                mColorAnimator.cancel();
            } else {
                mColorAnimator = new ValueAnimator();
            }
            mColorAnimator.setIntValues(new int[] {
                    mCurrentColor, newColor });
            mColorAnimator.setEvaluator(ARGB_EVALUATOR);
            mColorAnimator.setDuration(mColorChangeAnimationDurationMs);
            mColorAnimator.addUpdateListener(this.mAnimationListener);
            mColorAnimator.start();
        } else {
            if (newColor != mCurrentColor) {
                mCurrentColor = newColor;
                invalidate();
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        final float radius = getCircleRadius() + mCircleBorderWidth +
                mShadowWidth * mShadowVisibility;
        float desiredWidth = radius * 2;
        float desiredHeight = radius * 2;

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int width;
        int height;

        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            width = (int) Math.min(desiredWidth, widthSize);
        } else {
            width = (int) desiredWidth;
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            height = heightSize;
        } else if (heightMode == MeasureSpec.AT_MOST) {
            height = (int) Math.min(desiredHeight, heightSize);
        } else {
            height = (int) desiredHeight;
        }

        super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if (mDrawable != null) {
            // Retrieve the sizes of the drawable and the view.
            final int nativeDrawableWidth = mDrawable.getIntrinsicWidth();
            final int nativeDrawableHeight = mDrawable.getIntrinsicHeight();
            final int viewWidth = getMeasuredWidth();
            final int viewHeight = getMeasuredHeight();
            final float imageCirclePercentage = mImageCirclePercentage > 0
                    ? mImageCirclePercentage : 1;

            final float scaleFactor = Math.min(1f,
                    Math.min(
                            (float) nativeDrawableWidth != 0
                                    ? imageCirclePercentage * viewWidth / nativeDrawableWidth : 1,
                            (float) nativeDrawableHeight != 0
                                    ? imageCirclePercentage
                                        * viewHeight / nativeDrawableHeight : 1));

            // Scale the drawable down to fit the view, if needed.
            final int drawableWidth = Math.round(scaleFactor * nativeDrawableWidth);
            final int drawableHeight = Math.round(scaleFactor * nativeDrawableHeight);

            // Center the drawable within the view.
            final int drawableLeft = (viewWidth - drawableWidth) / 2
                    + Math.round(mImageHorizontalOffcenterPercentage * drawableWidth);
            final int drawableTop = (viewHeight - drawableHeight) / 2;

            mDrawable.setBounds(drawableLeft, drawableTop, drawableLeft + drawableWidth,
                    drawableTop + drawableHeight);
        }

        super.onLayout(changed, left, top, right, bottom);
    }

    public void setImageDrawable(Drawable drawable) {
        if (drawable != mDrawable) {
            final Drawable existingDrawable = mDrawable;
            mDrawable = drawable;

            final boolean skipLayout = drawable != null
                    && existingDrawable != null
                    && existingDrawable.getIntrinsicHeight() == drawable.getIntrinsicHeight()
                    && existingDrawable.getIntrinsicWidth() == drawable.getIntrinsicWidth();

            if (skipLayout) {
                mDrawable.setBounds(existingDrawable.getBounds());
            } else {
                requestLayout();
            }

            invalidate();
        }
    }

    public void setImageResource(int resId) {
        setImageDrawable(resId == 0 ? null : getContext().getDrawable(resId));
    }

    public void setImageCirclePercentage(float percentage) {
        float clamped = Math.max(0, Math.min(1, percentage));
        if (clamped != mImageCirclePercentage) {
            mImageCirclePercentage = clamped;
            invalidate();
        }
    }

    public void setImageHorizontalOffcenterPercentage(float percentage) {
        if (percentage != mImageHorizontalOffcenterPercentage) {
            mImageHorizontalOffcenterPercentage = percentage;
            invalidate();
        }
    }

    public void setImageTint(int tint) {
        if (tint != mImageTint) {
            mImageTint = tint;
            invalidate();
        }
    }

    public float getCircleRadius() {
        float radius = mCircleRadius;
        if (mCircleRadius <= 0 && mCircleRadiusPercent > 0) {
            radius = Math.max(getMeasuredHeight(), getMeasuredWidth()) * mCircleRadiusPercent;
        }

        return radius - mRadiusInset;
    }

    public float getCircleRadiusPercent() {
        return mCircleRadiusPercent;
    }

    public float getCircleRadiusPressed() {
        float radius = mCircleRadiusPressed;

        if (mCircleRadiusPressed <= 0 && mCircleRadiusPressedPercent > 0) {
            radius = Math.max(getMeasuredHeight(), getMeasuredWidth())
                    * mCircleRadiusPressedPercent;
        }

        return radius - mRadiusInset;
    }

    public float getCircleRadiusPressedPercent() {
        return mCircleRadiusPressedPercent;
    }

    public void setCircleRadius(float circleRadius) {
        if (circleRadius != mCircleRadius) {
            mCircleRadius = circleRadius;
            invalidate();
        }
    }

    /**
     * Sets the radius of the circle to be a percentage of the largest dimension of the view.
     * @param circleRadiusPercent A {@code float} from 0 to 1 representing the radius percentage.
     */
    public void setCircleRadiusPercent(float circleRadiusPercent) {
        if (circleRadiusPercent != mCircleRadiusPercent) {
            mCircleRadiusPercent = circleRadiusPercent;
            invalidate();
        }
    }

    public void setCircleRadiusPressed(float circleRadiusPressed) {
        if (circleRadiusPressed != mCircleRadiusPressed) {
            mCircleRadiusPressed = circleRadiusPressed;
            invalidate();
        }
    }

    /**
     * Sets the radius of the circle to be a percentage of the largest dimension of the view when
     * pressed.
     * @param circleRadiusPressedPercent A {@code float} from 0 to 1 representing the radius
     *                                   percentage.
     */
    public void setCircleRadiusPressedPercent(float circleRadiusPressedPercent) {
        if (circleRadiusPressedPercent  != mCircleRadiusPressedPercent) {
            mCircleRadiusPressedPercent = circleRadiusPressedPercent;
            invalidate();
        }
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        setColorForCurrentState();
    }

    public void setCircleColor(int circleColor) {
        setCircleColorStateList(ColorStateList.valueOf(circleColor));
    }

    public void setCircleColorStateList(ColorStateList circleColor) {
        if (!Objects.equals(circleColor, mCircleColor)) {
            mCircleColor = circleColor;
            setColorForCurrentState();
            invalidate();
        }
    }

    public ColorStateList getCircleColorStateList() {
        return mCircleColor;
    }

    public int getDefaultCircleColor() {
        return mCircleColor.getDefaultColor();
    }

    /**
     * Show the circle border as an indeterminate progress spinner.
     * The views circle border width and color must be set for this to have an effect.
     *
     * @param show true if the progress spinner is shown, false to hide it.
     */
    public void showIndeterminateProgress(boolean show) {
        mProgressIndeterminate = show;
        if (show) {
            mIndeterminateDrawable.startAnimation();
        } else {
            mIndeterminateDrawable.stopAnimation();
        }
    }

    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (visibility != View.VISIBLE) {
            showIndeterminateProgress(false);
        } else if (mProgressIndeterminate) {
            showIndeterminateProgress(true);
        }
    }

    public void setProgress(float progress) {
        if (progress != mProgress) {
            mProgress = progress;
            invalidate();
        }
    }

    /**
     * Set how much of the shadow should be shown.
     * @param shadowVisibility Value between 0 and 1.
     */
    public void setShadowVisibility(float shadowVisibility) {
        if (shadowVisibility != mShadowVisibility) {
            mShadowVisibility = shadowVisibility;
            invalidate();
        }
    }

    public float getInitialCircleRadius() {
        return mInitialCircleRadius;
    }

    public void setCircleBorderColor(int circleBorderColor) {
        mCircleBorderColor = circleBorderColor;
    }

    /**
     * Set the border around the circle.
     * @param circleBorderWidth Width of the border around the circle.
     */
    public void setCircleBorderWidth(float circleBorderWidth) {
        if (circleBorderWidth != mCircleBorderWidth) {
            mCircleBorderWidth = circleBorderWidth;
            invalidate();
        }
    }

    @Override
    public void setPressed(boolean pressed) {
        super.setPressed(pressed);
        if (pressed != mPressed) {
            mPressed = pressed;
            invalidate();
        }
    }

    public Drawable getImageDrawable() {
        return mDrawable;
    }

    /**
     * @return the milliseconds duration of the transition animation when the color changes.
     */
    public long getColorChangeAnimationDuration() {
        return mColorChangeAnimationDurationMs;
    }

    /**
     * @param mColorChangeAnimationDurationMs the milliseconds duration of the color change
     *            animation. The color change animation will run if the color changes with {@link #setCircleColor}
     *            or as a result of the active state changing.
     */
    public void setColorChangeAnimationDuration(long mColorChangeAnimationDurationMs) {
        this.mColorChangeAnimationDurationMs = mColorChangeAnimationDurationMs;
    }
}
