/*
 * 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 android.support.design.widget;

import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.support.v4.graphics.ColorUtils;

/**
 * A drawable which draws an oval 'border'.
 */
class CircularBorderDrawable extends Drawable {

    /**
     * We actually draw the stroke wider than the border size given. This is to reduce any
     * potential transparent space caused by anti-aliasing and padding rounding.
     * This value defines the multiplier used to determine to draw stroke width.
     */
    private static final float DRAW_STROKE_WIDTH_MULTIPLE = 1.3333f;

    final Paint mPaint;
    final Rect mRect = new Rect();
    final RectF mRectF = new RectF();

    float mBorderWidth;

    private int mTopOuterStrokeColor;
    private int mTopInnerStrokeColor;
    private int mBottomOuterStrokeColor;
    private int mBottomInnerStrokeColor;

    private int mTintColor;

    private boolean mInvalidateShader = true;

    public CircularBorderDrawable() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.STROKE);
    }

    void setGradientColors(int topOuterStrokeColor, int topInnerStrokeColor,
            int bottomOuterStrokeColor, int bottomInnerStrokeColor) {
        mTopOuterStrokeColor = topOuterStrokeColor;
        mTopInnerStrokeColor = topInnerStrokeColor;
        mBottomOuterStrokeColor = bottomOuterStrokeColor;
        mBottomInnerStrokeColor = bottomInnerStrokeColor;
    }

    /**
     * Set the border width
     */
    void setBorderWidth(float width) {
        if (mBorderWidth != width) {
            mBorderWidth = width;
            mPaint.setStrokeWidth(width * DRAW_STROKE_WIDTH_MULTIPLE);
            mInvalidateShader = true;
            invalidateSelf();
        }
    }

    @Override
    public void draw(Canvas canvas) {
        if (mInvalidateShader) {
            mPaint.setShader(createGradientShader());
            mInvalidateShader = false;
        }

        final float halfBorderWidth = mPaint.getStrokeWidth() / 2f;
        final RectF rectF = mRectF;

        // We need to inset the oval bounds by half the border width. This is because stroke draws
        // the center of the border on the dimension. Whereas we want the stroke on the inside.
        copyBounds(mRect);
        rectF.set(mRect);
        rectF.left += halfBorderWidth;
        rectF.top += halfBorderWidth;
        rectF.right -= halfBorderWidth;
        rectF.bottom -= halfBorderWidth;

        // Draw the oval
        canvas.drawOval(rectF, mPaint);
    }

    @Override
    public boolean getPadding(Rect padding) {
        final int borderWidth = Math.round(mBorderWidth);
        padding.set(borderWidth, borderWidth, borderWidth, borderWidth);
        return true;
    }

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

    void setTintColor(int tintColor) {
        mTintColor = tintColor;
        mInvalidateShader = true;
        invalidateSelf();
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        mPaint.setColorFilter(colorFilter);
        invalidateSelf();
    }

    @Override
    public int getOpacity() {
        return mBorderWidth > 0 ? PixelFormat.TRANSLUCENT : PixelFormat.TRANSPARENT;
    }

    @Override
    protected void onBoundsChange(Rect bounds) {
        mInvalidateShader = true;
    }

    /**
     * Creates a vertical {@link LinearGradient}
     * @return
     */
    private Shader createGradientShader() {
        final Rect rect = mRect;
        copyBounds(rect);

        final float borderRatio = mBorderWidth / rect.height();

        final int[] colors = new int[6];
        colors[0] = ColorUtils.compositeColors(mTopOuterStrokeColor, mTintColor);
        colors[1] = ColorUtils.compositeColors(mTopInnerStrokeColor, mTintColor);
        colors[2] = ColorUtils.compositeColors(
                ColorUtils.setAlphaComponent(mTopInnerStrokeColor, 0), mTintColor);
        colors[3] = ColorUtils.compositeColors(
                ColorUtils.setAlphaComponent(mBottomInnerStrokeColor, 0), mTintColor);
        colors[4] = ColorUtils.compositeColors(mBottomInnerStrokeColor, mTintColor);
        colors[5] = ColorUtils.compositeColors(mBottomOuterStrokeColor, mTintColor);

        final float[] positions = new float[6];
        positions[0] = 0f;
        positions[1] = borderRatio;
        positions[2] = 0.5f;
        positions[3] = 0.5f;
        positions[4] = 1f - borderRatio;
        positions[5] = 1f;

        return new LinearGradient(
                0, rect.top,
                0, rect.bottom,
                colors, positions,
                Shader.TileMode.CLAMP);
    }
}
