/*
 * @(#)ChopEllipseConnector.java 5.1
 *
 */

package CH.ifa.draw.figures;

import java.awt.Point;
import java.awt.Rectangle;

import org.apache.log4j.Logger;

import CH.ifa.draw.standard.ChopBoxConnector;
import CH.ifa.draw.util.Geom;
import de.renew.draw.storables.ontology.Figure;

/**
 * A ChopPieConnector is a modification of the {@link ChopEllipseConnector}
 * that locates a connection point by chopping the connection at the
 * ellipse defined by the figure's display box, unless the corresponding
 * arc segment is outside the start/end angles of the pie figure.
 * <p>
 * Created: 13 Jul 2008
 *
 * @author Michael Duvigneau
 **/
public class ChopPieConnector extends ChopBoxConnector {
    /** Logger used by the class */
    public static final Logger LOGGER = Logger.getLogger(ChopPieConnector.class);

    /*
     * Serialization support.
     */

    //private static final long serialVersionUID = ;
    /**
     * Owner of the instance.
     */
    private PieFigure _pieFig;

    /**
     * Constructs a new ChopPieConnector.
     */
    public ChopPieConnector() {}

    /**
     * Constructs a new ChopPieConnector.
     *
     * @param owner the figure to which this connector is attached
     */
    public ChopPieConnector(PieFigure owner) {
        super(owner);
        this._pieFig = owner;
    }

    @Override
    protected Point chop(Figure target, Rectangle source) {
        Rectangle r = target.displayBox();
        Point from = Geom.center(source);
        double angleRad =
            Geom.pointToAngle(r, from) + (r.intersection(source).equals(r) ? Math.PI : 0);

        // Compare angle on ellipse with angle of arc/pie.
        // however, the first is given in radian, the latter in degrees
        // however, this is possible only if we know our pie angles.
        if (_pieFig != null) {
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug(
                    "Chopping for pieFig=" + _pieFig + ", given target=" + target
                        + ", given source=" + source + ".");
            }
            double angleDeg = PieFigure.normalizeAngle(-Math.toDegrees(angleRad));
            double chosenAngle = angleDeg;
            if (LOGGER.isDebugEnabled()) {
                LOGGER.debug(
                    "   Angles are: angle_rad=" + angleRad + ", angle_deg=" + angleDeg
                        + ", pieFig.getStartAngle()=" + _pieFig.getStartAngle()
                        + ", pieFig.getEndAngle()=" + _pieFig.getEndAngle() + ".");
            }
            if (_pieFig.getStartAngle() < _pieFig.getEndAngle()) {
                LOGGER.debug("   start < end");
                if (angleDeg < _pieFig.getStartAngle()) {
                    LOGGER.debug("   angle < start < end");
                    // We are outside the arc segment on the ellipse
                    // (angle between zero and start).
                    // Compute the nearest arc end point and return it.
                    if ((_pieFig.getStartAngle() - angleDeg) < (angleDeg + 360
                        - _pieFig.getEndAngle())) {
                        chosenAngle = _pieFig.getStartAngle();
                    } else {
                        chosenAngle = _pieFig.getEndAngle();
                    }
                } else if (_pieFig.getEndAngle() < angleDeg) {
                    LOGGER.debug("   start < end < angle");
                    // We are outside the arc segment on the ellipse
                    // (angle between end and zero).
                    // Compute the nearest arc end point and return it.
                    if ((_pieFig.getStartAngle() + 360 - angleDeg) < (angleDeg
                        - _pieFig.getEndAngle())) {
                        chosenAngle = _pieFig.getStartAngle();
                    } else {
                        chosenAngle = _pieFig.getEndAngle();
                    }
                }
            } else if ((_pieFig.getStartAngle() > _pieFig.getEndAngle())
                && (_pieFig.getStartAngle() > angleDeg) && (angleDeg > _pieFig.getEndAngle())) {
                LOGGER.debug("   end < angle < start");
                // we are outside the arc segment on the ellipse
                // (angle between end and start)
                // Compute the nearest arc end point and return it.
                if ((_pieFig.getStartAngle() - angleDeg) < (angleDeg - _pieFig.getEndAngle())) {
                    chosenAngle = _pieFig.getStartAngle();
                } else {
                    chosenAngle = _pieFig.getEndAngle();
                }
            }
            if (chosenAngle != angleDeg) {
                angleRad = -Math.toRadians(chosenAngle);
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug(
                        "   chosen angle is: deg=" + chosenAngle + ", rad=" + angleRad + ".");
                }
            } else {
                LOGGER.debug("   chosen angle is unchanged.");
            }
        }
        return Geom.ovalAngleToPoint(r, angleRad);
    }
}