package nxm.sys.inc;

/** Interface Definitions for Commandable Objects. Commandable objects are
    objects that perform some type of computation in response to external
    directives. <br>
    <br>
    This interface defines the following:
    <ul>
      <li>Command Status Indicators:     {@link #NOOP},    {@link #NORMAL},
                                         {@link #FINISH},  {@link #SLEEP}</li>

      <li>Command State Indicators:      {@link #INIT},    {@link #OPEN},
                                         {@link #PROCESS}, {@link #SUSPEND},
                                         {@link #CLOSE},   {@link #EXIT},
                                         {@link #DONE}</li>

      <li>Command Sequence Directives:   {@link #START},   {@link #STOP}
                                         {@link #RESTART}, {@link #ABORT}
                                         {@link #PAUSE},   {@link #RESUME}</li>

      <li>Command Functionality Methods: {@link #open},    {@link #process},
                                         {@link #close}</li>
    </ul><br>
    <br>
    <h2><a id="state_diagram">State Diagram for a Commandable Object</a></h2>
    The following is a typical state diagram that most Commandable objects
    follow (for example, see {@link nxm.sys.lib.Command#run()}).<br>
    <br>
    All Commandable objecst should start in the {@link #INIT} and progress
    through the different states (in response to external directives) until
    the Commandable object has finished its computation.
    <pre>
    <b>
    DIRECTIVE                     STATE
    ----------------------------------------------------------------------------
    </b>
    START-------------------------------------------------------------+
                                                                      |
                                                                      |
                                                                      v
                                  +-------------+              +-------------+
    STOP------[State != INIT]-----| CLOSE State |-------------&gt;| INIT  State |
                                  |-------------|              |-------------|
                                  | do: close() |              | do:         |
                                  +-------------+              +-------------+
                                                                      |
                                                                      v
                                  +-------------+              +-------------+
    RESTART---[State != INIT]----&gt;| CLOSE State |-------------&gt;| OPEN  State |
                                  |-------------|              |-------------|
                                  | do: close() |              | do: open()  |
                                  +-------------+              +-------------+
                                                                      |
                           +-------------------[Status == FINISH ]&lt;---+
                           |                                          |
                           |                                  [Status != FINISH]
                           |                                          |
                           |                                          v
                           |                                   +-------------+
    RESUME----------------------------------------------------&gt;|PROCESS State|
                           |                                   |-------------|
                           |               +------------------&gt;|do: process()|
                           |               |                   +-------------+
                           |               |                          |
                           |               +---[Status == NORMAL ]&lt;---+
                           |               |                          |
                           |               +---[Status == NOOP   ]&lt;---+
                           |               |    do: Time.sleep(..)    |
                           |               |                          |
                           |               +---[Status == SLEEP  ]&lt;---+
                           |                    do: Time.sleep(..)    |
                           |                                          |
                           |                                          |
                           |                                          |
                           |               +---[Status == PAUSE  ]&lt;---+
                           |               |                          |
                           |               +---[Status == SUSPEND]&lt;---+
                           |               |                          |
                           |               v                          |
                           |      +-----------------+         [Status == FINISH]
    PAUSE------------------------&gt;|  SUSPEND State  |                 |
                           |      |-----------------|                 v
                           |      |do:Time.sleep(..)|          +-------------+
                           |      +-----------------+          | CLOSE State |
                           |                                   |-------------|
                           +----------------------------------&gt;|do: close()  |
                                                               +-------------+
                                                                      |
                                                                      v
                                                               +-------------+
    ABORT-----------------------------------------------------&gt;| EXIT  State |
                                                               |-------------|
                                                               | do:         |
                                                               +-------------+
                                                                      |
                                                                      v
                                                               +-------------+
                                                               | DONE  State |
                                                               |-------------|
                                                               | do:         |
                                                               +-------------+

    <b>
    ----------------------------------------------------------------------------
    </b>
    </pre>
    @author Jeff Schoen

    @see nxm.sys.lib.Command#run()
    @see nxm.sys.lib.Time#sleep(double)
 */
public interface Commandable {

  /** Command status indicating that a command is not doing any work. */
  int NOOP = -1;

  /** Command status indicating that a command is working normally. */
  int NORMAL = 0;

  /** Command states indicating that a command is in the initialization state.*/
  int INIT = 0;

  /** Command states indicating that a command is in the opening state. */
  int OPEN = 1;

  /** Command states indicating that a command is in the waiting state. */
  int WAIT = -1;

  /** Command states indicating that a command is in the processing state. */
  int PROCESS = 2;

  /** Command states indicating that a command is in the suspended state. */
  int SUSPEND = -2;

  /** Command states indicating that a command is in the closing state. */
  int CLOSE = 3;

  /** Command states indicating that a command is in the exiting state. */
  int EXIT = -3;

  /** Command states indicating that a command is in the done state. */
  int DONE = 4;

  /** Command sequence directive indicating that a command should start. */
  int START = 5;

  /** Command sequence directive indicating that a command should stop. */
  int STOP = 6;

  /** Command sequence directive indicating that a command should restart. */
  int RESTART = 7;

  /** Command sequence directive indicating that a command should sleep. */
  int SLEEP = 8;

  /** Command sequence directive indicating that a command should finish. */
  int FINISH = 9;

  /** Command sequence directive indicating that a command should abort. */
  int ABORT = 10;

  /** Command sequence directive indicating that a command should pause. */
  int PAUSE = 11;

  /** Command sequence directive indicating that a command should resume. */
  int RESUME = 12;

  /** The comma-command list of states.
      @see #stateListOffset
   */
  String stateList
    = "Exit,Suspend,Wait,Init,Open,Process,Close,Done,Start,"
    + "Stop,Restart,Sleep,Finish,Abort,Pause,Resume";

  /** This is the offset necessary to index into the list of states
      ({@link #stateList}). For example: this means that the string
      corresponding to the {@link #DONE} value would be element number
      <code>DONE + stateListOffset</code> in {@link #stateList}.
      @see #stateList
   */
  int stateListOffset = -4;

  /** This will prepare the commandable object for processing. This method must
      be called prior to calling {@link #process()} and should be used to open
      any files needed and to initialize any parameters.

      @return <ul>
                <li>{@link #NOOP}   if this method does no work.</li>
                <li>{@link #NORMAL} if this method successfully completes and
                                    the Commandable object is ready to be
                                    processed with {@link #process()}.</li>
                <li>{@link #FINISH} if this method successfully completes
                                    and the Commandable object does not require
                                    any processing with {@link #process()} (i.e.
                                    skip directly to {@link #close()}).</li>
              </ul>

      @see #process()
      @see #close()
      @see <a href="../../../nxm/sys/inc/Commandable.html#state_diagram">
           State Diagram for a Commandable Object</a>
   */
  int open();

  /** This will process the commandable objects algorithm. The {@link #open()}
      method will always be called before this method. This should be
      responsible for doing any of the data processing required by the
      commandable object.<br>
      <br>
      If the commandable object requires multiple processing cycles it will
      return {@link #NORMAL} or {@link #NOOP}.

      @return <ul>
                <li>{@link #NORMAL} upon completion of a single pass of the
                                    algorithm.</li>
                <li>{@link #FINISH} upon successful completion of the entire
                                    algorithm.</li>
                <li>{@link #NOOP  } upon completion of a single pass of the
                                    algorithm in which no work was performed
                                    (this usually indicates that the object is
                                    waiting for another thread to provide data
                                    to process).</li>
                <li>{@link #SLEEP}  upon completion of a single pass of the
                                    algorithm where a pause (see
                                    {@link nxm.sys.lib.Time#sleep(double)}) is
                                    required before {@link #process()} can be
                                    called again.</li>
                <li>{@link #PAUSE}
                    or {@link #SUSPEND} indicates that the Commandable object
                                        should be placed in the {@link #SUSPEND}
                                        state until the {@link #RESUME}
                                        directive is given.</li>
              </ul>

      @see nxm.sys.lib.Time#sleep(double)
      @see #open()
      @see #close()
      @see <a href="../../../nxm/sys/inc/Commandable.html#state_diagram">
           State Diagram for a Commandable Object</a>
   */
  int process();

  /** This will finish the commandable objects processing. This method
      is to be used to "clean up" after running {@link #open()} and
      {@link #process()}; this includes closing any files opened by
      {@link #open()} and clearing any temporary data used by
      {@link #process()}. This is the stage where the commandable object
      would typically perform any final reporting of data (such as the
      setting of RESULTS parameters).

      @return <ul>
                <li>{@link #NOOP}   if this method does no work.</li>
                <li>{@link #NORMAL} if this method successfully completes.</li>
              </ul>

      @see nxm.sys.lib.Results
      @see #open()
      @see #process()
      @see <a href="../../../nxm/sys/inc/Commandable.html#state_diagram">
           State Diagram for a Commandable Object</a>
   */
  int close();
} // end interface Commandable