package de.renew.faformalism.shadow;

import de.renew.simulatorontology.shadow.ShadowNet;
import de.renew.simulatorontology.shadow.ShadowNode;


public class ShadowFAArc extends ShadowNode {
    public static final org.apache.log4j.Logger LOGGER =
        org.apache.log4j.Logger.getLogger(ShadowFAArc.class);
    public ShadowFAState _src;
    public ShadowFAState _dest;
    private boolean _trace;

    /**
     * Defines a shadow arc for an FA from a shadow state
     * to another.
     * @param from                the start state of the arc
     * @param to                the end state of the arc
     */
    public ShadowFAArc(ShadowFAState from, ShadowFAState to) {
        super(ensureIdentity(from, to));

        _src = from;
        _dest = to;

        // The states should remember the Arc
        _src.add(this);
        _dest.add(this);
    }

    /**
     * Returns the net this arc identifies with.
     * Both given states determine this net.
     *
     * @param from  the state, the arc is coming from
     * @param to  the state, the arc is going to
     * @return  the net of the arc
     */
    private static ShadowNet ensureIdentity(ShadowFAState from, ShadowFAState to) {
        if ((from == null) | (to == null)) {
            throw new RuntimeException("Arc must be connected at both ends.");
        }

        // get from-net
        ShadowNet net = (from != null ? from.getNet() : null);

        // compare to to-net
        if (to != null && net != to.getNet()) {
            throw new RuntimeException("Must connect within one net.");
        }

        return net;
    }

    @Override
    public void discard() {
        LOGGER.debug("discard() called by " + this);
        _src.remove(this);
        _dest.remove(this);

        super.discard();
    }

    @Override
    public String toString() {
        return super.toString() + "  [(" + _src.getID() + ") -> (" + _dest.getID() + ")]";
    }

    @Override
    public void setTrace(boolean trace) {
        if (this._trace != trace) {
            this._trace = trace;
        }
    }

    @Override
    public boolean getTrace() {
        return _trace;
    }

    //TODO: readObject
}