/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *
 * This file is part of NMM. 
 * 
 * NMM is free software; you can redistribute it and/or modify it    
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; only version 2 of the License.      
 * 
 * NMM is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 
 * License for more details.  
 * 
 * You should have received a copy of the GNU General Public License 
 * along with NMM; if not, write to the Free Software Foundation,    
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */


#include "nmm/comm/IInputJack.idl"
#include "nmm/comm/IOutputJack.idl"


module NMM{

  /** Interface for controlling and configuring a node.
   *
   * This interface is implemented by all nodes. It defines methods for querying and
   * changing the current state of a node, format negotiation, prefetching and requesting
   * jacks.
   */
  interface INode
  {
    /** Types of a node.
     *
     * The type of a node describes its role in a flow graph and
     * its number of input and output streams.
     */
    enum Type {
      UNKNOWN = 0,            ///< Unknown type (used as wildcard in node descriptions)
      SOURCE,                 ///< Source node (no inputs, 1 output)
      SINK,                   ///< Sink node (1 input, no outputs)
      FILTER,                 ///< Filter node (1 input, 1 output, input format == output format)
      CONVERTER,              ///< Converter node (1 input, 1 output)
      MULTIPLEXER,            ///< Multiplexer node (N inputs, 1 output)
      DEMULTIPLEXER,          ///< Demultiplexer node (1 input, N outputs)
      MUX_DEMUX,              ///< Mux/Demux node (N inputs, M outputs)
      COMPOSITE               ///< Composite node (encapsulates a flow graph)
    };

    /** States of a node.
     *
     * The values of this type represent the possible states of a node.
     * All values are powers of 2 and therefore can be used as flags in a bitmask.
     */
    enum State {
      CONSTRUCTED = 1,        ///< The node has been constructed (initial state)
      INITIALIZED = 2,        ///< The node has been initialized
      OUTPUT_INITIALIZED = 4, ///< The node's output has been initialized
      ACTIVATED = 8,          ///< The node has been activated
      STARTED = 16            ///< The node has been started
    };

    /** Change the state of the node.
     * This method puts the node into the given state,
     * performing multiple state transitions if necessary.
     *
     * @param state The state of the node that should be reached
     * @exception StateTransitionFailedException if a state transition has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void reachState(in INode::State state)
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Change the state of the node to CONSTRUCTED.
     * This method puts the node into the COSTRUCTED state,
     * performing multiple state transitions if necessary.
     *
     * @exception StateTransitionFailedException if a state transition has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void reachConstructed()
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Change the state of the node to INITIALIZED.
     * This method puts the node into the INITIALIZED state,
     * performing multiple state transitions if necessary.
     *
     * @exception StateTransitionFailedException if a state transition has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void reachInitialized()
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Change the state of the node to OUTPUT_INITIALIZED.
     * This method puts the node into the OUTPUT_INITIALIZED state,
     * performing multiple state transitions if necessary.
     *
     * @exception StateTransitionFailedException if a state transition has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void reachOutputInitialized()
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Change the state of the node to ACTIVATED.
     * This method puts the node into the ACTIVATED state,
     * performing multiple state transitions if necessary.
     *
     * @exception StateTransitionFailedException if a state transition has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void reachActivated()
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Change the state of the node to STARTED.
     * This method puts the node into the STARTED state,
     * performing multiple state transitions if necessary.
     *
     * @exception StateTransitionFailedException if a state transition has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void reachStarted()
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Set prefetch queue size and enable prefetching.
     * This method enables prefetching for the node. It may only be called in state CONSTRUCTED.
     * If prefetching is enabled using this method, the node will not start processing data
     * before at least the given number of messages have been queued in its input queue.
     *
     * @param pre_fetch_queue_size Number of messages to prefetch
     */
    void setPrefetchQueueSize(in nmm_uint32 pre_fetch_queue_size) limited(INode::CONSTRUCTED);

    /** Set prefetch queue duration and enable prefetching.
     * This method enables prefetching for the node. It may only be called in state CONSTRUCTED.
     * If prefetching is enabled using this method, the node will not start processing data
     * before messages with at least the given total duration have been queued in its input queue.
     *
     * @param pre_fetch_queue_duration Total duration to prefetch
     */
    void setPrefetchQueueDuration(in Interval pre_fetch_queue_duration) limited(INode::CONSTRUCTED);

    /** Get the prefetch queue size.
     * This method gets the number of messages to be prefetched if prefetching was enabled
     * with setPrefetchQueueSize. Otherwise, it returns zero.
     *
     * @return Number of messages to prefetch or 0
     */
    nmm_uint32 getPrefetchQueueSize();

    /** Wait until prefetching is finished.
     * This method waits until the process of prefetching is finished, i.e. the
     * number of messages in the input queue or their total duration has reached
     * the value specified by setPrefetchQueueSize or setPrefetchQueueDuration.
     * This method may only to be called in state ACTIVATED.
     */
    void waitPrefetchFinished() limited(INode::ACTIVATED);

    /** Perform state transition from CONSTRUCTED to INITIALIZED.
     * This method changes the state and invokes the doInit method of the node.
     * The state transition fails if doInit fails or a required interface method for this
     * state transition has not been called successfully.
     *
     * @exception StateTransitionFailedException if doInit has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void init() limited(INode::CONSTRUCTED)
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Perform state transition from INITIALIZED to OUTPUT_INITIALIZED.
     * This method changes the state and invokes the doInitOutput method of the node.
     * The state transition fails if doInitOutput fails or a required interface method for this
     * state transition has not been called successfully.
     *
     * @exception StateTransitionFailedException if doInitOutput has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void initOutput() limited(INode::INITIALIZED)
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException) ;

    /** Perform state transition from OUTPUT_INITIALIZED to ACTIVATED.
     * This method changes the state and invokes the doActivate method of the node.
     * The state transition fails if doActivate fails or a required interface method for this
     * state transition has not been called successfully.
     *
     * @exception StateTransitionFailedException if doActivate has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void activate() limited(INode::OUTPUT_INITIALIZED)
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Flush the input queue of the node.
     * This method flushes the queues of all input jacks of the node.
     * It may only be called in state ACTIVATED or STARTED.
     *
     * @return SUCCESS if the method succeeded, otherwisew FAILURE
     */
    Result flush() limited(INode::ACTIVATED) limited(INode::STARTED);

    /** Perform state transition from ACTIVATED to STARTED.
     * This method changes the state and invokes the doStart method of the node.
     * The state transition fails if doStart fails or a required interface method for this
     * state transition has not been called successfully.
     *
     * @exception StateTransitionFailedException if doStart has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void start() limited(INode::ACTIVATED)
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException)  ;

    /** Perform state transition from STARTED to ACTIVATED.
     * This method changes the state and invokes the doStop method of the node.
     * The state transition fails if doStop fails or a required interface method for this
     * state transition has not been called successfully.
     *
     * @exception StateTransitionFailedException if doStop has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void stop() limited(INode::STARTED)
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Perform state transition from ACTIVATED to OUTPUT_INITIALIZED.
     * This method changes the state and invokes the doDeactivate method of the node.
     * The state transition fails if doDeactivate fails or a required interface method for this
     * state transition has not been called successfully.
     *
     * @exception StateTransitionFailedException if doDeactivate has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void deactivate() limited(INode::ACTIVATED)
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Perform state transition from OUTPUT_INITIALIZED to INITIALIZED.
     * This method changes the state and invokes the doDeinitOutput method of the node.
     * The state transition fails if doDeinitOutput fails or a required interface method for this
     * state transition has not been called successfully.
     *
     * @exception StateTransitionFailedException if doDeinitOutput has failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void deinitOutput() limited(INode::OUTPUT_INITIALIZED)
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Perform state transition from INITIALIZED to CONSTRUCTED.
     * This method changes the state and invokes the doDeinit method of the node.
     * The state transition fails if doDeinit fails or a required interface method for this
     * state transition has not been called successfully.
     *
     * @exception StateTransitionFailedException if doDeinithas failed
     * @exception UnsuccessfulRequiredCallException if a required interface method was not called successfully
     */
    void deinit() limited(INode::INITIALIZED)
      raises (StateTransitionFailedException, UnsuccessfulRequiredCallException);

    /** Check if the node is in CONSTRUCTED state.
     *
     * @return @c true if the node is in state CONSTRUCTED, otherwise @c false
     */
    nmm_bool isConstructed()        const;

    /** Check if the node is in INITIALIZED state.
     *
     * @return @c true if the node is in state INITIALIZED, otherwise @c false
     */
    nmm_bool isInitialized()        const;

    /** Check if the node is in OUTPUT_INITIALIZED state.
     *
     * @return @c true if the node is in state OUTPUT_INITIALIZED, otherwise @c false
     */
    nmm_bool isOutputInitialized()  const;

    /** Check if the node is in ACTIVATED state.
     *
     * @return @c true if the node is in state ACTIVATED, otherwise @c false
     */
    nmm_bool isActivated()          const;

    /** Check if the node is in STARTED state.
     *
     * @return @c true if the node is in state STARTED, otherwise @c false
     */
    nmm_bool isStarted()            const;

    /** Request an input jack.
     * This method requests an input jack with the given format and jack tag
     * and returns an interface to the requested jack.
     * If the request fails, a null pointer is returned.
     * The caller is responsible for deleting the jack interface.
     *
     * This method may only be called in state INITIALIZED.
     *
     * @param format The format of the jack
     * @param jack_tag The name of an input stream
     * @return An interface to the requested jack or 0
     */
    IInputJack* getInputJack(in Format format, in string jack_tag) limited(INode::INITIALIZED);

    /** Get an interface to a connected input jack.
     * This method returns an interface to an existing and connected input jack with the
     * given jack tag. If no such jack exists, a null pointer is returned.
     * The caller is responsible for deleting the jack interface.
     *
     * @param jack_tag The name of an input stream
     * @return An interface to the existing and connected jack or 0
     */
    IInputJack* getInputStream(in string jack_tag ) limited(INode::INITIALIZED);
      
    /** Get all input stream tags.
     * This method returns a list of the jack tags of all input streams of the node.
     *
     * @return List of input streams as jack tags
     */
    list<string> getInputStreamTags() const;

    /** Check if an input stream is connected.
     * This method returns a flag which indicates if the input stream
     * with the given jack tag is connected.
     * If no such stream exists, the result is @c false.
     *
     * @param jack_tag The name of an input stream
     * @return @c true if the stream is connected, @c false if the stream is not connected or does not exist
     */
    nmm_bool isInputConnected(in string jack_tag = "default") const;

    /** Get the format of an input stream.
     * This method returns the connection format of the given stream if the stream is connected.
     * If the stream is not connected or does not exist, a null pointer is returned.
     * The caller is responsible for deleting the returned Format object.
     *
     * @param jack_tag The name of an input stream
     * @returns A pointer to a Format object describing the connection format or 0
     */
    Format* getInputStreamFormat(in string jack_tag = "default");

    /** Request an output jack.
     * This method requests an output jack with the given format and jack tag
     * and returns an interface to the requested jack.
     * If the request fails, a null pointer is returned.
     * The caller is responsible for deleting the jack interface.
     *
     * This method may only be called in state OUTPUT_INITIALIZED.
     *
     * @param format The format of the jack
     * @param jack_tag The name of an output stream
     * @return An interface to the requested jack or 0
     */
     IOutputJack* getOutputJack(in Format format, in string jack_tag) limited(INode::OUTPUT_INITIALIZED);

     /** Request an output jack.
     * This method requests an output jack with the given format and jack tag
     * and returns an interface to the requested jack.
     * If the request fails, a null pointer is returned.
     * The caller is responsible for deleting the jack interface.
     *
     * Unlike getOutputJack, this method may only be called in state INITIALIZED.
     * This method bypasses format negotiation and should only be used for debugging.
     *
     * @param format The format of the jack
     * @param jack_tag The name of an output stream
     * @return An interface to the requested jack or 0
     */
     IOutputJack* getUnintializedOutputJack(in Format format, in string jack_tag) limited(INode::INITIALIZED);

    /** Get an interface to a connected output jack.
     * This method returns an interface to an existing and connected output jack with the
     * given jack tag. If no such jack exists, a null pointer is returned.
     * The caller is responsible for deleting the jack interface.
     *
     * @param jack_tag The name of an output stream
     * @return An interface to the existing and connected jack or 0
     */
    IOutputJack* getOutputStream(in string jack_tag) limited(INode::OUTPUT_INITIALIZED);

    /** Get all output stream tags.
     * This method returns a list of the jack tags of all output streams of the node.
     *
     * @return List of output streams as jack tags
     */
    list<string> getOutputStreamTags() const;

    /** Check if an output stream is connected.
     * This method returns a flag which indicates if the output stream
     * with the given jack tag is connected.
     * If no such stream exists, the result is @c false.
     *
     * @param jack_tag The name of an output stream
     * @return @c true if the stream is connected, @c false if the stream is not connected or does not exist
     */
    nmm_bool isOutputConnected(in string jack_tag = "default") const;

    /** Clone an output jack.
     * This method requests a clone of an existing and connected output jack with the
     * given jack tag.
     * It returns an interface to the cloned jack and the connection format.
     * The cloned jack is unconnected.
     * If no matching jack exists, a null pointer is returned.
     * The caller is responsible for deleting the jack interface and the returned
     * format object.
     *
     * This method is used for connecting an output jack to multiple input jacks.
     *
     * @param jack_tag The name of an output stream
     * @param intersec_format Returns a pointer to a Format object describing the connection format or 0
     * @return An interface to the cloned jack or 0
     */
    IOutputJack* cloneOutputJack(out Format* intersec_format, in string jack_tag = "default") 
      limited(INode::OUTPUT_INITIALIZED) limited(INode::ACTIVATED);

    /** Get the format of an output stream.
     * This method returns the connection format of the given stream if the stream is connected.
     * If the stream is not connected or does not exist, a null pointer is returned.
     * The caller is responsible for deleting the returned Format object.
     *
     * @param jack_tag The name of an output stream
     * @returns A pointer to a Format object describing the connection format or 0
     */
    Format* getOutputStreamFormat(in string jack_tag = "default");

    /** Get the cost of an input stream.
     * This method returns the cost of the input stream with the given jack tag.
     * If no such stream exists, the returned cost is zero.
     *
     * @param jack_tag The name of an input stream
     * @return The cost of the stream or zero
     *
     * @deprecated This interface is part of the resource manager which is not available in this release
     */
    nmm_float getCost(in string jack_tag) const;


    /** Get the type of the node.
     *
     * @return The type of the node
     */
    INode::Type getType() const;

    /** Get the current state of the node.
     *
     * @return The current state of the node
     */
    INode::State getState() const;

    /** Get the input property of the node.
     * This method returns a copy of the input property of the node.
     * The input property is the set of formats which are supported by the input streams of the node.
     * The caller is responsible for deleting the returned Property object.
     *
     * The input property is valid in the states INITIALIZED, OUTPUT_INITIALIZED, ACTIVATED and STARTED.
     * In all other states, the property is empty.
     *
     * @return A pointer to a Property object describing the set of formats
     */
     Property* getInputProperty();

    /** Get the working input property of the node.
     * This method returns a copy of the working input property of the node.
     * The working input property is the set of formats which are supported by the input streams of the node
     * with the current configuration of connected input streams.
     * The caller is responsible for deleting the returned Property object.
     *
     * The input property is valid in the states OUTPUT_INITIALIZED, ACTIVATED and STARTED.
     * In all other states, the property is empty.
     *
     * @return A pointer to a Property object describing the set of formats
     */
     Property* getWorkingInputProperty();

    /** Get the output property of the node.
     * This method returns a copy of the output property of the node.
     * The output property is the set of formats which are supported by the output streams of the node.
     * The caller is responsible for deleting the returned Property object.
     *
     * The output property is valid in the states INITIALIZED, OUTPUT_INITIALIZED, ACTIVATED and STARTED.
     * In all other states, the property is empty.
     *
     * @return A pointer to a Property object describing the set of formats
     */
     Property* getOutputProperty();

    /** Get the working output property of the node.
     * This method returns a copy of the working output property of the node.
     * The working output property is the set of formats which are supported by the output streams of the node
     * with the current configuration of connected input streams.
     * The caller is responsible for deleting the returned Property object.
     *
     * The output property is valid in the states OUTPUT_INITIALIZED, ACTIVATED and STARTED.
     * In all other states, the property is empty.
     *
     * @return A pointer to a Property object describing the set of formats
     */
     Property* getWorkingOutputProperty();

    /** Get the computation configuration of the node.
     * This method returns a copy of the computation configuration of the node.
     * The computation configuration is a set of parameters which control the operation of a node and which
     * are not parameters of input and output formats, such as quality parameters of an encoder.
     * The caller is responsible for deleting the returned ComputationConfig object.
     *
     * The computation configuration is valid in the states INITIALIZED, OUTPUT_INITIALIZED, ACTIVATED and STARTED.
     * In all other states, the configuration has no parameters.
     *
     * @return A pointer to a ComputationConfig object describing the computation configuration
     *
     * @deprecated This interface is part of the resource manager which is not available in this release
     */
     ComputationConfig* getComputationConfig() const;

    /** Get the working computation configuration of the node.
     * This method returns a copy of the working computation configuration of the node.
     * working The computation configuration is a set of parameters which control the operation of a node and which
     * are not parameters of input and output formats, such as quality parameters of an encoder.
     * Unlike the computation configuration, the working computation configuration also depends on the configuration
     * of connected input streams.
     * The caller is responsible for deleting the returned ComputationConfig object.
     *
     * The working computation configuration is valid in the states OUTPUT_INITIALIZED, ACTIVATED and STARTED.
     * In all other states, the configuration has no parameters.
     *
     * @return A pointer to a ComputationConfig object describing the computation configuration
     *
     * @deprecated This interface is part of the resource manager which is not available in this release
     */
     ComputationConfig* getWorkingComputationConfig() const;

    /** Set the computation configuration of the node.
     *
     * @param computation_config A computation configuration
     *
     * @deprecated This interface is part of the resource manager which is not available in this release
     */
    void setComputationConfig(in ComputationConfig* computation_config);

    /** Set the working computation configuration of the node.
     *
     * @param computation_config A computation configuration
     *
     * @deprecated This interface is part of the resource manager which is not available in this release
     */
    void setWorkingComputationConfig(in ComputationConfig* computation_config);

    /** Get the internal cost of the node.
     *
     * This method returns the cost of all internal computation performed by a node
     * which is not dependent on input and output format parameters.
     *
     * @return The internal cost of the node
     *
     * @deprecated This interface is part of the resource manager which is not available in this release
     */
    nmm_float getInternalCost() const;

    /** Request data from the predecessor node.
     * This is an instream event which is used by dynamic data analysis.
     * It is sent internally between nodes and should not be sent manually by applications or plug-ins.
     *
     * @return DELETE
     */
    Result sendData() limited(INode::OUTPUT_INITIALIZED) limited(INode::ACTIVATED) limited(INode::STARTED) instream;

    /** Data request from the predecessor node has failed.
     * This is an instream event which is used by dynamic data analysis.
     * It is sent internally between nodes and should not be sent manually by applications or plug-ins.
     *
     * @return DELETE
     */
    Result sendDataFailed() limited(INode::INITIALIZED) instream;
  };
}
