/*

   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.image.renderable;

import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Rectangle2D;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderContext;

import org.apache.batik.ext.awt.image.PadMode;
import org.apache.batik.ext.awt.image.rendered.AffineRed;
import org.apache.batik.ext.awt.image.rendered.CachableRed;
import org.apache.batik.ext.awt.image.rendered.GaussianBlurRed8Bit;
import org.apache.batik.ext.awt.image.rendered.PadRed;

/**
 * GaussianBlurRable implementation
 *
 * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
 * @version $Id$
 */
public class GaussianBlurRable8Bit
    extends    AbstractColorInterpolationRable
    implements GaussianBlurRable {

    /**
     * Deviation along the x-axis
     */
    private double stdDeviationX;

    /**
     * Deviation along the y-axis
     */
    private double stdDeviationY;

    public GaussianBlurRable8Bit(Filter src,
                                 double stdevX, double stdevY) {
        super(src, null);
        setStdDeviationX(stdevX);
        setStdDeviationY(stdevY);
    }

    /**
     * The deviation along the x axis, in user space.
     * @param stdDeviationX should be greater than zero.
     */
    public void setStdDeviationX(double stdDeviationX){
        if(stdDeviationX < 0){
            throw new IllegalArgumentException();
        }

        touch();
        this.stdDeviationX = stdDeviationX;
    }

    /**
     * The deviation along the y axis, in user space.
     * @param stdDeviationY should be greater than zero
     */
    public void setStdDeviationY(double stdDeviationY){
        if(stdDeviationY < 0){
            throw new IllegalArgumentException();
        }
        touch();
        this.stdDeviationY = stdDeviationY;
    }

    /**
     * Returns the deviation along the x-axis, in user space.
     */
    public double getStdDeviationX(){
        return stdDeviationX;
    }

    /**
     * Returns the deviation along the y-axis, in user space.
     */
    public double getStdDeviationY(){
        return stdDeviationY;
    }

    /**
     * Sets the source of the blur operation
     */
    public void setSource(Filter src){
        init(src, null);
    }

    /**
     * Constant: 3*sqrt(2*PI)/4
     */
    static final double DSQRT2PI = (Math.sqrt(2*Math.PI)*3.0/4.0);

    /**
     * Grow the source's bounds
     */
    public Rectangle2D getBounds2D(){
        Rectangle2D src = getSource().getBounds2D();
        float dX = (float)(stdDeviationX*DSQRT2PI);
        float dY = (float)(stdDeviationY*DSQRT2PI);
        float radX = 3*dX/2;
        float radY = 3*dY/2;
        return new Rectangle2D.Float
            ((float)(src.getMinX()  -radX),
             (float)(src.getMinY()  -radY),
             (float)(src.getWidth() +2*radX),
             (float)(src.getHeight()+2*radY));
    }

    /**
     * Returns the source of the blur operation
     */
    public Filter getSource(){
        return (Filter)getSources().get(0);
    }

    public static final double eps = 0.0001;

    public static boolean eps_eq(double f1, double f2) {
        return ((f1 >= f2-eps) && (f1 <= f2+eps));
    }
    public static boolean eps_abs_eq(double f1, double f2) {
        if (f1 <0) f1 = -f1;
        if (f2 <0) f2 = -f2;
        return eps_eq(f1, f2);
    }

    public RenderedImage createRendering(RenderContext rc) {
        // Just copy over the rendering hints.
        RenderingHints rh = rc.getRenderingHints();
        if (rh == null) rh = new RenderingHints(null);

        // update the current affine transform
        AffineTransform at = rc.getTransform();


        // This splits out the scale and applies it
        // prior to the Gaussian.  Then after appying the gaussian
        // it applies the shear (rotation) and translation components.
        double sx = at.getScaleX();
        double sy = at.getScaleY();

        double shx = at.getShearX();
        double shy = at.getShearY();

        double tx = at.getTranslateX();
        double ty = at.getTranslateY();

        // The Scale is the "hypotonose" of the matrix vectors.
        double scaleX = Math.sqrt(sx*sx + shy*shy);
        double scaleY = Math.sqrt(sy*sy + shx*shx);

        double sdx = stdDeviationX*scaleX;
        double sdy = stdDeviationY*scaleY;

        // This is the affine transform between our usr space and an
        // intermediate space which is scaled similarly to our device
        // space but is still axially aligned with our device space.
        AffineTransform srcAt;

        // This is the affine transform between our intermediate
        // coordinate space and the real device space, or null (if
        // we don't need an intermediate space).
        AffineTransform resAt;

        int outsetX, outsetY;
        if ((sdx < 10)           &&
            (sdy < 10)           &&
            eps_eq    (sdx, sdy) &&
            eps_abs_eq(sx/scaleX, sy/scaleY)) {
            // Ok we have a square Gaussian kernel which means it is
            // circularly symetric, further our residual matrix (after
            // removing scaling) is a rotation matrix (perhaps with
            // mirroring), thus we can generate our source directly in
            // device space and convolve there rather than going to an
            // intermediate space (axially aligned with usr space) and
            // then completing the requested rotation/shear, with an
            // AffineRed...

            srcAt = at;
            resAt = null;
            outsetX = 0;
            outsetY = 0;
        } else {

            // Limit std dev to 10.  Put any extra into our
            // residual matrix.  This will effectively linearly
            // interpolate, but with such a large StdDev the
            // function is fairly smooth anyway...
            if (sdx > 10) {
                scaleX = scaleX*10/sdx;
                sdx = 10;
            }
            if (sdy > 10) {
                scaleY = scaleY*10/sdy;
                sdy = 10;
            }

            // Scale to device coords.
            srcAt = AffineTransform.getScaleInstance(scaleX, scaleY);

            // The shear/rotation simply divides out the
            // common scale factor in the matrix.
            resAt = new AffineTransform(sx/scaleX, shy/scaleX,
                                        shx/scaleY,  sy/scaleY,
                                        tx, ty);
            // Add a pixel all around for the affine to interpolate with.
            outsetX = 1;
            outsetY = 1;
        }


        Shape aoi = rc.getAreaOfInterest();
        if(aoi == null)
            aoi = getBounds2D();

        Shape devShape = srcAt.createTransformedShape(aoi);
        Rectangle devRect = devShape.getBounds();

        outsetX += GaussianBlurRed8Bit.surroundPixels(sdx, rh);
        outsetY += GaussianBlurRed8Bit.surroundPixels(sdy, rh);

        devRect.x      -= outsetX;
        devRect.y      -= outsetY;
        devRect.width  += 2*outsetX;
        devRect.height += 2*outsetY;

        Rectangle2D r;
        try {
            AffineTransform invSrcAt = srcAt.createInverse();
            r = invSrcAt.createTransformedShape(devRect).getBounds2D();
        } catch (NoninvertibleTransformException nte) {
            // Grow the region in usr space.
            r = aoi.getBounds2D();
            r = new Rectangle2D.Double(r.getX()-outsetX/scaleX,
                                       r.getY()-outsetY/scaleY,
                                       r.getWidth() +2*outsetX/scaleX,
                                       r.getHeight()+2*outsetY/scaleY);
        }

        RenderedImage ri;
        ri = getSource().createRendering(new RenderContext(srcAt, r, rh));
        if (ri == null)
            return null;

        CachableRed cr = convertSourceCS(ri);

        // System.out.println("DevRect: " + devRect);

        if (!devRect.equals(cr.getBounds())) {
            // System.out.println("MisMatch Dev:" + devRect);
            // System.out.println("         CR :" + cr.getBounds());
            cr = new PadRed(cr, devRect, PadMode.ZERO_PAD, rh);
        }

        cr = new GaussianBlurRed8Bit(cr, sdx, sdy, rh);

        if ((resAt != null) && (!resAt.isIdentity()))
            cr = new AffineRed(cr, resAt, rh);

        return cr;
    }

    /**
     * Returns the region of input data is is required to generate
     * outputRgn.
     * @param srcIndex  The source to do the dependency calculation for.
     * @param outputRgn The region of output you are interested in
     *  generating dependencies for.  The is given in the user coordiate
     *  system for this node.
     * @return The region of input required.  This is in the user
     * coordinate system for the source indicated by srcIndex.
     */
    public Shape getDependencyRegion(int srcIndex, Rectangle2D outputRgn){
        if(srcIndex != 0)
            outputRgn = null;
        else {
            // There is only one source in GaussianBlur
            float dX = (float)(stdDeviationX*DSQRT2PI);
            float dY = (float)(stdDeviationY*DSQRT2PI);
            float radX = 3*dX/2;
            float radY = 3*dY/2;
            outputRgn = new Rectangle2D.Float
                            ((float)(outputRgn.getMinX()  -radX),
                             (float)(outputRgn.getMinY()  -radY),
                             (float)(outputRgn.getWidth() +2*radX),
                             (float)(outputRgn.getHeight()+2*radY));

            Rectangle2D bounds = getBounds2D();
            if ( ! outputRgn.intersects(bounds) )
                return new Rectangle2D.Float();
            // Intersect with output region
            outputRgn = outputRgn.createIntersection(bounds);
        }

        return outputRgn;
    }

    /**
     * This calculates the region of output that is affected by a change
     * in a region of input.
     * @param srcIndex The input that inputRgn reflects changes in.
     * @param inputRgn the region of input that has changed, used to
     *  calculate the returned shape.  This is given in the user
     *  coordinate system of the source indicated by srcIndex.
     * @return The region of output that would be invalid given
     *  a change to inputRgn of the source selected by srcIndex.
     *  this is in the user coordinate system of this node.
     */
    public Shape getDirtyRegion(int srcIndex, Rectangle2D inputRgn){
        Rectangle2D dirtyRegion = null;
        if(srcIndex == 0){
            float dX = (float)(stdDeviationX*DSQRT2PI);
            float dY = (float)(stdDeviationY*DSQRT2PI);
            float radX = 3*dX/2;
            float radY = 3*dY/2;
            inputRgn = new Rectangle2D.Float
                            ((float)(inputRgn.getMinX()  -radX),
                             (float)(inputRgn.getMinY()  -radY),
                             (float)(inputRgn.getWidth() +2*radX),
                             (float)(inputRgn.getHeight()+2*radY));

            Rectangle2D bounds = getBounds2D();
            if ( ! inputRgn.intersects(bounds) )
                return new Rectangle2D.Float();
            // Intersect with input region
            dirtyRegion = inputRgn.createIntersection(bounds);
        }

        return dirtyRegion;
    }


}
