/**
 *  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.bezier;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;

import net.sf.jaxodraw.object.JaxoObject;
import net.sf.jaxodraw.object.JaxoObjectEditPanel;
import net.sf.jaxodraw.util.graphics.JaxoGraphics2D;


/**
 * Implementation of a bezier for fermion lines.
 *
 * @since 2.0
 */
public class JaxoFBezier extends JaxoBezierObject {
    private static final long serialVersionUID = 314159L;

    /** {@inheritDoc} */
    @Override
    public final boolean isCopy(final JaxoObject comp) {
        boolean isCopy = false;

        if (comp instanceof JaxoFBezier) {
            isCopy = super.isCopy(comp);
        }

        return isCopy;
    }

    /** {@inheritDoc} */
    public final void paint(final JaxoGraphics2D g2) {
        g2.setColor(getColor());
        g2.setStroke(getStroke());
        g2.draw(getObjectPath());

        if (isPaintArrow()) {
            paintArrow(g2);
        }
    }

    /**
     * Returns the bounding box of this object.
     *
     * @return the bounding box of this object.
     */
    public Rectangle getBounds() {
        // use Area for bounding box calculation instead of gp.getBounds(),
        // see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4599407
        final Rectangle bb =
            getStroke().createStrokedShape(new Area(getObjectPath()))
                .getBounds();

        if (isPaintArrow()) {
            bb.add(getArrow().getBounds(arrowCoordinates()));
        }

        return bb;
    }

    /** {@inheritDoc} */
    public final String latexCommand(final float scale, final Dimension canvasDim) {
        final int canvasHeight = canvasDim.height;
        String arrowCommand = "";
        String jdIdentifier = "%JaxoID:FBez";

        final Point2D latexP1 = getLatexPoint(getX(), getY(), scale, canvasHeight);
        final Point2D latexP2 = getLatexPoint(getX2(), getY2(), scale, canvasHeight);
        final Point2D latexP3 = getLatexPoint(getX3(), getY3(), scale, canvasHeight);
        final Point2D latexP4 = getLatexPoint(getX4(), getY4(), scale, canvasHeight);

        final String command = bezierLatexCommand("", latexP1, latexP2, latexP3, latexP4);

        if (isPaintArrow()) {
            final float k = .0025f;
            final float arrowPosition = getArrowPosition();

            final Point2D b1 = getPointOnCurve(arrowPosition - k);
            final Point2D b2 = getPointOnCurve(arrowPosition + k);
            final Point2D startPoint = getLatexPoint(b1.getX(), b1.getY(), scale, canvasHeight);
            final Point2D endPoint = getLatexPoint(b2.getX(), b2.getY(), scale, canvasHeight);
            final String arrowcmd = getArrowCommand(scale);

            arrowCommand = "\\Line" +  arrowcmd + "("
                + D_FORMAT.format(startPoint.getX()) + ","
                + D_FORMAT.format(startPoint.getY()) + ")" + "("
                + D_FORMAT.format(endPoint.getX()) + ","
                + D_FORMAT.format(endPoint.getY()) + ")";

            jdIdentifier += arrowcmd;
        }

        return command + arrowCommand + jdIdentifier;
    }

    /** {@inheritDoc} */
    public void prepareEditPanel(final JaxoObjectEditPanel editPanel) {
        editPanel.add4PointsPanel(getPoints(), 0, 0, 2);
        //editPanel.addDoubleLinePanel(bezier, 3, 0);
        editPanel.addLineColorPanel(getColor(), 2, 0);
        editPanel.addStrokePanel(getStrokeWidth(), 0, 1);
        //editPanel.addArrowPanel(isPaintArrow(), isFlip(), false, false, 1, 1);
        //editPanel.addArrowPositionPanel(getArrowPosition(), 2, 1);
        editPanel.addArrowPanel(isPaintArrow(), isFlip(), getArrowPosition(), 1, 1);
        editPanel.addArrowOptionsEditPanel(getArrow(), 2, 1);

        editPanel.setTitleAndIcon("Fermion_bezier_parameters", "bezierf.png");
    }

    private GeneralPath getObjectPath() {
        final GeneralPath gp = getGeneralPath();
        gp.reset();

        gp.moveTo(getX(), getY());
        gp.curveTo(getX2(), getY2(), getX3(), getY3(), getX4(), getY4());

        return gp;
    }

}
