/* 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.
 *
 */

#ifndef NMM_CONNECT_HPP
#define NMM_CONNECT_HPP NMM_CONNECT_HPP

#include "nmm/nmm_prefix.hpp"

#include "INode.hpp"

#include "nmm/comm/InstreamChannel.hpp"
#include "nmm/comm/UnbindingException.hpp"

#include "visibility.hpp"

namespace NMM {

  // INode connect
  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @param connection_format (out) Returns the connection format
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode* n1, const string& out_jack,
                         INode* n2, const string& in_jack,
                         const Format* format, Format* connection_format)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode* n1, const string& out_jack, 
                         INode* n2, const string& in_jack, 
                         const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param format Requested connection format
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode* n1,  
                         INode* n2,  
                         const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param format Requested connection format
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode* n1, const string& out_jack, 
                         INode* n2,  
                         const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode* n1,  
                         INode* n2, const string& in_jack, 
                         const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode* n1, const string& out_jack, 
                         INode* n2, const string& in_jack)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode* n1,  
                         INode* n2)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode* n1, const string& out_jack,
                         INode* n2)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode* n1,
                         INode* n2, const string& in_jack)
    throw(const BindingException&);

  // INode_var connect
  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @param connection_format (out) Returns the connection format
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode_var& n1, const string& out_jack,
                         INode_var& n2, const string& in_jack,
                         const Format* format, Format* connection_format)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode_var& n1, const string& out_jack, 
                         INode_var& n2, const string& in_jack, 
                         const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param format Requested connection format
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode_var& n1,  
                         INode_var& n2,  
                         const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param format Requested connection format
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode_var& n1, const string& out_jack,
                         INode_var& n2,  
                         const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode_var& n1,
                         INode_var& n2, const string& in_jack, 
                         const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode_var& n1, const string& out_jack, 
                         INode_var& n2, const string& in_jack)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode_var& n1,
                         INode_var& n2)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode_var& n1, const string& out_jack,
                         INode_var& n2)
    throw(const BindingException&);

  /** Connect two nodes.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void connect(INode_var& n1,
                         INode_var& n2, const string& in_jack)
    throw(const BindingException&);

  // INode c_connect
  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @param connection_format (out) Returns the connection format
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode* n1, const string& out_jack,
                                       INode* n2, const string& in_jack,
                                       const Format* format, Format* connection_format)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode* n1, const string& out_jack, 
                                       INode* n2, const string& in_jack, 
                                       const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param format Requested connection format
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode* n1,  
                                       INode* n2,  
                                       const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param format Requested connection format
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode* n1, const string& out_jack,
                                       INode* n2,  
                                       const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode* n1,
                                       INode* n2, const string& in_jack, 
                                       const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode* n1, const string& out_jack,
                                       INode* n2, const string& in_jack)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode* n1,
                                       INode* n2)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode* n1, const string& out_jack,
                                       INode* n2)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode* n1,
                                       INode* n2, const string& in_jack)
    throw(const BindingException&);

  /********************** INode_var c_connect *********************/
  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @param connection_format (out) Returns the connection format
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode_var& n1, const string& out_jack,
                                       INode_var& n2, const string& in_jack,
                                       const Format* format, Format* connection_format)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode_var& n1, const string& out_jack,
                                       INode_var& n2, const string& in_jack, 
                                       const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param format Requested connection format
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode_var& n1,
                                       INode_var& n2,  
                                       const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param format Requested connection format
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode_var& n1, const string& out_jack,
                                       INode_var& n2,  
                                       const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param format Requested connection format
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode_var& n1,
                                       INode_var& n2, const string& in_jack, 
                                       const Format* format)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode_var& n1, const string& out_jack,
                                       INode_var& n2, const string& in_jack)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode_var& n1,
                                       INode_var& n2)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode_var& n1, const string& out_jack,
                                       INode_var& n2)
    throw(const BindingException&);

  /** Connect two nodes.
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* c_connect(INode_var& n1,
                                       INode_var& n2, const string& in_jack)
    throw(const BindingException&);

  // disconnect
  /** Quick disconnect of an output jack.
   *
   * @param n A node
   * @param out_jack ID of output jack to disconnect
   */
  DLLEXPORT void quick_disconnect_output(INode_var& n, const string& out_jack = "default")
    throw(const UnbindingException&);

  /** Quick disconnect of an output jack.
   *
   * @param n A node
   * @param out_jack ID of output jack to disconnect
   */
  DLLEXPORT void quick_disconnect_output(INode* n, const string& out_jack = "default" )
    throw(const UnbindingException&);

  /** Disconnect an output jack.
   *
   * @param n A node
   * @param out_jack ID of output jack to disconnect
   */
  DLLEXPORT void disconnect_output(INode_var& n, const string& out_jack = "default")
    throw(const UnbindingException&);

  /** Disconnect an output jack.
   *
   * @param n A node
   * @param out_jack ID of output jack to disconnect
   */
  DLLEXPORT void disconnect_output(INode* n, const string& out_jack = "default" )
    throw(const UnbindingException&);

  /** Disconnect an input jack.
   *
   * @param n A node
   * @param in_jack ID of input jack to disconnect
   */
  DLLEXPORT void disconnect_input(INode_var& n, const string& in_jack = "default")
    throw(const UnbindingException&);

  /** Disconnect an input jack.
   *
   * @param n A node
   * @param in_jack ID of input jack to disconnect
   */
  DLLEXPORT void disconnect_input(INode* n, const string& in_jack = "default" )
    throw(const UnbindingException&);

  // s_connect
  DLLEXPORT void s_connect(INode* n1, const string& out_jack, 
                           INode* n2, const string& in_jack, Format* conection_format = 0)
    throw(const BindingException&);

  DLLEXPORT InstreamChannel* c_s_connect(INode* n1, const string& out_jack,
                                         INode* n2, const string& in_jack, Format* conection_format = 0)
    throw(const BindingException&);

  // unchecked_connect
  /** Connect two nodes without type checking.
   * This connection method bypasses format negotiation
   * It should only be used for debugging.
   * A format must always be specified explicitly.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param given_format Forced connection format
   * @exception BindingException if the connection failed
   */
  DLLEXPORT void unchecked_connect(INode* n1, const string& out_jack, 
                                   INode* n2, const string& in_jack, 
                                   const Format* given_format)
    throw(const BindingException&);

  /** Connect two nodes without type checking.
   * This connection method bypasses format negotiation
   * It should only be used for debugging.
   * A format must always be specified explicitly.
   *
   * This connection method returns a pointer to a new communication channel.
   * The caller is responsible for deleting the communication channel object.
   *
   * @param n1 Upstream node
   * @param out_jack ID of output jack of @c n1 to connect
   * @param n2 Downstream node
   * @param in_jack ID of input jack of @c n2 to connect
   * @param given_format Forced connection format
   * @return The communication channel created by this connection
   * @exception BindingException if the connection failed
   */
  DLLEXPORT InstreamChannel* unchecked_c_connect(INode* n1, const string& out_jack, 
                                                 INode* n2, const string& in_jack, 
                                                 const Format* given_format)
    throw(const BindingException&);
}

#include "nmm/nmm_suffix.hpp"

#endif
