/*
 * 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.graphics;

import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.graphics.drawable.Drawable;

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

/**
 * Defines a simple shape, used for bounding graphical regions.
 * <p>
 * Can be computed for a View, or computed by a Drawable, to drive the shape of
 * shadows cast by a View, or to clip the contents of the View.
 *
 * @see android.view.ViewOutlineProvider
 * @see android.view.View#setOutlineProvider(android.view.ViewOutlineProvider)
 * @see Drawable#getOutline(Outline)
 */
public final class Outline {
    private static final float RADIUS_UNDEFINED = Float.NEGATIVE_INFINITY;

    /** @hide */
    public static final int MODE_EMPTY = 0;
    /** @hide */
    public static final int MODE_ROUND_RECT = 1;
    /** @hide */
    public static final int MODE_CONVEX_PATH = 2;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = false,
            value = {
                    MODE_EMPTY,
                    MODE_ROUND_RECT,
                    MODE_CONVEX_PATH,
            })
    public @interface Mode {}

    /** @hide */
    @Mode
    public int mMode = MODE_EMPTY;

    /**
     * Only guaranteed to be non-null when mode == MODE_CONVEX_PATH
     *
     * @hide
     */
    public Path mPath;

    /** @hide */
    public final Rect mRect = new Rect();
    /** @hide */
    public float mRadius = RADIUS_UNDEFINED;
    /** @hide */
    public float mAlpha;

    /**
     * Constructs an empty Outline. Call one of the setter methods to make
     * the outline valid for use with a View.
     */
    public Outline() {}

    /**
     * Constructs an Outline with a copy of the data in src.
     */
    public Outline(@NonNull Outline src) {
        set(src);
    }

    /**
     * Sets the outline to be empty.
     *
     * @see #isEmpty()
     */
    public void setEmpty() {
        if (mPath != null) {
            // rewind here to avoid thrashing the allocations, but could alternately clear ref
            mPath.rewind();
        }
        mMode = MODE_EMPTY;
        mRect.setEmpty();
        mRadius = RADIUS_UNDEFINED;
    }

    /**
     * Returns whether the Outline is empty.
     * <p>
     * Outlines are empty when constructed, or if {@link #setEmpty()} is called,
     * until a setter method is called
     *
     * @see #setEmpty()
     */
    public boolean isEmpty() {
        return mMode == MODE_EMPTY;
    }


    /**
     * Returns whether the outline can be used to clip a View.
     * <p>
     * Currently, only Outlines that can be represented as a rectangle, circle,
     * or round rect support clipping.
     *
     * @see android.view.View#setClipToOutline(boolean)
     */
    public boolean canClip() {
        return mMode != MODE_CONVEX_PATH;
    }

    /**
     * Sets the alpha represented by the Outline - the degree to which the
     * producer is guaranteed to be opaque over the Outline's shape.
     * <p>
     * An alpha value of <code>0.0f</code> either represents completely
     * transparent content, or content that isn't guaranteed to fill the shape
     * it publishes.
     * <p>
     * Content producing a fully opaque (alpha = <code>1.0f</code>) outline is
     * assumed by the drawing system to fully cover content beneath it,
     * meaning content beneath may be optimized away.
     */
    public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {
        mAlpha = alpha;
    }

    /**
     * Returns the alpha represented by the Outline.
     */
    public float getAlpha() {
        return mAlpha;
    }

    /**
     * Replace the contents of this Outline with the contents of src.
     *
     * @param src Source outline to copy from.
     */
    public void set(@NonNull Outline src) {
        mMode = src.mMode;
        if (src.mMode == MODE_CONVEX_PATH) {
            if (mPath == null) {
                mPath = new Path();
            }
            mPath.set(src.mPath);
        }
        mRect.set(src.mRect);
        mRadius = src.mRadius;
        mAlpha = src.mAlpha;
    }

    /**
     * Sets the Outline to the rounded rect defined by the input rect, and
     * corner radius.
     */
    public void setRect(int left, int top, int right, int bottom) {
        setRoundRect(left, top, right, bottom, 0.0f);
    }

    /**
     * Convenience for {@link #setRect(int, int, int, int)}
     */
    public void setRect(@NonNull Rect rect) {
        setRect(rect.left, rect.top, rect.right, rect.bottom);
    }

    /**
     * Sets the Outline to the rounded rect defined by the input rect, and corner radius.
     * <p>
     * Passing a zero radius is equivalent to calling {@link #setRect(int, int, int, int)}
     */
    public void setRoundRect(int left, int top, int right, int bottom, float radius) {
        if (left >= right || top >= bottom) {
            setEmpty();
            return;
        }

        if (mMode == MODE_CONVEX_PATH) {
            // rewind here to avoid thrashing the allocations, but could alternately clear ref
            mPath.rewind();
        }
        mMode = MODE_ROUND_RECT;
        mRect.set(left, top, right, bottom);
        mRadius = radius;
    }

    /**
     * Convenience for {@link #setRoundRect(int, int, int, int, float)}
     */
    public void setRoundRect(@NonNull Rect rect, float radius) {
        setRoundRect(rect.left, rect.top, rect.right, rect.bottom, radius);
    }

    /**
     * Populates {@code outBounds} with the outline bounds, if set, and returns
     * {@code true}. If no outline bounds are set, or if a path has been set
     * via {@link #setConvexPath(Path)}, returns {@code false}.
     *
     * @param outRect the rect to populate with the outline bounds, if set
     * @return {@code true} if {@code outBounds} was populated with outline
     *         bounds, or {@code false} if no outline bounds are set
     */
    public boolean getRect(@NonNull Rect outRect) {
        if (mMode != MODE_ROUND_RECT) {
            return false;
        }
        outRect.set(mRect);
        return true;
    }

    /**
     * Returns the rounded rect radius, if set, or a value less than 0 if a path has
     * been set via {@link #setConvexPath(Path)}. A return value of {@code 0}
     * indicates a non-rounded rect.
     *
     * @return the rounded rect radius, or value < 0
     */
    public float getRadius() {
        return mRadius;
    }

    /**
     * Sets the outline to the oval defined by input rect.
     */
    public void setOval(int left, int top, int right, int bottom) {
        if (left >= right || top >= bottom) {
            setEmpty();
            return;
        }

        if ((bottom - top) == (right - left)) {
            // represent circle as round rect, for efficiency, and to enable clipping
            setRoundRect(left, top, right, bottom, (bottom - top) / 2.0f);
            return;
        }

        if (mPath == null) {
            mPath = new Path();
        } else {
            mPath.rewind();
        }

        mMode = MODE_CONVEX_PATH;
        mPath.addOval(left, top, right, bottom, Path.Direction.CW);
        mRect.setEmpty();
        mRadius = RADIUS_UNDEFINED;
    }

    /**
     * Convenience for {@link #setOval(int, int, int, int)}
     */
    public void setOval(@NonNull Rect rect) {
        setOval(rect.left, rect.top, rect.right, rect.bottom);
    }

    /**
     * Sets the Constructs an Outline from a
     * {@link android.graphics.Path#isConvex() convex path}.
     */
    public void setConvexPath(@NonNull Path convexPath) {
        if (convexPath.isEmpty()) {
            setEmpty();
            return;
        }

        if (!convexPath.isConvex()) {
            throw new IllegalArgumentException("path must be convex");
        }

        if (mPath == null) {
            mPath = new Path();
        }

        mMode = MODE_CONVEX_PATH;
        mPath.set(convexPath);
        mRect.setEmpty();
        mRadius = RADIUS_UNDEFINED;
    }

    /**
     * Offsets the Outline by (dx,dy)
     */
    public void offset(int dx, int dy) {
        if (mMode == MODE_ROUND_RECT) {
            mRect.offset(dx, dy);
        } else if (mMode == MODE_CONVEX_PATH) {
            mPath.offset(dx, dy);
        }
    }
}
