/*
 * 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 android.support.v7.graphics.drawable;

import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.annotation.FloatRange;
import android.support.annotation.IntDef;
import android.support.annotation.RestrictTo;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v4.view.ViewCompat;
import android.support.v7.appcompat.R;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * A drawable that can draw a "Drawer hamburger" menu or an arrow and animate between them.
 * <p>
 * The progress between the two states is controlled via {@link #setProgress(float)}.
 * </p>
 */
public class DrawerArrowDrawable extends Drawable {

    /**
     * Direction to make the arrow point towards the left.
     *
     * @see #setDirection(int)
     * @see #getDirection()
     */
    public static final int ARROW_DIRECTION_LEFT = 0;

    /**
     * Direction to make the arrow point towards the right.
     *
     * @see #setDirection(int)
     * @see #getDirection()
     */
    public static final int ARROW_DIRECTION_RIGHT = 1;

    /**
     * Direction to make the arrow point towards the start.
     *
     * <p>When used in a view with a {@link ViewCompat#LAYOUT_DIRECTION_RTL RTL} layout direction,
     * this is the same as {@link #ARROW_DIRECTION_RIGHT}, otherwise it is the same as
     * {@link #ARROW_DIRECTION_LEFT}.</p>
     *
     * @see #setDirection(int)
     * @see #getDirection()
     */
    public static final int ARROW_DIRECTION_START = 2;

    /**
     * Direction to make the arrow point to the end.
     *
     * <p>When used in a view with a {@link ViewCompat#LAYOUT_DIRECTION_RTL RTL} layout direction,
     * this is the same as {@link #ARROW_DIRECTION_LEFT}, otherwise it is the same as
     * {@link #ARROW_DIRECTION_RIGHT}.</p>
     *
     * @see #setDirection(int)
     * @see #getDirection()
     */
    public static final int ARROW_DIRECTION_END = 3;

    /** @hide */
    @RestrictTo(LIBRARY_GROUP)
    @IntDef({ARROW_DIRECTION_LEFT, ARROW_DIRECTION_RIGHT,
            ARROW_DIRECTION_START, ARROW_DIRECTION_END})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ArrowDirection {}

    private final Paint mPaint = new Paint();

    // The angle in degrees that the arrow head is inclined at.
    private static final float ARROW_HEAD_ANGLE = (float) Math.toRadians(45);
    // The length of top and bottom bars when they merge into an arrow
    private float mArrowHeadLength;
    // The length of middle bar
    private float mBarLength;
    // The length of the middle bar when arrow is shaped
    private float mArrowShaftLength;
    // The space between bars when they are parallel
    private float mBarGap;
    // Whether bars should spin or not during progress
    private boolean mSpin;
    // Use Path instead of canvas operations so that if color has transparency, overlapping sections
    // wont look different
    private final Path mPath = new Path();
    // The reported intrinsic size of the drawable.
    private final int mSize;
    // Whether we should mirror animation when animation is reversed.
    private boolean mVerticalMirror = false;
    // The interpolated version of the original progress
    private float mProgress;
    // the amount that overlaps w/ bar size when rotation is max
    private float mMaxCutForBarSize;
    // The arrow direction
    private int mDirection = ARROW_DIRECTION_START;

    /**
     * @param context used to get the configuration for the drawable from
     */
    public DrawerArrowDrawable(Context context) {
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.MITER);
        mPaint.setStrokeCap(Paint.Cap.BUTT);
        mPaint.setAntiAlias(true);

        final TypedArray a = context.getTheme().obtainStyledAttributes(null,
                R.styleable.DrawerArrowToggle, R.attr.drawerArrowStyle,
                R.style.Base_Widget_AppCompat_DrawerArrowToggle);

        setColor(a.getColor(R.styleable.DrawerArrowToggle_color, 0));
        setBarThickness(a.getDimension(R.styleable.DrawerArrowToggle_thickness, 0));
        setSpinEnabled(a.getBoolean(R.styleable.DrawerArrowToggle_spinBars, true));
        // round this because having this floating may cause bad measurements
        setGapSize(Math.round(a.getDimension(R.styleable.DrawerArrowToggle_gapBetweenBars, 0)));

        mSize = a.getDimensionPixelSize(R.styleable.DrawerArrowToggle_drawableSize, 0);
        // round this because having this floating may cause bad measurements
        mBarLength = Math.round(a.getDimension(R.styleable.DrawerArrowToggle_barLength, 0));
        // round this because having this floating may cause bad measurements
        mArrowHeadLength = Math.round(a.getDimension(
                R.styleable.DrawerArrowToggle_arrowHeadLength, 0));
        mArrowShaftLength = a.getDimension(R.styleable.DrawerArrowToggle_arrowShaftLength, 0);
        a.recycle();
    }

    /**
     * Sets the length of the arrow head (from tip to edge, perpendicular to the shaft).
     *
     * @param length the length in pixels
     */
    public void setArrowHeadLength(float length) {
        if (mArrowHeadLength != length) {
            mArrowHeadLength = length;
            invalidateSelf();
        }
    }

    /**
     * Returns the length of the arrow head (from tip to edge, perpendicular to the shaft),
     * in pixels.
     */
    public float getArrowHeadLength() {
        return mArrowHeadLength;
    }

    /**
     * Sets the arrow shaft length.
     *
     * @param length the length in pixels
     */
    public void setArrowShaftLength(float length) {
        if (mArrowShaftLength != length) {
            mArrowShaftLength = length;
            invalidateSelf();
        }
    }

    /**
     * Returns the arrow shaft length in pixels.
     */
    public float getArrowShaftLength() {
        return mArrowShaftLength;
    }

    /**
     * The length of the bars when they are parallel to each other.
     */
    public float getBarLength() {
        return mBarLength;
    }

    /**
     * Sets the length of the bars when they are parallel to each other.
     *
     * @param length the length in pixels
     */
    public void setBarLength(float length) {
        if (mBarLength != length) {
            mBarLength = length;
            invalidateSelf();
        }
    }

    /**
     * Sets the color of the drawable.
     */
    public void setColor(@ColorInt int color) {
        if (color != mPaint.getColor()) {
            mPaint.setColor(color);
            invalidateSelf();
        }
    }

    /**
     * Returns the color of the drawable.
     */
    @ColorInt
    public int getColor() {
        return mPaint.getColor();
    }

    /**
     * Sets the thickness (stroke size) for the bars.
     *
     * @param width stroke width in pixels
     */
    public void setBarThickness(float width) {
        if (mPaint.getStrokeWidth() != width) {
            mPaint.setStrokeWidth(width);
            mMaxCutForBarSize = (float) (width / 2 * Math.cos(ARROW_HEAD_ANGLE));
            invalidateSelf();
        }
    }

    /**
     * Returns the thickness (stroke width) of the bars.
     */
    public float getBarThickness() {
        return mPaint.getStrokeWidth();
    }

    /**
     * Returns the max gap between the bars when they are parallel to each other.
     *
     * @see #getGapSize()
     */
    public float getGapSize() {
        return mBarGap;
    }

    /**
     * Sets the max gap between the bars when they are parallel to each other.
     *
     * @param gap the gap in pixels
     *
     * @see #getGapSize()
     */
    public void setGapSize(float gap) {
        if (gap != mBarGap) {
            mBarGap = gap;
            invalidateSelf();
        }
    }

    /**
     * Set the arrow direction.
     */
    public void setDirection(@ArrowDirection int direction) {
        if (direction != mDirection) {
            mDirection = direction;
            invalidateSelf();
        }
    }

    /**
     * Returns whether the bars should rotate or not during the transition.
     *
     * @see #setSpinEnabled(boolean)
     */
    public boolean isSpinEnabled() {
        return mSpin;
    }

    /**
     * Returns whether the bars should rotate or not during the transition.
     *
     * @param enabled true if the bars should rotate.
     *
     * @see #isSpinEnabled()
     */
    public void setSpinEnabled(boolean enabled) {
        if (mSpin != enabled) {
            mSpin = enabled;
            invalidateSelf();
        }
    }

    /**
     * Returns the arrow direction.
     */
    @ArrowDirection
    public int getDirection() {
        return mDirection;
    }

    /**
     * If set, canvas is flipped when progress reached to end and going back to start.
     */
    public void setVerticalMirror(boolean verticalMirror) {
        if (mVerticalMirror != verticalMirror) {
            mVerticalMirror = verticalMirror;
            invalidateSelf();
        }
    }

    @Override
    public void draw(Canvas canvas) {
        Rect bounds = getBounds();

        final boolean flipToPointRight;
        switch (mDirection) {
            case ARROW_DIRECTION_LEFT:
                flipToPointRight = false;
                break;
            case ARROW_DIRECTION_RIGHT:
                flipToPointRight = true;
                break;
            case ARROW_DIRECTION_END:
                flipToPointRight = DrawableCompat.getLayoutDirection(this)
                        == ViewCompat.LAYOUT_DIRECTION_LTR;
                break;
            case ARROW_DIRECTION_START:
            default:
                flipToPointRight = DrawableCompat.getLayoutDirection(this)
                        == ViewCompat.LAYOUT_DIRECTION_RTL;
                break;
        }

        // Interpolated widths of arrow bars

        float arrowHeadBarLength = (float) Math.sqrt(mArrowHeadLength * mArrowHeadLength * 2);
        arrowHeadBarLength = lerp(mBarLength, arrowHeadBarLength, mProgress);
        final float arrowShaftLength = lerp(mBarLength, mArrowShaftLength, mProgress);
        // Interpolated size of middle bar
        final float arrowShaftCut = Math.round(lerp(0, mMaxCutForBarSize, mProgress));
        // The rotation of the top and bottom bars (that make the arrow head)
        final float rotation = lerp(0, ARROW_HEAD_ANGLE, mProgress);

        // The whole canvas rotates as the transition happens
        final float canvasRotate = lerp(flipToPointRight ? 0 : -180,
                flipToPointRight ? 180 : 0, mProgress);

        final float arrowWidth = Math.round(arrowHeadBarLength * Math.cos(rotation));
        final float arrowHeight = Math.round(arrowHeadBarLength * Math.sin(rotation));

        mPath.rewind();
        final float topBottomBarOffset = lerp(mBarGap + mPaint.getStrokeWidth(), -mMaxCutForBarSize,
                mProgress);

        final float arrowEdge = -arrowShaftLength / 2;
        // draw middle bar
        mPath.moveTo(arrowEdge + arrowShaftCut, 0);
        mPath.rLineTo(arrowShaftLength - arrowShaftCut * 2, 0);

        // bottom bar
        mPath.moveTo(arrowEdge, topBottomBarOffset);
        mPath.rLineTo(arrowWidth, arrowHeight);

        // top bar
        mPath.moveTo(arrowEdge, -topBottomBarOffset);
        mPath.rLineTo(arrowWidth, -arrowHeight);

        mPath.close();

        canvas.save();

        // Rotate the whole canvas if spinning, if not, rotate it 180 to get
        // the arrow pointing the other way for RTL.
        final float barThickness = mPaint.getStrokeWidth();
        final int remainingSpace = (int) (bounds.height() - barThickness * 3 - mBarGap * 2);
        float yOffset = (remainingSpace / 4) * 2; // making sure it is a multiple of 2.
        yOffset += barThickness * 1.5 + mBarGap;

        canvas.translate(bounds.centerX(), yOffset);
        if (mSpin) {
            canvas.rotate(canvasRotate * ((mVerticalMirror ^ flipToPointRight) ? -1 : 1));
        } else if (flipToPointRight) {
            canvas.rotate(180);
        }
        canvas.drawPath(mPath, mPaint);

        canvas.restore();
    }

    @Override
    public void setAlpha(int alpha) {
        if (alpha != mPaint.getAlpha()) {
            mPaint.setAlpha(alpha);
            invalidateSelf();
        }
    }

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

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

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

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

    /**
     * Returns the current progress of the arrow.
     */
    @FloatRange(from = 0.0, to = 1.0)
    public float getProgress() {
        return mProgress;
    }

    /**
     * Set the progress of the arrow.
     *
     * <p>A value of {@code 0.0} indicates that the arrow should be drawn in it's starting
     * position. A value of {@code 1.0} indicates that the arrow should be drawn in it's ending
     * position.</p>
     */
    public void setProgress(@FloatRange(from = 0.0, to = 1.0) float progress) {
        if (mProgress != progress) {
            mProgress = progress;
            invalidateSelf();
        }
    }

    /**
     * Returns the paint instance used for all drawing.
     */
    public final Paint getPaint() {
        return mPaint;
    }

    /**
     * Linear interpolate between a and b with parameter t.
     */
    private static float lerp(float a, float b, float t) {
        return a + (b - a) * t;
    }
}