/*
 * Copyright (C) 2007 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.ColorInt;
import android.annotation.ColorLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;

public class SweepGradient extends Shader {
    @UnsupportedAppUsage
    private float mCx;
    @UnsupportedAppUsage
    private float mCy;
    @UnsupportedAppUsage
    private float[] mPositions;

    // @ColorInts are replaced by @ColorLongs, but these remain due to @UnsupportedAppUsage.
    @UnsupportedAppUsage
    @ColorInt
    private int[] mColors;
    @UnsupportedAppUsage
    @ColorInt
    private int mColor0;
    @UnsupportedAppUsage
    @ColorInt
    private int mColor1;

    @ColorLong
    private final long[] mColorLongs;

    /**
     * A Shader that draws a sweep gradient around a center point.
     *
     * @param cx       The x-coordinate of the center
     * @param cy       The y-coordinate of the center
     * @param colors   The sRGB colors to be distributed between around the center.
     *                 There must be at least 2 colors in the array.
     * @param positions May be NULL. The relative position of
     *                 each corresponding color in the colors array, beginning
     *                 with 0 and ending with 1.0. If the values are not
     *                 monotonic, the drawing may produce unexpected results.
     *                 If positions is NULL, then the colors are automatically
     *                 spaced evenly.
     */
    public SweepGradient(float cx, float cy, @NonNull @ColorInt int[] colors,
            @Nullable float[] positions) {
        this(cx, cy, convertColors(colors), positions, ColorSpace.get(ColorSpace.Named.SRGB));
    }

    /**
     * A Shader that draws a sweep gradient around a center point.
     *
     * @param cx       The x-coordinate of the center
     * @param cy       The y-coordinate of the center
     * @param colors   The colors to be distributed between around the center.
     *                 There must be at least 2 colors in the array.
     * @param positions May be NULL. The relative position of
     *                 each corresponding color in the colors array, beginning
     *                 with 0 and ending with 1.0. If the values are not
     *                 monotonic, the drawing may produce unexpected results.
     *                 If positions is NULL, then the colors are automatically
     *                 spaced evenly.
     * @throws IllegalArgumentException if there are less than two colors, the colors do
     *      not share the same {@link ColorSpace} or do not use a valid one, or {@code positions}
     *      is not {@code null} and has a different length from {@code colors}.
     */
    public SweepGradient(float cx, float cy, @NonNull @ColorLong long[] colors,
            @Nullable float[] positions) {
        this(cx, cy, colors.clone(), positions, detectColorSpace(colors));
    }

    /**
     * Base constructor. Assumes @param colors is a copy that this object can hold onto,
     * and all colors share @param colorSpace.
     */
    private SweepGradient(float cx, float cy, @NonNull @ColorLong long[] colors,
            @Nullable float[] positions, ColorSpace colorSpace) {
        super(colorSpace);

        if (positions != null && colors.length != positions.length) {
            throw new IllegalArgumentException(
                    "color and position arrays must be of equal length");
        }
        mCx = cx;
        mCy = cy;
        mColorLongs = colors;
        mPositions = positions != null ? positions.clone() : null;
    }

    /**
     * A Shader that draws a sweep gradient around a center point.
     *
     * @param cx       The x-coordinate of the center
     * @param cy       The y-coordinate of the center
     * @param color0   The sRGB color to use at the start of the sweep
     * @param color1   The sRGB color to use at the end of the sweep
     */
    public SweepGradient(float cx, float cy, @ColorInt int color0, @ColorInt int color1) {
        this(cx, cy, Color.pack(color0), Color.pack(color1));
    }

    /**
     * A Shader that draws a sweep gradient around a center point.
     *
     * @param cx       The x-coordinate of the center
     * @param cy       The y-coordinate of the center
     * @param color0   The color to use at the start of the sweep
     * @param color1   The color to use at the end of the sweep
     *
     * @throws IllegalArgumentException if the colors do
     *      not share the same {@link ColorSpace} or do not use a valid one.
     */
    public SweepGradient(float cx, float cy, @ColorLong long color0, @ColorLong long color1) {
        this(cx, cy, new long[] {color0, color1}, null);
    }

    @Override
    long createNativeInstance(long nativeMatrix) {
        return nativeCreate(nativeMatrix, mCx, mCy, mColorLongs, mPositions,
                colorSpace().getNativeInstance());
    }

    private static native long nativeCreate(long matrix, float x, float y,
            long[] colors, float[] positions, long colorSpaceHandle);
}

