/*
 * Copyright 1998-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package javax.swing.text.html;

import java.awt.Polygon;
import java.io.Serializable;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.text.AttributeSet;

/**
 * Map is used to represent a map element that is part of an HTML document.
 * Once a Map has been created, and any number of areas have been added,
 * you can test if a point falls inside the map via the contains method.
 *
 * @author  Scott Violet
 */
class Map implements Serializable {
    /** Name of the Map. */
    private String           name;
    /** An array of AttributeSets. */
    private Vector           areaAttributes;
    /** An array of RegionContainments, will slowly grow to match the
     * length of areaAttributes as needed. */
    private Vector           areas;

    public Map() {
    }

    public Map(String name) {
        this.name = name;
    }

    /**
     * Returns the name of the Map.
     */
    public String getName() {
        return name;
    }

    /**
     * Defines a region of the Map, based on the passed in AttributeSet.
     */
    public void addArea(AttributeSet as) {
        if (as == null) {
            return;
        }
        if (areaAttributes == null) {
            areaAttributes = new Vector(2);
        }
        areaAttributes.addElement(as.copyAttributes());
    }

    /**
     * Removes the previously created area.
     */
    public void removeArea(AttributeSet as) {
        if (as != null && areaAttributes != null) {
            int numAreas = (areas != null) ? areas.size() : 0;
            for (int counter = areaAttributes.size() - 1; counter >= 0;
                 counter--) {
                if (((AttributeSet)areaAttributes.elementAt(counter)).
                    isEqual(as)){
                    areaAttributes.removeElementAt(counter);
                    if (counter < numAreas) {
                        areas.removeElementAt(counter);
                    }
                }
            }
        }
    }

    /**
     * Returns the AttributeSets representing the differet areas of the Map.
     */
    public AttributeSet[] getAreas() {
        int numAttributes = (areaAttributes != null) ? areaAttributes.size() :
                            0;
        if (numAttributes != 0) {
            AttributeSet[]    retValue = new AttributeSet[numAttributes];

            areaAttributes.copyInto(retValue);
            return retValue;
        }
        return null;
    }

    /**
     * Returns the AttributeSet that contains the passed in location,
     * <code>x</code>, <code>y</code>. <code>width</code>, <code>height</code>
     * gives the size of the region the map is defined over. If a matching
     * area is found, the AttribueSet for it is returned.
     */
    public AttributeSet getArea(int x, int y, int width, int height) {
        int      numAttributes = (areaAttributes != null) ?
                                 areaAttributes.size() : 0;

        if (numAttributes > 0) {
            int      numAreas = (areas != null) ? areas.size() : 0;

            if (areas == null) {
                areas = new Vector(numAttributes);
            }
            for (int counter = 0; counter < numAttributes; counter++) {
                if (counter >= numAreas) {
                    areas.addElement(createRegionContainment
                            ((AttributeSet)areaAttributes.elementAt(counter)));
                }
                RegionContainment       rc = (RegionContainment)areas.
                                             elementAt(counter);
                if (rc != null && rc.contains(x, y, width, height)) {
                    return (AttributeSet)areaAttributes.elementAt(counter);
                }
            }
        }
        return null;
    }

    /**
     * Creates and returns an instance of RegionContainment that can be
     * used to test if a particular point lies inside a region.
     */
    protected RegionContainment createRegionContainment
                                  (AttributeSet attributes) {
        Object     shape = attributes.getAttribute(HTML.Attribute.SHAPE);

        if (shape == null) {
            shape = "rect";
        }
        if (shape instanceof String) {
            String                shapeString = ((String)shape).toLowerCase();
            RegionContainment     rc = null;

            try {
                if (shapeString.equals("rect")) {
                    rc = new RectangleRegionContainment(attributes);
                }
                else if (shapeString.equals("circle")) {
                    rc = new CircleRegionContainment(attributes);
                }
                else if (shapeString.equals("poly")) {
                    rc = new PolygonRegionContainment(attributes);
                }
                else if (shapeString.equals("default")) {
                    rc = DefaultRegionContainment.sharedInstance();
                }
            } catch (RuntimeException re) {
                // Something wrong with attributes.
                rc = null;
            }
            return rc;
        }
        return null;
    }

    /**
     * Creates and returns an array of integers from the String
     * <code>stringCoords</code>. If one of the values represents a
     * % the returned value with be negative. If a parse error results
     * from trying to parse one of the numbers null is returned.
     */
    static protected int[] extractCoords(Object stringCoords) {
        if (stringCoords == null || !(stringCoords instanceof String)) {
            return null;
        }

        StringTokenizer    st = new StringTokenizer((String)stringCoords,
                                                    ", \t\n\r");
        int[]              retValue = null;
        int                numCoords = 0;

        while(st.hasMoreElements()) {
            String         token = st.nextToken();
            int            scale;

            if (token.endsWith("%")) {
                scale = -1;
                token = token.substring(0, token.length() - 1);
            }
            else {
                scale = 1;
            }
            try {
                int       intValue = Integer.parseInt(token);

                if (retValue == null) {
                    retValue = new int[4];
                }
                else if(numCoords == retValue.length) {
                    int[]    temp = new int[retValue.length * 2];

                    System.arraycopy(retValue, 0, temp, 0, retValue.length);
                    retValue = temp;
                }
                retValue[numCoords++] = intValue * scale;
            } catch (NumberFormatException nfe) {
                return null;
            }
        }
        if (numCoords > 0 && numCoords != retValue.length) {
            int[]    temp = new int[numCoords];

            System.arraycopy(retValue, 0, temp, 0, numCoords);
            retValue = temp;
        }
        return retValue;
    }


    /**
     * Defines the interface used for to check if a point is inside a
     * region.
     */
    interface RegionContainment {
        /**
         * Returns true if the location <code>x</code>, <code>y</code>
         * falls inside the region defined in the receiver.
         * <code>width</code>, <code>height</code> is the size of
         * the enclosing region.
         */
        public boolean contains(int x, int y, int width, int height);
    }


    /**
     * Used to test for containment in a rectangular region.
     */
    static class RectangleRegionContainment implements RegionContainment {
        /** Will be non-null if one of the values is a percent, and any value
         * that is non null indicates it is a percent
         * (order is x, y, width, height). */
        float[]       percents;
        /** Last value of width passed in. */
        int           lastWidth;
        /** Last value of height passed in. */
        int           lastHeight;
        /** Top left. */
        int           x0;
        int           y0;
        /** Bottom right. */
        int           x1;
        int           y1;

        public RectangleRegionContainment(AttributeSet as) {
            int[]    coords = Map.extractCoords(as.getAttribute(HTML.
                                                           Attribute.COORDS));

            percents = null;
            if (coords == null || coords.length != 4) {
                throw new RuntimeException("Unable to parse rectangular area");
            }
            else {
                x0 = coords[0];
                y0 = coords[1];
                x1 = coords[2];
                y1 = coords[3];
                if (x0 < 0 || y0 < 0 || x1 < 0 || y1 < 0) {
                    percents = new float[4];
                    lastWidth = lastHeight = -1;
                    for (int counter = 0; counter < 4; counter++) {
                        if (coords[counter] < 0) {
                            percents[counter] = Math.abs
                                        (coords[counter]) / 100.0f;
                        }
                        else {
                            percents[counter] = -1.0f;
                        }
                    }
                }
            }
        }

        public boolean contains(int x, int y, int width, int height) {
            if (percents == null) {
                return contains(x, y);
            }
            if (lastWidth != width || lastHeight != height) {
                lastWidth = width;
                lastHeight = height;
                if (percents[0] != -1.0f) {
                    x0 = (int)(percents[0] * width);
                }
                if (percents[1] != -1.0f) {
                    y0 = (int)(percents[1] * height);
                }
                if (percents[2] != -1.0f) {
                    x1 = (int)(percents[2] * width);
                }
                if (percents[3] != -1.0f) {
                    y1 = (int)(percents[3] * height);
                }
            }
            return contains(x, y);
        }

        public boolean contains(int x, int y) {
            return ((x >= x0 && x <= x1) &&
                    (y >= y0 && y <= y1));
        }
    }


    /**
     * Used to test for containment in a polygon region.
     */
    static class PolygonRegionContainment extends Polygon implements
                 RegionContainment {
        /** If any value is a percent there will be an entry here for the
         * percent value. Use percentIndex to find out the index for it. */
        float[]           percentValues;
        int[]             percentIndexs;
        /** Last value of width passed in. */
        int               lastWidth;
        /** Last value of height passed in. */
        int               lastHeight;

        public PolygonRegionContainment(AttributeSet as) {
            int[]    coords = Map.extractCoords(as.getAttribute(HTML.Attribute.
                                                                COORDS));

            if (coords == null || coords.length == 0 ||
                coords.length % 2 != 0) {
                throw new RuntimeException("Unable to parse polygon area");
            }
            else {
                int        numPercents = 0;

                lastWidth = lastHeight = -1;
                for (int counter = coords.length - 1; counter >= 0;
                     counter--) {
                    if (coords[counter] < 0) {
                        numPercents++;
                    }
                }

                if (numPercents > 0) {
                    percentIndexs = new int[numPercents];
                    percentValues = new float[numPercents];
                    for (int counter = coords.length - 1, pCounter = 0;
                         counter >= 0; counter--) {
                        if (coords[counter] < 0) {
                            percentValues[pCounter] = coords[counter] /
                                                      -100.0f;
                            percentIndexs[pCounter] = counter;
                            pCounter++;
                        }
                    }
                }
                else {
                    percentIndexs = null;
                    percentValues = null;
                }
                npoints = coords.length / 2;
                xpoints = new int[npoints];
                ypoints = new int[npoints];

                for (int counter = 0; counter < npoints; counter++) {
                    xpoints[counter] = coords[counter + counter];
                    ypoints[counter] = coords[counter + counter + 1];
                }
            }
        }

        public boolean contains(int x, int y, int width, int height) {
            if (percentValues == null || (lastWidth == width &&
                                          lastHeight == height)) {
                return contains(x, y);
            }
            // Force the bounding box to be recalced.
            bounds = null;
            lastWidth = width;
            lastHeight = height;
            float fWidth = (float)width;
            float fHeight = (float)height;
            for (int counter = percentValues.length - 1; counter >= 0;
                 counter--) {
                if (percentIndexs[counter] % 2 == 0) {
                    // x
                    xpoints[percentIndexs[counter] / 2] =
                            (int)(percentValues[counter] * fWidth);
                }
                else {
                    // y
                    ypoints[percentIndexs[counter] / 2] =
                            (int)(percentValues[counter] * fHeight);
                }
            }
            return contains(x, y);
        }
    }


    /**
     * Used to test for containment in a circular region.
     */
    static class CircleRegionContainment implements RegionContainment {
        /** X origin of the circle. */
        int           x;
        /** Y origin of the circle. */
        int           y;
        /** Radius of the circle. */
        int           radiusSquared;
        /** Non-null indicates one of the values represents a percent. */
        float[]       percentValues;
        /** Last value of width passed in. */
        int           lastWidth;
        /** Last value of height passed in. */
        int           lastHeight;

        public CircleRegionContainment(AttributeSet as) {
            int[]    coords = Map.extractCoords(as.getAttribute(HTML.Attribute.
                                                                COORDS));

            if (coords == null || coords.length != 3) {
                throw new RuntimeException("Unable to parse circular area");
            }
            x = coords[0];
            y = coords[1];
            radiusSquared = coords[2] * coords[2];
            if (coords[0] < 0 || coords[1] < 0 || coords[2] < 0) {
                lastWidth = lastHeight = -1;
                percentValues = new float[3];
                for (int counter = 0; counter < 3; counter++) {
                    if (coords[counter] < 0) {
                        percentValues[counter] = coords[counter] /
                                                 -100.0f;
                    }
                    else {
                        percentValues[counter] = -1.0f;
                    }
                }
            }
            else {
                percentValues = null;
            }
        }

        public boolean contains(int x, int y, int width, int height) {
            if (percentValues != null && (lastWidth != width ||
                                          lastHeight != height)) {
                int      newRad = Math.min(width, height) / 2;

                lastWidth = width;
                lastHeight = height;
                if (percentValues[0] != -1.0f) {
                    this.x = (int)(percentValues[0] * width);
                }
                if (percentValues[1] != -1.0f) {
                    this.y = (int)(percentValues[1] * height);
                }
                if (percentValues[2] != -1.0f) {
                    radiusSquared = (int)(percentValues[2] *
                                   Math.min(width, height));
                    radiusSquared *= radiusSquared;
                }
            }
            return (((x - this.x) * (x - this.x) +
                     (y - this.y) * (y - this.y)) <= radiusSquared);
        }
    }


    /**
     * An implementation that will return true if the x, y location is
     * inside a rectangle defined by origin 0, 0, and width equal to
     * width passed in, and height equal to height passed in.
     */
    static class DefaultRegionContainment implements RegionContainment {
        /** A global shared instance. */
        static DefaultRegionContainment  si = null;

        public static DefaultRegionContainment sharedInstance() {
            if (si == null) {
                si = new DefaultRegionContainment();
            }
            return si;
        }

        public boolean contains(int x, int y, int width, int height) {
            return (x <= width && x >= 0 && y >= 0 && y <= width);
        }
    }
}
