// Connection.h (Cortex)
// * PURPOSE
//   Represents a general connection between two media nodes.
//
// * NOTES 13aug99
//   Connection is undergoing massive resimplification(TM).
//   1) It's now intended to be stored and passed by value; synchronization
//      and reference issues are no more.
//   2) It now refers to the participatory nodes by ID, not pointer.  This
//      makes the nodes slightly more cumbersome to look up, but makes
//      Connection completely 'safe': an outdated instance doesn't contain
//      any dangerous information.
//
// * NOTES 29jul99
//   1) For completeness, a release() or disconnect() method would be nice.  Problems?
//   2) How will connections between 'external' nodes be denoted?  For example,
//      the audioMixer->audioOutput connection must not be broken EVER.  Other external
//      connections might be manually broken, but should be left alone when the
//      NodeManager quits (whereas all internal connections need to be removed by
//      the dtor.)  This implies two flags: 'internal' and 'locked'...
//
// * HISTORY
//   e.moon		25jun99		Begun

#ifndef __Connection_H__
#define __Connection_H__

#include <Debug.h>
#include <MediaNode.h>
#include <String.h>

#include "cortex_defs.h"

__BEGIN_CORTEX_NAMESPACE

class NodeManager;
class NodeGroup;
class NodeRef;

class Connection {

	// rather incestuous set of classes we've got here...
	friend NodeRef;
	friend NodeManager;

public:					// *** types & constants
	enum flag_t {
		// connection should be removed automatically when the NodeManager
		//   is destroyed
		INTERNAL					= 1<<1,
		// connection must never be removed
		LOCKED						= 1<<2
	};

public:					// *** dtor/user-level ctors
	virtual ~Connection();
	
	Connection();
	Connection(
		const Connection&					clone); //nyi
	Connection& operator=(
		const Connection&					clone); //nyi

public:					// *** accessors

	uint32 id() const																{ return m_id; }

	bool isValid() const														{ return
																										m_sourceNode != media_node::null &&
																										m_destinationNode != media_node::null &&
																										!m_disconnected; }

	// changed 13aug99
	media_node_id sourceNode() const 								{ return m_sourceNode.node; }
	const media_source& source() const 							{ return m_source; }
	const char* outputName() const 									{ return m_outputName.String(); }
	
	// changed 13aug99
	media_node_id destinationNode() const 					{ return m_destinationNode.node; }
	const media_destination& destination() const 		{ return m_destination; }
	const char* inputName() const 									{ return m_inputName.String(); }
	
	const media_format& format() const 							{ return m_format; }
	
	uint32 flags() const														{ return m_flags; }

	// input/output access [e.moon 14oct99]
	status_t getInput(
		media_input*							outInput);

	status_t getOutput(
		media_output*							outOutput);

protected:				// *** general ctor accessible to subclasses &
									//     cortex::NodeManager

	// id must be non-0
	Connection(
		uint32										id,
		media_node								srcNode,
		const media_source&				src,
		const char*								outputName,
		media_node								destNode,
		const media_destination&	dest,
		const char*								inputName,
		const media_format&				format,
		uint32										flags);

	// if any information about the pre-connection (free) output format
	// is known, call this method.  this info may be useful in
	// finding the output to re-establish the connection later on.
			
	void setOutputHint(
		const char*								origName,
		const media_format&				origFormat);

	// if any information about the pre-connection (free) input format
	// is known, call this method.  this info may be useful in
	// finding the output to re-establish the connection later on.
			
	void setInputHint(
		const char*								origName,
		const media_format&				origFormat);

private:					// *** members

	// info that may be useful for reconstituting a particular
	// connection later on.
	struct endpoint_hint {
		endpoint_hint(const char* _name, const media_format& _format) :
			name(_name), format(_format) {}

		BString					name;
		media_format		format;
	};

	// waiting to die?
	bool												m_disconnected;

	// unique connection ID
	uint32											m_id;

	// [e.moon 14oct99] now stores media_nodes

	// source/output info
	media_node									m_sourceNode;
	media_source								m_source;
	BString											m_outputName;

	endpoint_hint*							m_outputHint;	
	
	// dest/input info
	media_node									m_destinationNode;
	media_destination						m_destination;
	BString											m_inputName;
	
	endpoint_hint*							m_inputHint;
	
	// connection format
	media_format								m_format;

	// behaviour modification	
	uint32											m_flags;
};

__END_CORTEX_NAMESPACE

#endif /*__Connection_H__*/
