/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */

package net.sf.jaxodraw.object.arrow;

import java.awt.Graphics2D;
import java.awt.Rectangle;

import java.beans.PropertyChangeListener;

import java.io.Serializable;

import java.text.DecimalFormat;

import net.sf.jaxodraw.gui.panel.edit.JaxoEditPanel;
import net.sf.jaxodraw.object.JaxoObject;


/**
 * An arrow for a JaxoObject.
 */
public interface JaxoArrow
        extends Serializable, Cloneable, PropertyChangeListener {

    /** The decimal format used for numbers in LaTeX output. */
    DecimalFormat D_FORMAT = JaxoObject.D_FORMAT;

    /**
     * Paints the arrow to the given graphics context.
     *
     * @param g2 The graphics context to paint to.
     * @param coords The coordinates of the arrow to paint.
     */
    void paint(Graphics2D g2, Coordinates coords);

    /**
     * Returns an exact copy (clone) of the given JaxoArrow.
     *
     * @return The copy of the given JaxoArrow.
     */
    JaxoArrow copy();

    /**
     * Checks if this Arrow is a copy of the given test Arrow.
     *
     * @param testArrow the Arrow to test against.
     *
     * @return True if the two arrows are equal.
     */
    boolean isCopy(JaxoArrow testArrow);

    /**
     * Returns a bounding rectangle for this arrow at the given coordinates.
     *
     * @param coords The coordinates of the arrow.
     *
     * @return a rectangle that completely contains the arrow.
     */
    Rectangle getBounds(Coordinates coords);

    /**
     * Return a panel that allows to edit the parameters of the arrow.
     *
     * @return an arrow edit panel or null if the arrow cannot be edited.
     */
    JaxoEditPanel getEditPanel();

    /**
     * Returns the arrow part of the latex command for axodraw4j.
     *
     * @param arPos the arrow position.
     * @param scale the current scale.
     *
     * @return the arrow latex command.
     */
    String latexCommand(float arPos, float scale);

    /**
     * The coordinates of an arrow.
     * An arrow is something that has a location and a direction.
     */
    class Coordinates {
        private final double xCoord;
        private final double yCoord;
        private final double angleCoord;

        /**
         * Construct a set of coordinates.
         *
         * @param x the x position of the arrow.
         * @param y the y position of the arrow.
         * @param angle the angle of the arrow.
         */
        public Coordinates(double x, double y, double angle) {
            this.xCoord = x;
            this.yCoord = y;
            this.angleCoord = angle;
        }

        /**
         * Return the x position of the arrow.
         *
         * @return the x position of the arrow.
         */
        public double getX() {
            return xCoord;
        }

        /**
         * Return the y position of the arrow.
         *
         * @return the y position of the arrow.
         */
        public double getY() {
            return yCoord;
        }

        /**
         * Return the angle of the arrow.
         *
         * @return the angle of the arrow.
         */
        public double getAngle() {
            return angleCoord;
        }
    }
}
