/*

   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You 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 org.apache.batik.ext.awt;

import java.awt.Color;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;

/**
 * <p>
 * This class provides a way to fill a shape with a circular radial color
 * gradient pattern. The user may specify 2 or more gradient colors, and this
 * paint will provide an interpolation between each color.
 * <p>
 *
 * The user must provide an array of floats specifying how to distribute the
 * colors along the gradient.  These values should range from 0.0 to 1.0 and
 * act like keyframes along the gradient (they mark where the gradient should
 * be exactly a particular color).
 *
 * <p>
 * This paint will map the first color of the gradient to a focus point within
 * the circle, and the last color to the perimeter of the circle, interpolating
 * smoothly for any inbetween colors specified by the user.  Any line drawn
 * from the focus point to the circumference will span the all the gradient
 * colors.  By default the focus is set to be the center of the circle.
 *
 * <p>
 * Specifying a focus point outside of the circle's radius will result in the
 * focus being set to the intersection point of the focus-center line and the
 * perimenter of the circle.
 * <p>
 *
 * Specifying a cycle method allows the user to control the painting behavior
 * outside of the bounds of the circle's radius.  See LinearGradientPaint for
 * more details.
 *
 * <p>
 * The following code demonstrates typical usage of RadialGradientPaint:
 * <p>
 * <code>
 * Point2D center = new Point2D.Float(0, 0);<br>
 * float radius = 20;
 * float[] dist = {0.0, 0.2, 1.0};<br>
 * Color[] colors = {Color.red, Color.white, Color.blue};<br>
 * RadialGradientPaint p = new RadialGradientPaint(center, radius,
 * dist, colors);
 * </code>
 *
 * <p> In the event that the user does not set the first keyframe value equal
 * to 0 and the last keyframe value equal to 1, keyframes will be created at
 * these positions and the first and last colors will be replicated there.
 * So, if a user specifies the following arrays to construct a gradient:<br>
 * {Color.blue, Color.red}, {.3, .7}<br>
 * this will be converted to a gradient with the following keyframes:
 * {Color.blue, Color.blue, Color.red, Color.red}, {0, .3, .7, 1}
 *
 *
 * <p>
 * <img src = "radial.jpg">
 * <p>
 * This image demonstrates a radial gradient with NO_CYCLE and default focus.
 * <p>
 *
 * <img src = "radial2.jpg">
 * <p>
 * This image demonstrates a radial gradient with NO_CYCLE and non-centered
 * focus.
 * <p>
 *
 * <img src = "radial3.jpg">
 * <p>
 * This image demonstrates a radial gradient with REFLECT and non-centered
 * focus.
 *
 * @author  Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
 * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
 * @version $Id$
 *
 */
public final class RadialGradientPaint extends MultipleGradientPaint {

    /** Focus point which defines the 0% gradient stop x coordinate. */
    private Point2D focus;

    /** Center of the circle defining the 100% gradient stop x coordinate. */
    private Point2D center;

    /** Radius of the outermost circle defining the 100% gradient stop. */
    private float radius;

    /**
     * <p>
     *
     * Constructs a <code>RadialGradientPaint</code>, using the center as the
     * focus point.
     *
     * @param cx the x coordinate in user space of the center point of the
     * circle defining the gradient.  The last color of the gradient is mapped
     * to the perimeter of this circle
     *
     * @param cy the y coordinate in user space of the center point of the
     * circle defining the gradient.  The last color of the gradient is mapped
     * to the perimeter of this circle
     *
     * @param radius the radius of the circle defining the extents of the
     * color gradient
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the
     * distribution of colors along the gradient
     *
     * @param colors array of colors to use in the gradient. The first color
     * is used at the focus point, the last color around the perimeter of the
     * circle.
     *
     *
     * @throws IllegalArgumentException
     *         if fractions.length != colors.length, or if colors is less
     *         than 2 in size, or if radius < 0
     *
     *
     */
    public RadialGradientPaint(float cx, float cy, float radius,
                               float[] fractions, Color[] colors) {
        this(cx, cy,
             radius,
             cx, cy,
             fractions,
             colors);
    }

    /**
     * <p>
     *
     * Constructs a <code>RadialGradientPaint</code>, using the center as the
     * focus point.
     *
     * @param center the center point, in user space, of the circle defining
     * the gradient
     *
     * @param radius the radius of the circle defining the extents of the
     * color gradient
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the
     * distribution of colors along the gradient
     *
     * @param colors array of colors to use in the gradient. The first color
     * is used at the focus point, the last color around the perimeter of the
     * circle.
     *
     * @throws NullPointerException if center point is null
     *
     * @throws IllegalArgumentException
     *         if fractions.length != colors.length, or if colors is less
     *         than 2 in size, or if radius < 0
     *
     *
     */
    public RadialGradientPaint(Point2D center, float radius,
                               float[] fractions, Color[] colors) {
        this(center,
             radius,
             center,
             fractions,
             colors);
    }

    /**
     * <p>
     *
     * Constructs a <code>RadialGradientPaint</code>.
     *
     * @param cx the x coordinate in user space of the center point of the
     * circle defining the gradient.  The last color of the gradient is mapped
     * to the perimeter of this circle
     *
     * @param cy the y coordinate in user space of the center point of the
     * circle defining the gradient.  The last color of the gradient is mapped
     * to the perimeter of this circle
     *
     * @param radius the radius of the circle defining the extents of the
     * color gradient
     *
     * @param fx the x coordinate of the point in user space to which the
     * first color is mapped
     *
     * @param fy the y coordinate of the point in user space to which the
     * first color is mapped
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the
     * distribution of colors along the gradient
     *
     * @param colors array of colors to use in the gradient. The first color
     * is used at the focus point, the last color around the perimeter of the
     * circle.
     *
     * @throws IllegalArgumentException
     *         if fractions.length != colors.length, or if colors is less
     *         than 2 in size, or if radius < 0
     *
     *
     */
    public RadialGradientPaint(float cx, float cy, float radius,
                               float fx, float fy,
                               float[] fractions, Color[] colors) {
        this(new Point2D.Float(cx, cy),
             radius,
             new Point2D.Float(fx, fy),
             fractions,
             colors,
             NO_CYCLE,
             SRGB);
    }

    /**
     * <p>
     *
     * Constructs a <code>RadialGradientPaint</code>.
     *
     * @param center the center point, in user space, of the circle defining
     * the gradient. The last color of the gradient is mapped to the perimeter
     * of this circle
     *
     * @param radius the radius of the circle defining the extents of the color
     * gradient
     *
     * @param focus the point, in user space, to which the first color is
     * mapped
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the
     * distribution of colors along the gradient
     *
     * @param colors array of colors to use in the gradient. The first color
     * is used at the focus point, the last color around the perimeter of the
     * circle.
     *
     * @throws NullPointerException if one of the points is null
     *
     * @throws IllegalArgumentException
     *         if fractions.length != colors.length, or if colors is less
     *         than 2 in size, or if radius < 0
     *
     */
    public RadialGradientPaint(Point2D center, float radius,
                               Point2D focus,
                               float[] fractions, Color[] colors) {
        this(center,
             radius,
             focus,
             fractions,
             colors,
             NO_CYCLE,
             SRGB);
    }

    /**
     * <p>
     *
     * Constructs a <code>RadialGradientPaint</code>.
     *
     * @param center the center point in user space of the circle defining the
     * gradient. The last color of the gradient is mapped to the perimeter of
     * this circle
     *
     * @param radius the radius of the circle defining the extents of the color
     * gradient
     *
     * @param focus the point in user space to which the first color is mapped
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the
     * distribution of colors along the gradient
     *
     * @param colors array of colors to use in the gradient. The first color is
     * used at the focus point, the last color around the perimeter of the
     * circle.
     *
     * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
     *
     * @param colorSpace which colorspace to use for interpolation,
     * either SRGB or LINEAR_RGB
     *
     * @throws NullPointerException if one of the points is null
     *
     * @throws IllegalArgumentException
     *         if fractions.length != colors.length, or if colors is less
     *         than 2 in size, or if radius < 0
     *
     */
    public RadialGradientPaint(Point2D center, float radius,
                               Point2D focus,
                               float[] fractions, Color[] colors,
                               CycleMethodEnum cycleMethod,
                               ColorSpaceEnum colorSpace) {
        this(center,
             radius,
             focus,
             fractions,
             colors,
             cycleMethod,
             colorSpace,
             new AffineTransform());
    }

    /**
     * <p>
     *
     * Constructs a <code>RadialGradientPaint</code>.
     *
     * @param center the center point in user space of the circle defining the
     * gradient.  The last color of the gradient is mapped to the perimeter of
     * this circle
     *
     * @param radius the radius of the circle defining the extents of the color
     * gradient.
     *
     * @param focus the point in user space to which the first color is mapped
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the
     * distribution of colors along the gradient
     *
     * @param colors array of colors to use in the gradient. The first color is
     * used at the focus point, the last color around the perimeter of the
     * circle.
     *
     * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
     *
     * @param colorSpace which colorspace to use for interpolation,
     * either SRGB or LINEAR_RGB
     *
     * @param gradientTransform transform to apply to the gradient
     *
     * @throws NullPointerException if one of the points is null,
     * or gradientTransform is null
     *
     * @throws IllegalArgumentException
     *         if fractions.length != colors.length, or if colors is less
     *         than 2 in size, or if radius < 0
     *
     */
    public RadialGradientPaint(Point2D center,
                               float radius,
                               Point2D focus,
                               float[] fractions,  Color[] colors,
                               CycleMethodEnum cycleMethod,
                               ColorSpaceEnum colorSpace,
                               AffineTransform gradientTransform){
        super(fractions, colors, cycleMethod, colorSpace, gradientTransform);

        // Check input arguments
        if (center == null) {
            throw new NullPointerException("Center point should not be null.");
        }

        if (focus == null) {
            throw new NullPointerException("Focus point should not be null.");
        }

        if (radius <= 0) {
            throw new IllegalArgumentException("radius should be greater than zero");
        }

        //copy parameters
        this.center = (Point2D)center.clone();
        this.focus = (Point2D)focus.clone();
        this.radius = radius;
    }

    /**
     * <p>
     *
     * Constructs a <code>RadialGradientPaint</code>, the gradient circle is
     * defined by a bounding box.
     *
     * @param gradientBounds the bounding box, in user space, of the circle
     * defining outermost extent of the gradient.
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the
     * distribution of colors along the gradient
     *
     * @param colors array of colors to use in the gradient. The first color
     * is used at the focus point, the last color around the perimeter of the
     * circle.
     *
     * @throws NullPointerException if the gradientBounds is null
     *
     * @throws IllegalArgumentException
     *         if fractions.length != colors.length, or if colors is less
     *         than 2 in size, or if radius < 0
     *
     */
    public RadialGradientPaint(Rectangle2D gradientBounds,
                               float[] fractions,  Color[] colors) {

        //calculate center point and radius based on bounding box coordinates.
        this((float)gradientBounds.getX() +
             ( (float)gradientBounds.getWidth() / 2),

             (float)gradientBounds.getY() +
             ( (float)gradientBounds.getWidth() / 2),

             (float)gradientBounds.getWidth() / 2,
             fractions, colors);
    }


    /** <p>
     * Creates and returns a PaintContext used to generate the color pattern,
     * for use by the internal rendering engine.
     *
     * @param cm {@link ColorModel} that receives
     * the <code>Paint</code> data. This is used only as a hint.
     *
     * @param deviceBounds the device space bounding box of the
     * graphics primitive being rendered
     *
     * @param userBounds the user space bounding box of the
     * graphics primitive being rendered
     *
     * @param transform the {@link AffineTransform} from user
     * space into device space
     *
     * @param hints the hints that the context object uses to choose
     * between rendering alternatives
     *
     * @return the {@link PaintContext} that generates color patterns.
     *
     * @throws IllegalArgumentException if the transform is not invertible
     *
     * @see PaintContext
     */
    public PaintContext createContext(ColorModel cm,
                                      Rectangle deviceBounds,
                                      Rectangle2D userBounds,
                                      AffineTransform transform,
                                      RenderingHints hints) {
        // Can't modify the transform passed in...
        transform = new AffineTransform(transform);
        // incorporate the gradient transform
        transform.concatenate(gradientTransform);

        try{
            return new RadialGradientPaintContext
                (cm, deviceBounds, userBounds, transform, hints,
                 (float)center.getX(), (float)center.getY(), radius,
                 (float)focus.getX(), (float)focus.getY(),
                 fractions, colors, cycleMethod, colorSpace);
        }

        catch(NoninvertibleTransformException e){
            throw new IllegalArgumentException("transform should be " +
                                               "invertible");
        }
    }

    /**
     * Returns a copy of the center point of the radial gradient.
     * @return a {@link Point2D} object that is a copy of the center point
     */
    public Point2D getCenterPoint() {
        return new Point2D.Double(center.getX(), center.getY());
    }

    /** Returns a copy of the end point of the gradient axis.
     * @return a {@link Point2D} object that is a copy of the focus point
     */
    public Point2D getFocusPoint() {
        return new Point2D.Double(focus.getX(), focus.getY());
    }

    /** Returns the radius of the circle defining the radial gradient.
     * @return the radius of the circle defining the radial gradient
     */
    public float getRadius() {
        return radius;
    }
}
