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

package CH.ifa.draw.figures;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.io.IOException;
import java.io.Serial;
import java.util.Vector;

import CH.ifa.draw.standard.BoxHandleKit;
import CH.ifa.draw.util.Geom;
import de.renew.draw.storables.ontology.Connector;
import de.renew.draw.storables.ontology.StorableInput;
import de.renew.draw.storables.ontology.StorableOutput;
import de.renew.draw.ui.ontology.FigureHandle;

/**
 * An ellipse figure.
 */
public class EllipseFigure extends AttributeFigure {
    /*
     * Serialization support.
     */
    @Serial
    private static final long serialVersionUID = -6856203289355118951L;

    /**
     * Determines position and size of the ellipse by
     * specifying position and size of its bounding box.
     *
     * @serial
     **/
    private Rectangle _displayBox;

    /**
     * Unused serial version number.
     */
    @SuppressWarnings("unused")
    private final int _ellipseFigureSerializedDataVersion = 1;

    /**
     * Constructor that sets (0, 0) as point of origin and corner of
     * the Rectangle that is used as display box.
     */
    public EllipseFigure() {
        this(new Point(0, 0), new Point(0, 0));
    }

    /**
     * Constructor that sets the origin and corner of
     * the Rectangle that is used as display box.
     *
     * @param origin Origin of DisplayBox
     * @param corner Corner of DisplayBox
     */
    public EllipseFigure(Point origin, Point corner) {
        basicDisplayBox(origin, corner);
    }

    @Override
    public Vector<FigureHandle> handles() {
        Vector<FigureHandle> handles = new Vector<>();
        BoxHandleKit.addHandles(this, handles);
        //        handles.addElement(new PolygonScaleHandle(this));
        return handles;
    }

    @Override
    public void basicDisplayBox(Point origin, Point corner) {
        _displayBox = new Rectangle(origin);
        _displayBox.add(corner);
    }

    @Override
    public Rectangle displayBox() {
        return new Rectangle(_displayBox.x, _displayBox.y, _displayBox.width, _displayBox.height);
    }

    /**
     * Checks if a point is inside the figure.
     */
    @Override
    public boolean containsPoint(int x, int y) {
        if (super.containsPoint(x, y)) {
            return Geom.ellipseContainsPoint(displayBox(), x, y);
        } else {
            return false;
        }
    }

    @Override
    protected void basicMoveBy(int x, int y) {
        _displayBox.translate(x, y);
    }

    @Override
    public void drawBackground(Graphics g) {
        Rectangle r = displayBox();
        Graphics2D g2 = (Graphics2D) g;
        Shape s = new Ellipse2D.Double(r.x, r.y, r.width, r.height);
        //        g2.rotate(45,r.getCenterX(),r.getCenterY());
        g2.fill(s);
        //        g2.rotate(-45,r.getCenterX(),r.getCenterY());
    }

    @Override
    public void drawFrame(Graphics g) {
        Rectangle r = displayBox();
        Graphics2D g2 = (Graphics2D) g;
        Shape s = new Ellipse2D.Double(r.x, r.y, r.width, r.height);
        //        g2.rotate(45,r.getCenterX(),r.getCenterY());
        g2.draw(s);
    }

    @Override
    public Insets connectionInsets() {
        Rectangle r = _displayBox;
        int cx = r.width / 2;
        int cy = r.height / 2;
        return new Insets(cy, cx, cy, cx);
    }

    @Override
    public Connector connectorAt(int x, int y) {
        return new ChopEllipseConnector(this);
    }

    @Override
    public void write(StorableOutput dw) {
        super.write(dw);
        dw.writeInt(_displayBox.x);
        dw.writeInt(_displayBox.y);
        dw.writeInt(_displayBox.width);
        dw.writeInt(_displayBox.height);
    }

    @Override
    public void read(StorableInput dr) throws IOException {
        super.read(dr);
        _displayBox = new Rectangle(dr.readInt(), dr.readInt(), dr.readInt(), dr.readInt());
    }
}