/*
 * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/* ********************************************************************
 **********************************************************************
 **********************************************************************
 *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
 *** As  an unpublished  work pursuant to Title 17 of the United    ***
 *** States Code.  All rights reserved.                             ***
 **********************************************************************
 **********************************************************************
 **********************************************************************/

package java.awt.image.renderable;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.RenderedImage;
import java.awt.RenderingHints;
import java.util.Hashtable;
import java.util.Vector;

/**
 * This class handles the renderable aspects of an operation with help
 * from its associated instance of a ContextualRenderedImageFactory.
 */
public class RenderableImageOp implements RenderableImage {

    /** A ParameterBlock containing source and parameters. */
    ParameterBlock paramBlock;

    /** The associated ContextualRenderedImageFactory. */
    ContextualRenderedImageFactory myCRIF;

    /** The bounding box of the results of this RenderableImageOp. */
    Rectangle2D boundingBox;


    /**
     * Constructs a RenderedImageOp given a
     * ContextualRenderedImageFactory object, and
     * a ParameterBlock containing RenderableImage sources and other
     * parameters.  Any RenderedImage sources referenced by the
     * ParameterBlock will be ignored.
     *
     * @param CRIF a ContextualRenderedImageFactory object
     * @param paramBlock a ParameterBlock containing this operation's source
     *        images and other parameters necessary for the operation
     *        to run.
     */
    public RenderableImageOp(ContextualRenderedImageFactory CRIF,
                             ParameterBlock paramBlock) {
        this.myCRIF = CRIF;
        this.paramBlock = (ParameterBlock) paramBlock.clone();
    }

    /**
     * Returns a vector of RenderableImages that are the sources of
     * image data for this RenderableImage. Note that this method may
     * return an empty vector, to indicate that the image has no sources,
     * or null, to indicate that no information is available.
     *
     * @return a (possibly empty) Vector of RenderableImages, or null.
     */
    public Vector<RenderableImage> getSources() {
        return getRenderableSources();
    }

    private Vector getRenderableSources() {
        Vector sources = null;

        if (paramBlock.getNumSources() > 0) {
            sources = new Vector();
            int i = 0;
            while (i < paramBlock.getNumSources()) {
                Object o = paramBlock.getSource(i);
                if (o instanceof RenderableImage) {
                    sources.add((RenderableImage)o);
                    i++;
                } else {
                    break;
                }
            }
        }
        return sources;
    }

    /**
     * Gets a property from the property set of this image.
     * If the property name is not recognized, java.awt.Image.UndefinedProperty
     * will be returned.
     *
     * @param name the name of the property to get, as a String.
     * @return a reference to the property Object, or the value
     *         java.awt.Image.UndefinedProperty.
     */
    public Object getProperty(String name) {
        return myCRIF.getProperty(paramBlock, name);
    }

    /**
     * Return a list of names recognized by getProperty.
     * @return a list of property names.
     */
    public String[] getPropertyNames() {
        return myCRIF.getPropertyNames();
    }

    /**
     * Returns true if successive renderings (that is, calls to
     * createRendering() or createScaledRendering()) with the same arguments
     * may produce different results.  This method may be used to
     * determine whether an existing rendering may be cached and
     * reused.  The CRIF's isDynamic method will be called.
     * @return <code>true</code> if successive renderings with the
     *         same arguments might produce different results;
     *         <code>false</code> otherwise.
     */
    public boolean isDynamic() {
        return myCRIF.isDynamic();
    }

    /**
     * Gets the width in user coordinate space.  By convention, the
     * usual width of a RenderableImage is equal to the image's aspect
     * ratio (width divided by height).
     *
     * @return the width of the image in user coordinates.
     */
    public float getWidth() {
        if (boundingBox == null) {
            boundingBox = myCRIF.getBounds2D(paramBlock);
        }
        return (float)boundingBox.getWidth();
    }

    /**
     * Gets the height in user coordinate space.  By convention, the
     * usual height of a RenderedImage is equal to 1.0F.
     *
     * @return the height of the image in user coordinates.
     */
    public float getHeight() {
        if (boundingBox == null) {
            boundingBox = myCRIF.getBounds2D(paramBlock);
        }
        return (float)boundingBox.getHeight();
    }

    /**
     * Gets the minimum X coordinate of the rendering-independent image data.
     */
    public float getMinX() {
        if (boundingBox == null) {
            boundingBox = myCRIF.getBounds2D(paramBlock);
        }
        return (float)boundingBox.getMinX();
    }

    /**
     * Gets the minimum Y coordinate of the rendering-independent image data.
     */
    public float getMinY() {
        if (boundingBox == null) {
            boundingBox = myCRIF.getBounds2D(paramBlock);
        }
        return (float)boundingBox.getMinY();
    }

    /**
     * Change the current ParameterBlock of the operation, allowing
     * editing of image rendering chains.  The effects of such a
     * change will be visible when a new rendering is created from
     * this RenderableImageOp or any dependent RenderableImageOp.
     *
     * @param paramBlock the new ParameterBlock.
     * @return the old ParameterBlock.
     * @see #getParameterBlock
     */
    public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
        ParameterBlock oldParamBlock = this.paramBlock;
        this.paramBlock = (ParameterBlock)paramBlock.clone();
        return oldParamBlock;
    }

    /**
     * Returns a reference to the current parameter block.
     * @return the <code>ParameterBlock</code> of this
     *         <code>RenderableImageOp</code>.
     * @see #setParameterBlock(ParameterBlock)
     */
    public ParameterBlock getParameterBlock() {
        return paramBlock;
    }

    /**
     * Creates a RenderedImage instance of this image with width w, and
     * height h in pixels.  The RenderContext is built automatically
     * with an appropriate usr2dev transform and an area of interest
     * of the full image.  All the rendering hints come from hints
     * passed in.
     *
     * <p> If w == 0, it will be taken to equal
     * Math.round(h*(getWidth()/getHeight())).
     * Similarly, if h == 0, it will be taken to equal
     * Math.round(w*(getHeight()/getWidth())).  One of
     * w or h must be non-zero or else an IllegalArgumentException
     * will be thrown.
     *
     * <p> The created RenderedImage may have a property identified
     * by the String HINTS_OBSERVED to indicate which RenderingHints
     * were used to create the image.  In addition any RenderedImages
     * that are obtained via the getSources() method on the created
     * RenderedImage may have such a property.
     *
     * @param w the width of rendered image in pixels, or 0.
     * @param h the height of rendered image in pixels, or 0.
     * @param hints a RenderingHints object containg hints.
     * @return a RenderedImage containing the rendered data.
     */
    public RenderedImage createScaledRendering(int w, int h,
                                               RenderingHints hints) {
        // DSR -- code to try to get a unit scale
        double sx = (double)w/getWidth();
        double sy = (double)h/getHeight();
        if (Math.abs(sx/sy - 1.0) < 0.01) {
            sx = sy;
        }
        AffineTransform usr2dev = AffineTransform.getScaleInstance(sx, sy);
        RenderContext newRC = new RenderContext(usr2dev, hints);
        return createRendering(newRC);
    }

    /**
     * Gets a RenderedImage instance of this image with a default
     * width and height in pixels.  The RenderContext is built
     * automatically with an appropriate usr2dev transform and an area
     * of interest of the full image.  All the rendering hints come
     * from hints passed in.  Implementors of this interface must be
     * sure that there is a defined default width and height.
     *
     * @return a RenderedImage containing the rendered data.
     */
    public RenderedImage createDefaultRendering() {
        AffineTransform usr2dev = new AffineTransform(); // Identity
        RenderContext newRC = new RenderContext(usr2dev);
        return createRendering(newRC);
    }

    /**
     * Creates a RenderedImage which represents this
     * RenderableImageOp (including its Renderable sources) rendered
     * according to the given RenderContext.
     *
     * <p> This method supports chaining of either Renderable or
     * RenderedImage operations.  If sources in
     * the ParameterBlock used to construct the RenderableImageOp are
     * RenderableImages, then a three step process is followed:
     *
     * <ol>
     * <li> mapRenderContext() is called on the associated CRIF for
     * each RenderableImage source;
     * <li> createRendering() is called on each of the RenderableImage sources
     * using the backwards-mapped RenderContexts obtained in step 1,
     * resulting in a rendering of each source;
     * <li> ContextualRenderedImageFactory.create() is called
     * with a new ParameterBlock containing the parameters of
     * the RenderableImageOp and the RenderedImages that were created by the
     * createRendering() calls.
     * </ol>
     *
     * <p> If the elements of the source Vector of
     * the ParameterBlock used to construct the RenderableImageOp are
     * instances of RenderedImage, then the CRIF.create() method is
     * called immediately using the original ParameterBlock.
     * This provides a basis case for the recursion.
     *
     * <p> The created RenderedImage may have a property identified
     * by the String HINTS_OBSERVED to indicate which RenderingHints
     * (from the RenderContext) were used to create the image.
     * In addition any RenderedImages
     * that are obtained via the getSources() method on the created
     * RenderedImage may have such a property.
     *
     * @param renderContext The RenderContext to use to perform the rendering.
     * @return a RenderedImage containing the desired output image.
     */
    public RenderedImage createRendering(RenderContext renderContext) {
        RenderedImage image = null;
        RenderContext rcOut = null;

        // Clone the original ParameterBlock; if the ParameterBlock
        // contains RenderableImage sources, they will be replaced by
        // RenderedImages.
        ParameterBlock renderedParamBlock = (ParameterBlock)paramBlock.clone();
        Vector sources = getRenderableSources();

        try {
            // This assumes that if there is no renderable source, that there
            // is a rendered source in paramBlock

            if (sources != null) {
                Vector renderedSources = new Vector();
                for (int i = 0; i < sources.size(); i++) {
                    rcOut = myCRIF.mapRenderContext(i, renderContext,
                                                    paramBlock, this);
                    RenderedImage rdrdImage =
                       ((RenderableImage)sources.elementAt(i)).createRendering(rcOut);
                    if (rdrdImage == null) {
                        return null;
                    }

                    // Add this rendered image to the ParameterBlock's
                    // list of RenderedImages.
                    renderedSources.addElement(rdrdImage);
                }

                if (renderedSources.size() > 0) {
                    renderedParamBlock.setSources(renderedSources);
                }
            }

            return myCRIF.create(renderContext, renderedParamBlock);
        } catch (ArrayIndexOutOfBoundsException e) {
            // This should never happen
            return null;
        }
    }
}
