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

import java.awt.Dimension;
import java.awt.Graphics;
import java.io.IOException;
import java.io.Serializable;
import java.util.Hashtable;
import java.util.Vector;

import CH.ifa.draw.figures.RectangleFigure;
import CH.ifa.draw.standard.FigureEnumerator;
import CH.ifa.draw.standard.MergedFigureEnumerator;
import de.renew.draw.storables.ontology.Figure;
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.FigureHandle;
import de.renew.remote.ObjectAccessor;
import de.renew.simulatorontology.shadow.ShadowNet;
import de.renew.simulatorontology.shadow.ShadowNetElement;
import de.renew.simulatorontology.shadow.ShadowTransition;


public class TransitionFigure extends RectangleFigure
    implements TransitionNodeFigure, FigureWithHighlight, InscribableFigure, SimulableFigure
{
    /*
     * Serialization support.
     */
    private static final long serialVersionUID = -7877776241236946512L;
    @SuppressWarnings("unused")
    private final int transFigureSerializedDataVersion = 1;

    /**
     * The shadow of this transition figure.
     * Initially <code>null</code>, will be created
     * when needed.
     * <p>
     * This field is transient because its information
     * can be regenerated via <code>buildShadow(...)</code>.
     * </p>
     **/
    private transient ShadowTransition shadow = null;

    /**
     * This figure will be highlighted in a instance
     * drawing in the same manner as the transition
     * will be highlighted. May be <code>null</code>.
     * @serial
     **/
    private Figure hilightFig = null;

    public TransitionFigure() {
        super();
    }

    @Override
    public Vector<FigureHandle> handles() {
        Vector<FigureHandle> handles = super.handles();
        handles.addElement(new ArcConnectionHandle(this));
        return handles;
    }

    @Override
    public final void draw(Graphics g) {
        super.draw(g);
        if (isVisible() && getAttribute(Breakpoint.ATTRIBUTENAME) != null) {
            BreakpointDecoration.draw(g, displayBox());
        }
    }

    public boolean getTraceMode() {
        Object value = getAttribute("TraceMode");
        if (value instanceof Boolean bool) {
            return bool;
        }
        return true;
    }

    @Override
    public void release() {
        super.release();
        if (shadow != null) {
            shadow.discard();
        }
    }

    @Override
    public ShadowNetElement buildShadow(ShadowNet net) {
        shadow = new ShadowTransition(net);
        shadow.setContext(this);
        shadow.setID(this.getID());
        shadow.setTrace(getTraceMode());
        return shadow;
    }

    @Override
    public ShadowNetElement getShadow() {
        return shadow;
    }

    public static Dimension defaultDimension() {
        return new Dimension(24, 16);
    }

    @Override
    public void setHighlightFigure(Figure fig) {
        hilightFig = fig;
    }

    @Override
    public Figure getHighlightFigure() {
        return hilightFig;
    }

    /**
     * Returns all figures with dependencies of the superclass
     * plus an optional hilight figure.
     **/
    @Override
    public FigureEnumeration getFiguresWithDependencies() {
        FigureEnumeration superDep = super.getFiguresWithDependencies();
        Vector<Figure> myDep = new Vector<>(1);
        myDep.addElement(getHighlightFigure());
        return new MergedFigureEnumerator(superDep, new FigureEnumerator(myDep));
    }

    /**
     * Creates an instance figure for this figure.
     * @param drawing The instance drawing to create the figure for.
     * @param netElements The net elements.
     * @return The new instance figure.
     */
    @Override
    public InstanceFigure createInstanceFigure(
        InstanceDrawing drawing, Hashtable<Serializable, ObjectAccessor> netElements)
    {
        return new TransitionInstanceFigure(drawing, this, netElements);
    }

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

    /**
     * Reads the Figure from a StorableInput.
     */
    @Override
    public void read(StorableInput dr) throws IOException {
        super.read(dr);
        if (dr.getVersion() >= 4) {
            setHighlightFigure((Figure) dr.readStorable());
        }
    }

    /**
     * If this a  transition of a non-standard type, return the name of that type.
     * Otherwise return <code>null</code>.
     *
     * It is used by the PNML export to tag transition elements
     * with the necessary information for the import.
     */
    public String transitionSubtype() {
        return null;
    }
}