/*
 * @(#)VirtualPlaceFigure.java 5.1
 *
 */
package de.renew.gui;

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

import CH.ifa.draw.framework.FigureChangeAdapter;
import CH.ifa.draw.standard.FigureEnumerator;
import CH.ifa.draw.standard.MergedFigureEnumerator;
import de.renew.draw.storables.api.StorableApi;
import de.renew.draw.storables.ontology.Figure;
import de.renew.draw.storables.ontology.FigureChangeEvent;
import de.renew.draw.storables.ontology.FigureEnumeration;
import de.renew.draw.storables.ontology.StorableInput;
import de.renew.draw.storables.ontology.StorableOutput;
import de.renew.draw.ui.ontology.DrawingView;
import de.renew.simulatorontology.shadow.ShadowNet;
import de.renew.simulatorontology.shadow.ShadowNetElement;


public class VirtualPlaceFigure extends PlaceFigure {
    /*
     * Serialization support.
     */
    private static final long serialVersionUID = -7877776241236946511L;
    @SuppressWarnings("unused")
    private final int virtualPlaceFigureSerializedDataVersion = 1;

    /**
     * The place figure which is referenced by this virtual
     * place figure.
     * @serial
     **/
    private PlaceFigure place = null;

    public VirtualPlaceFigure() { // No-Arg-Constructor for loading only!
        super();
    }

    public VirtualPlaceFigure(PlaceFigure place) {
        super();
        setPlace(place);
    }

    private void setPlace(PlaceFigure place) {
        this.place = (PlaceFigure) place.getSemanticFigure();
        adapt();
        final FigureChangeEvent removeEvent = StorableApi.createFigureChangeEvent(this, null);
        place.addFigureChangeListener(new FigureChangeAdapter() {
            @Override
            public void figureChanged(FigureChangeEvent e) {
                adapt();
            }

            @Override
            public void figureRemoved(FigureChangeEvent e) {
                if (listener() != null) {
                    listener().figureRequestRemove(removeEvent);
                }
            }
        });
    }

    /**
     * This method returns the place whose marking is ultimately
     * supposed to be displayed.
     */
    @Override
    public PlaceFigure getSemanticFigure() {
        return (PlaceFigure) place.getSemanticFigure();
    }

    private void adapt() {
        super.setAttribute("FillColor", place.getFillColor());
        super.setAttribute("FrameColor", place.getFrameColor());
    }

    @Override
    public void drawFrame(Graphics g) {
        super.drawFrame(g);
        Rectangle r = displayBox();
        Shape s = new Ellipse2D.Double(r.x + 2, r.y + 2, r.width - 4, r.height - 4);
        ((Graphics2D) g).draw(s);
    }

    @Override
    public ShadowNetElement buildShadow(ShadowNet net) {
        return null;
    }

    @Override
    public ShadowNetElement getShadow() {
        return place.getShadow();
    }

    @Override
    public void setAttribute(String attr, Object value) {
        if ("FillColor".equals(attr) || "FrameColor".equals(attr)) {
            place.setAttribute(attr, value);
        } else {
            super.setAttribute(attr, value);
        }
    }

    @Override
    public boolean inspect(DrawingView view, boolean alternate) {
        if (alternate) {
            return super.inspect(view, true);
        } else {
            view.clearSelection();
            view.addToSelection(place);
            return true;
        }
    }

    @Override
    public FigureEnumeration getFiguresWithDependencies() {
        FigureEnumeration superDep = super.getFiguresWithDependencies();
        Vector<Figure> myDep = new Vector<>(1);
        myDep.addElement(place);
        return new MergedFigureEnumerator(superDep, new FigureEnumerator(myDep));
    }

    /**
      * Stores the Figure to a StorableOutput.
      */
    @Override
    public void write(StorableOutput dw) {
        super.write(dw);
        dw.writeStorable(place);
    }

    /**
     * Reads the Figure from a StorableInput.
     */
    @Override
    public void read(StorableInput dr) throws IOException {
        super.read(dr);
        setPlace((PlaceFigure) dr.readStorable());
    }

    /**
     * Deserialization method, behaves like default readObject
     * method except restoring the connection from this virtual
     * place to the original place.
     **/
    private void readObject(java.io.ObjectInputStream in)
        throws IOException, ClassNotFoundException
    {
        in.defaultReadObject();
        setPlace(place);
    }
}