/*

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

import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.FlatteningPathIterator;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.util.List;
import java.util.ArrayList;

/**
 * Utilitiy class for length calculations of paths.
 * <p>
 *   PathLength is a utility class for calculating the length
 *   of a path, the location of a point at a particular length
 *   along the path, and the angle of the tangent to the path
 *   at a given length.
 * </p>
 * <p>
 *   It uses a FlatteningPathIterator to create a flattened version
 *   of the Path. This means the values returned are not always
 *   exact (in fact, they rarely are), but in most cases they
 *   are reasonably accurate.
 * </p>
 *
 * @author <a href="mailto:dean.jackson@cmis.csiro.au">Dean Jackson</a>
 * @version $Id$
 */
public class PathLength {

    /**
     * The path to use for calculations.
     */
    protected Shape path;

    /**
     * The list of flattened path segments.
     */
    protected List segments;

    /**
     * Array where the index is the index of the original path segment
     * and the value is the index of the first of the flattened segments
     * in {@link #segments} that corresponds to that original path segment.
     */
    protected int[] segmentIndexes;

    /**
     * Cached copy of the path length.
     */
    protected float pathLength;

    /**
     * Whether this path been flattened yet.
     */
    protected boolean initialised;

    /**
     * Creates a new PathLength object for the specified {@link Shape}.
     * @param path The Path (or Shape) to use.
     */
    public PathLength(Shape path) {
        setPath(path);
    }

    /**
     * Returns the path to use for calculations.
     * @return Path used in calculations.
     */
    public Shape getPath() {
        return path;
    }

    /**
     * Sets the path to use for calculations.
     * @param v Path to be used in calculations.
     */
    public void setPath(Shape v) {
        this.path = v;
        initialised = false;
    }

    /**
     * Returns the length of the path used by this PathLength object.
     * @return The length of the path.
     */
    public float lengthOfPath() {
        if (!initialised) {
            initialise();
        }
        return pathLength;
    }

    /**
     * Flattens the path and determines the path length.
     */
    protected void initialise() {
        pathLength = 0f;

        PathIterator pi = path.getPathIterator(new AffineTransform());
        SingleSegmentPathIterator sspi = new SingleSegmentPathIterator();
        segments = new ArrayList(20);
        List indexes = new ArrayList(20);
        int index = 0;
        int origIndex = -1;
        float lastMoveX = 0f;
        float lastMoveY = 0f;
        float currentX = 0f;
        float currentY = 0f;
        float[] seg = new float[6];
        int segType;

        segments.add(new PathSegment(PathIterator.SEG_MOVETO, 0f, 0f, 0f,
                                     origIndex));

        while (!pi.isDone()) {
            origIndex++;
            indexes.add(new Integer(index));
            segType = pi.currentSegment(seg);
            switch (segType) {
                case PathIterator.SEG_MOVETO:
                    segments.add(new PathSegment(segType, seg[0], seg[1],
                                                 pathLength, origIndex));
                    currentX = seg[0];
                    currentY = seg[1];
                    lastMoveX = currentX;
                    lastMoveY = currentY;
                    index++;
                    pi.next();
                    break;
                case PathIterator.SEG_LINETO:
                    pathLength += Point2D.distance(currentX, currentY, seg[0],
                                                   seg[1]);
                    segments.add(new PathSegment(segType, seg[0], seg[1],
                                                 pathLength, origIndex));
                    currentX = seg[0];
                    currentY = seg[1];
                    index++;
                    pi.next();
                    break;
                case PathIterator.SEG_CLOSE:
                    pathLength += Point2D.distance(currentX, currentY,
                                                   lastMoveX, lastMoveY);
                    segments.add(new PathSegment(PathIterator.SEG_LINETO,
                                                 lastMoveX, lastMoveY,
                                                 pathLength, origIndex));
                    currentX = lastMoveX;
                    currentY = lastMoveY;
                    index++;
                    pi.next();
                    break;
                default:
                    sspi.setPathIterator(pi, currentX, currentY);
                    FlatteningPathIterator fpi =
                        new FlatteningPathIterator(sspi, 0.01f);
                    while (!fpi.isDone()) {
                        segType = fpi.currentSegment(seg);
                        if (segType == PathIterator.SEG_LINETO) {
                            pathLength += Point2D.distance(currentX, currentY,
                                                           seg[0], seg[1]);
                            segments.add(new PathSegment(segType, seg[0],
                                                         seg[1], pathLength,
                                                         origIndex));
                            currentX = seg[0];
                            currentY = seg[1];
                            index++;
                        }
                        fpi.next();
                    }
            }
        }
        segmentIndexes = new int[indexes.size()];
        for (int i = 0; i < segmentIndexes.length; i++) {
            segmentIndexes[i] = ((Integer) indexes.get(i)).intValue();
        }
        initialised = true;
    }

    /**
     * Returns the number of segments in the path.
     */
    public int getNumberOfSegments() {
        if (!initialised) {
            initialise();
        }
        return segmentIndexes.length;
    }

    /**
     * Returns the length at the start of the segment given by the specified
     * index.
     */
    public float getLengthAtSegment(int index) {
        if (!initialised) {
            initialise();
        }
        if (index <= 0) {
            return 0;
        }
        if (index >= segmentIndexes.length) {
            return pathLength;
        }
        PathSegment seg = (PathSegment) segments.get(segmentIndexes[index]);
        return seg.getLength();
    }

    /**
     * Returns the index of the segment at the given distance along the path.
     */
    public int segmentAtLength(float length) {
        int upperIndex = findUpperIndex(length);
        if (upperIndex == -1) {
            // Length is off the end of the path.
            return -1;
        }

        if (upperIndex == 0) {
            // Length was probably zero, so return the upper segment.
            PathSegment upper = (PathSegment) segments.get(upperIndex);
            return upper.getIndex();
        }

        PathSegment lower = (PathSegment) segments.get(upperIndex - 1);
        return lower.getIndex();
    }

    /**
     * Returns the point that is the given proportion along the path segment
     * given by the specified index.
     */
    public Point2D pointAtLength(int index, float proportion) {
        if (!initialised) {
            initialise();
        }
        if (index < 0 || index >= segmentIndexes.length) {
            return null;
        }
        PathSegment seg = (PathSegment) segments.get(segmentIndexes[index]);
        float start = seg.getLength();
        float end;
        if (index == segmentIndexes.length - 1) {
            end = pathLength;
        } else {
            seg = (PathSegment) segments.get(segmentIndexes[index + 1]);
            end = seg.getLength();
        }
        return pointAtLength(start + (end - start) * proportion);
    }

    /**
     * Returns the point that is at the given length along the path.
     * @param length The length along the path
     * @return The point at the given length
     */
    public Point2D pointAtLength(float length) {
        int upperIndex = findUpperIndex(length);
        if (upperIndex == -1) {
            // Length is off the end of the path.
            return null;
        }

        PathSegment upper = (PathSegment) segments.get(upperIndex);

        if (upperIndex == 0) {
            // Length was probably zero, so return the upper point.
            return new Point2D.Float(upper.getX(), upper.getY());
        }

        PathSegment lower = (PathSegment) segments.get(upperIndex - 1);

        // Now work out where along the line would be the length.
        float offset = length - lower.getLength();

        // Compute the slope.
        double theta = Math.atan2(upper.getY() - lower.getY(),
                                  upper.getX() - lower.getX());

        float xPoint = (float) (lower.getX() + offset * Math.cos(theta));
        float yPoint = (float) (lower.getY() + offset * Math.sin(theta));

        return new Point2D.Float(xPoint, yPoint);
    }

    /**
     * Returns the slope of the path at the specified length.
     * @param index The segment number
     * @param proportion The proportion along the given segment
     * @return the angle in radians, in the range [-{@link Math#PI},
     *         {@link Math#PI}].
     */
    public float angleAtLength(int index, float proportion) {
        if (!initialised) {
            initialise();
        }
        if (index < 0 || index >= segmentIndexes.length) {
            return 0f;
        }
        PathSegment seg = (PathSegment) segments.get(segmentIndexes[index]);
        float start = seg.getLength();
        float end;
        if (index == segmentIndexes.length - 1) {
            end = pathLength;
        } else {
            seg = (PathSegment) segments.get(segmentIndexes[index + 1]);
            end = seg.getLength();
        }
        return angleAtLength(start + (end - start) * proportion);
    }

    /**
     * Returns the slope of the path at the specified length.
     * @param length The length along the path
     * @return the angle in radians, in the range [-{@link Math#PI},
     *         {@link Math#PI}].
     */
    public float angleAtLength(float length) {
        int upperIndex = findUpperIndex(length);
        if (upperIndex == -1) {
            // Length is off the end of the path.
            return 0f;
        }

        PathSegment upper = (PathSegment) segments.get(upperIndex);

        if (upperIndex == 0) {
            // Length was probably zero, so return the angle between the first
            // and second segments.
            upperIndex = 1;
        }

        PathSegment lower = (PathSegment) segments.get(upperIndex - 1);

        // Compute the slope.
        return (float) Math.atan2(upper.getY() - lower.getY(),
                                  upper.getX() - lower.getX());
    }

    /**
     * Returns the index of the path segment that bounds the specified
     * length along the path.
     * @param length The length along the path
     * @return The path segment index, or -1 if there is not such segment
     */
    public int findUpperIndex(float length) {
        if (!initialised) {
            initialise();
        }

        if (length < 0 || length > pathLength) {
            // Length is outside the path, so return -1.
            return -1;
        }

        // Find the two segments that are each side of the length.
        int lb = 0;
        int ub = segments.size() - 1;
        while (lb != ub) {
            int curr = (lb + ub) >> 1;
            PathSegment ps = (PathSegment) segments.get(curr);
            if (ps.getLength() >= length) {
                ub = curr;
            } else {
                lb = curr + 1;
            }
        }
        for (;;) {
            PathSegment ps = (PathSegment) segments.get(ub);
            if (ps.getSegType() != PathIterator.SEG_MOVETO
                    || ub == segments.size() - 1) {
                break;
            }
            ub++;
        }

        int upperIndex = -1;
        int currentIndex = 0;
        int numSegments = segments.size();
        while (upperIndex <= 0 && currentIndex < numSegments) {
            PathSegment ps = (PathSegment) segments.get(currentIndex);
            if (ps.getLength() >= length
                    && ps.getSegType() != PathIterator.SEG_MOVETO) {
                upperIndex = currentIndex;
            }
            currentIndex++;
        }
        return upperIndex;
    }

    /**
     * A {@link PathIterator} that returns only the next path segment from
     * another {@link PathIterator}.
     */
    protected static class SingleSegmentPathIterator implements PathIterator {

        /**
         * The path iterator being wrapped.
         */
        protected PathIterator it;

        /**
         * Whether the single segment has been passed.
         */
        protected boolean done;

        /**
         * Whether the generated move command has been returned.
         */
        protected boolean moveDone;

        /**
         * The x coordinate of the next move command.
         */
        protected double x;

        /**
         * The y coordinate of the next move command.
         */
        protected double y;

        /**
         * Sets the path iterator to use and the initial SEG_MOVETO command
         * to return before it.
         */
        public void setPathIterator(PathIterator it, double x, double y) {
            this.it = it;
            this.x = x;
            this.y = y;
            done = false;
            moveDone = false;
        }

        public int currentSegment(double[] coords) {
            int type = it.currentSegment(coords);
            if (!moveDone) {
                coords[0] = x;
                coords[1] = y;
                return SEG_MOVETO;
            }
            return type;
        }

        public int currentSegment(float[] coords) {
            int type = it.currentSegment(coords);
            if (!moveDone) {
                coords[0] = (float) x;
                coords[1] = (float) y;
                return SEG_MOVETO;
            }
            return type;
        }

        public int getWindingRule() {
            return it.getWindingRule();
        }

        public boolean isDone() {
            return done || it.isDone();
        }

        public void next() {
            if (!done) {
                if (!moveDone) {
                    moveDone = true;
                } else {
                    it.next();
                    done = true;
                }
            }
        }
    }

    /**
     * A single path segment in the flattened version of the path.
     * This is a local helper class. PathSegment-objects are stored in
     * the {@link PathLength#segments} - list.
     * This is used as an immutable value-object.
     */
    protected static class PathSegment {

        /**
         * The path segment type.
         */
        protected final int segType;

        /**
         * The x coordinate of the path segment.
         */
        protected float x;

        /**
         * The y coordinate of the path segment.
         */
        protected float y;

        /**
         * The length of the path segment, accumulated from the start.
         */
        protected float length;

        /**
         * The index of the original path segment this flattened segment is a
         * part of.
         */
        protected int index;

        /**
         * Creates a new PathSegment with the specified parameters.
         * @param segType The segment type
         * @param x The x coordinate
         * @param y The y coordinate
         * @param len The segment length
         * @param idx The index of the original path segment this flattened
         *            segment is a part of
         */
        PathSegment(int segType, float x, float y, float len, int idx) {
            this.segType = segType;
            this.x = x;
            this.y = y;
            this.length = len;
            this.index = idx;
        }

        /**
         * Returns the segment type.
         */
        public int getSegType() {
            return segType;
        }

        /**
         * Returns the x coordinate of the path segment.
         */
        public float getX() {
            return x;
        }

        /**
         * Sets the x coordinate of the path segment.
         */
        public void setX(float v) {
            x = v;
        }

        /**
         * Returns the y coordinate of the path segment.
         */
        public float getY() {
            return y;
        }

        /**
         * Sets the y coordinate of the path segment.
         */
        public void setY(float v) {
            y = v;
        }

        /**
         * Returns the length of the path segment.
         */
        public float getLength() {
            return length;
        }

        /**
         * Sets the length of the path segment.
         */
        public void setLength(float v) {
            length = v;
        }

        /**
         * Returns the segment index.
         */
        public int getIndex() {
            return index;
        }

        /**
         * Sets the segment index.
         */
        public void setIndex(int v) {
            index = v;
        }
    }
}
