/*

   Copyright 2001-2003  The Apache Software Foundation 

   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 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;

/**
 * The <code>LinearGradientPaint</code> class provides a way to fill
 * a {@link java.awt.Shape} with a linear color gradient pattern.  The user may
 * specify 2 or more gradient colors, and this paint will provide an
 * interpolation between each color.  The user also specifies start and end
 * points which define where in user space the color gradient should begin 
 * and end.
 * <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>
 * For example:
 * <br>
 * <code>
 * <p>
 * Point2D start = new Point2D.Float(0, 0);<br>
 * Point2D end = new Point2D.Float(100,100);<br>
 * float[] dist = {0.0, 0.2, 1.0};<br>
 * Color[] colors = {Color.red, Color.white, Color.blue};<br>
 * LinearGradientPaint p = new LinearGradientPaint(start, end, dist, colors);
 * </code>
 *<p>
 * This code will create a LinearGradientPaint which interpolates between 
 * red and white for the first 20% of the gradient and between white and blue 
 * for the remaining 80%.
 *
 * <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>
 * The user may also select what action the LinearGradientPaint should take
 * when filling color outside the start and end points. If no cycle method is
 * specified, NO_CYCLE will be chosen by default, so the endpoint colors 
 * will be used to fill the remaining area.  
 *
 * <p> The following image demonstrates the options NO_CYCLE and REFLECT.
 *
 * <p>
 * <img src = "cyclic.jpg">
 *
 * <p> The colorSpace parameter allows the user to specify in which colorspace
 *  the interpolation should be performed, default sRGB or linearized RGB.
 *  
 *
 * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
 * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
 * @version $Id$
 * @see java.awt.Paint
 * @see java.awt.Graphics2D#setPaint
 *
 */
public final class LinearGradientPaint extends MultipleGradientPaint {

    /** Gradient start and end points. */
    private Point2D start, end;   
       
    /**<p>
     * Constructs an <code>LinearGradientPaint</code> with the default 
     * NO_CYCLE repeating method and SRGB colorspace.
     *
     * @param startX the x coordinate of the gradient axis start point 
     * in user space
     *
     * @param startY the y coordinate of the gradient axis start point 
     * in user space
     *
     * @param endX the x coordinate of the gradient axis end point 
     * in user space
     *
     * @param endY the y coordinate of the gradient axis end point 
     * in user space
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the 
     * distribution of colors along the gradient
     *
     * @param colors array of colors corresponding to each fractional value
     *     
     *
     * @throws IllegalArgumentException if start and end points are the 
     * same points, or if fractions.length != colors.length, or if colors 
     * is less than 2 in size.
     *
     */
    public LinearGradientPaint(float startX, float startY, 
                               float endX, float endY, 
                               float[] fractions, Color[] colors) {

        this(new Point2D.Float(startX, startY),
             new Point2D.Float(endX, endY), 
             fractions, 
             colors,
             NO_CYCLE,
             SRGB);
    }

    /**<p>
     * Constructs an <code>LinearGradientPaint</code> with default SRGB 
     * colorspace.
     *
     * @param startX the x coordinate of the gradient axis start point 
     * in user space
     *
     * @param startY the y coordinate of the gradient axis start point 
     * in user space
     *
     * @param endX the x coordinate of the gradient axis end point 
     * in user space
     * 
     * @param endY the y coordinate of the gradient axis end point 
     * in user space
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the 
     * distribution of colors along the gradient
     *
     * @param colors array of colors corresponding to each fractional value
     *
     * @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
     *
     * @throws IllegalArgumentException if start and end points are the 
     * same points, or if fractions.length != colors.length, or if colors 
     * is less than 2 in size.
     *
     */
    public LinearGradientPaint(float startX, float startY, 
                               float endX, float endY, 
                               float[] fractions, Color[] colors, 
                               CycleMethodEnum cycleMethod) {
        this(new Point2D.Float(startX, startY), 
             new Point2D.Float(endX, endY), 
             fractions, 
             colors,
             cycleMethod,
             SRGB);
    }

    /**<p>
     * Constructs a <code>LinearGradientPaint</code> with the default 
     * NO_CYCLE repeating method and SRGB colorspace.
     *
     * @param start the gradient axis start <code>Point</code> in user space
     *
     * @param end the gradient axis end <code>Point</code> in user space
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the 
     * distribution of colors along the gradient
     *
     * @param colors array of colors corresponding to each fractional value
     *
     * @throws NullPointerException if one of the points is null
     *
     * @throws IllegalArgumentException if start and end points are the 
     * same points, or if fractions.length != colors.length, or if colors 
     * is less than 2 in size.
     *
     */
    public LinearGradientPaint(Point2D start, Point2D end, float[] fractions,
                               Color[] colors) {

        this(start, end, fractions, colors, NO_CYCLE, SRGB);
    }
    
    /**<p>
     * Constructs a <code>LinearGradientPaint</code>.
     *
     * @param start the gradient axis start <code>Point</code> in user space
     *
     * @param end the gradient axis end <code>Point</code> in user space
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the 
     * distribution of colors along the gradient
     *
     * @param colors array of colors corresponding to each fractional value
     *
     * @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 start and end points are the 
     * same points, or if fractions.length != colors.length, or if colors 
     * is less than 2 in size.
     *
     */
    public LinearGradientPaint(Point2D start, Point2D end, float[] fractions,
                               Color[] colors, 
                               CycleMethodEnum cycleMethod, 
                               ColorSpaceEnum colorSpace) {
	
        this(start, end, fractions, colors, cycleMethod, colorSpace, 
             new AffineTransform());
	
    }
    
    /**<p>
     * Constructs a <code>LinearGradientPaint</code>.
     *
     * @param start the gradient axis start <code>Point</code> in user space
     *
     * @param end the gradient axis end <code>Point</code> in user space
     *
     * @param fractions numbers ranging from 0.0 to 1.0 specifying the 
     * distribution of colors along the gradient
     *
     * @param colors array of colors corresponding to each fractional value
     *
     * @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 start and end points are the 
     * same points, or if fractions.length != colors.length, or if colors 
     * is less than 2 in size.
     *
     */
    public LinearGradientPaint(Point2D start, Point2D end, float[] fractions,
                               Color[] colors,
                               CycleMethodEnum cycleMethod, 
                               ColorSpaceEnum colorSpace, 
                               AffineTransform gradientTransform) {
        super(fractions, colors, cycleMethod, colorSpace, gradientTransform);

        //
        // Check input parameters
        //	
        if (start == null || end == null) {
            throw new NullPointerException("Start and end points must be" +
                                           "non-null");
        }

        if (start.equals(end)) {
            throw new IllegalArgumentException("Start point cannot equal" +
                                               "endpoint");
        }

        //copy the points...
        this.start = (Point2D)start.clone();

        this.end = (Point2D)end.clone();
	
    }
    
    /**
     * 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.
     *
     * @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 LinearGradientPaintContext(cm, 
                                                  deviceBounds,
                                                  userBounds, 
                                                  transform,
                                                  hints,
                                                  start, 
                                                  end,
                                                  fractions,
                                                  this.getColors(),
                                                  cycleMethod,
                                                  colorSpace);
        }
	
        catch(NoninvertibleTransformException e) {
            e.printStackTrace();
            throw new IllegalArgumentException("transform should be" + 
                                               "invertible");
        }
    }
    
    /**
     * Returns a copy of the start point of the gradient axis
     * @return a {@link Point2D} object that is a copy of the point
     * that anchors the first color of this 
     * <code>LinearGradientPaint</code>.  
     */
    public Point2D getStartPoint() {
        return new Point2D.Double(start.getX(), start.getY());
    }
    
    /** Returns a copy of the end point of the gradient axis
     * @return a {@link Point2D} object that is a copy of the point
     * that anchors the last color of this 
     * <code>LinearGradientPaint</code>.  
     */
    public Point2D getEndPoint() {
        return new Point2D.Double(end.getX(), end.getY());
    }
        
}


