package de.renew.gui;

import de.renew.net.Net;

/**
 * Breakpoints observe the simulation of a net and stop
 * its execution if a certain event occurs.
 * An overview of different observation techniques is
 * given in the {@link BreakpointManager}.
 *
 * <p>This interface has to be implemented by all breakpoints
 * manageable by the {@link BreakpointManager}.
 * It also supplies common constants for implementations.
 *
 * @author Michael Duvigneau
 */
public interface Breakpoint {

    /**
     * The name of the attribute of place or transition figures
     * in which the information concerning breakpoints is stored.
     *
     * <p>Figures marked in this way will get an attached breakpoint
     * when the next simulation starts.
     * The value of the attribute is an {@link Integer} object
     * representing the mode of the breakpoint to create.
     * Created breakpoints will always be global, e.g. hittable
     * at all instances of the corresponding net element.
     **/
    String ATTRIBUTENAME = "BreakpointMode";

    /**
     * Breakpoint mode:
     * Default mode, depends on the observed net element.
     *
     * The default mode is
     *   FIRE for transition instances,
     *   MARKINGCHANGE for place instances,
     *   ...
     * @see #FIRE
     * @see #MARKINGCHANGE
     **/
    int DEFAULT = 0;

    /**
     * Breakpoint mode:
     * Stops execution if a transition instance starts firing.
     * @see TransitionInstanceBreakpoint
     **/
    int FIRE = 1;

    /**
     * Breakpoint mode:
     * Stops execution if a transition instance completes firing.
     * @see TransitionInstanceBreakpoint
     **/
    int FIRECOMPLETE = 2;

    /**
     * Breakpoint mode:
     * Stops execution if a place instance's marking changes,
     * e.g. one or more tokens are added, removed or tested.
     * <p>
     * Testing and untesting tokens via test arcs is considered
     * as a marking change in this mode. If you want to ignore
     * test arcs, use <code>MARKINGCHANGENOTEST</code>.
     * </p>
     *
     * @see PlaceInstanceBreakpoint
     * @see #MARKINGCHANGENOTEST
     **/
    int MARKINGCHANGE = 3;

    /**
     * Stops execution if any instance of a transition fires.
     *
     * @deprecated this mode is no longer in use, as the mode {@link #FIRE}
     * offers the same functionality when breakpoints with this
     * mode are attached to transitions instead of transition instances.
     **/
    @Deprecated(forRemoval = true)
    int INSCRIPTION = 4;

    /**
     * Breakpoint mode:
     * Stops execution if a place instance's marking changes,
     * e.g. one or more tokens are added or removed.
     * <p>
     * Testing and untesting tokens via test arcs is ignored
     * in this mode. If you want to pay attention to such
     * changes, too, use <code>MARKINGCHANGE</code>.
     * </p>
     *
     * @see PlaceInstanceBreakpoint
     * @see #MARKINGCHANGE
     **/
    int MARKINGCHANGENOTEST = 5;

    /**
     * Breakpoint mode:
     * Stops execution if a place instance's marking changes
     * by adding exactly one token.
     *
     * @see PlaceInstanceBreakpoint
     **/
    int TOKENADDED = 6;

    /**
     * Breakpoint mode:
     * Stops execution if a place instance's marking changes
     * by removing exactly one token.
     *
     * @see PlaceInstanceBreakpoint
     **/
    int TOKENREMOVED = 7;

    /**
     * Breakpoint mode:
     * Stops execution if a place instance's marking changes
     * the test status of one or more tokens.
     *
     * @see PlaceInstanceBreakpoint
     **/
    int TOKENTESTCHANGE = 8;

    /**
     * Returns the transition or place (or a transition/place instance)
     * instance which is observed by the breakpoint.
     *
     * <p>If a static transition or place is returned, all its
     * instances are observed.
     * The instance which was most recently hit will be
     * returned via {@link #getHitElement()}.
     * To get the net the transition or place belongs to,
     * use {@link #getTaggedNet()}.
     *
     * @return the element observed by the breakpoint
     **/
    Object getTaggedElement();

    /**
     * Returns the transition or place instance at which the
     * breakpoint was most recently hit.
     *
     * <p>To get the net element the breakpoint was originally
     * attached to use {@link #getTaggedElement()}.
     *
     * @return the element at which the breakpoint was most recently hit
     *         or {@code null} if the breakpoint was never hit since its creation
     **/
    Object getHitElement();

    /**
     * Returns the net to which the observed place or
     * transition belongs.
     *
     * <p>This method is needed to be able to show the tagged
     * element because places and transitions do not know
     * their net by themselves.
     *
     * @return the net to which this breakpoint belongs
     **/
    Net getTaggedNet();

    /**
     * Releases all resources, unregisters from any event
     * producers and undoes all modifications to the net
     * done at the breakpoint's creation.
     *
     * <p>This method is invoked when the breakpoint is removed from a net.
     **/
    void release();
}
