//---------------------------------------------------------------------------

#ifndef networkH
#define networkH
   
struct NameStruct {
	string name;
	list<Node>::iterator ndi;		// not defined if it is PI.
	bool PI;					// is it a PI?
	unsigned int pos;
};

class Network {
  private:
	string model;			// name of the model
	list<Node> nodes;		// here are the PLAs
	vector<string> inames;			// names of input ports
	vector<string> onames;			// names of output ports

	list<NameStruct> names;		// list of names with iterators to their source nodes and output numbers

	bool connected;				// is the network connected?

	vector<list<Node>::iterator> indexnodes;	// vector of nodes, if Network is indexed
	
	void Connect(void);		// Constructs the connections by processing BLIF names
	void Disconnect(void);	// Deletes the connections
	void GenerateNames(void);	// Generates the "names" structure


  public:
	Network();
	Network( Blif &src );
	~Network();

	int tmp;			// for different purposes. Must not be modified by the kernel

	// setters & getters
	list<Node> *GetData(void) { return &nodes; };
	unsigned int GetNodes(void) const { return nodes.size(); };		// returns number of nodes
	unsigned int GetInputs(void) const { return inames.size(); };
	unsigned int GetOutputs(void) const { return onames.size(); };
	unsigned int GetLiterals(void);
	list<NameStruct> *GetNameStruct(void);
	void SetModel( const string _model ) { model = _model; };

	// info
	bool isPI( const string name ) const;		// is the signal a PI?
	bool isPO( const string name ) const;		// is the signal a PO?
	bool empty(void) const { return nodes.empty(); };
	NameStruct *FindName( const string name );		// Finds a node with an outout of a given name or NULL if not found

	// I/O
	void SaveMBlif( const char *fn );	// Saves the network to a MBLIF file

	// data manipulation
	void AddNode( const Node &_node );
	void SpliceNetworks( Network &net );			// splices two networks. Data from net is deleted
	list<Node>::iterator DeleteNode( const list<Node>::iterator ni );
	void ToSingleOutput(void);			// Converts the network into a network of single-output nodes, like Blif
	list<Node>::iterator MergeNodes( list<Node>::iterator node1, list<Node>::iterator node2 );  // merges two nodes into one
	void Rename( const string oldname, const string newname );	// Changes the given net name, in the whole network
	void AddInput( const string name );		// Adds an input, if not present
	void AddOutput( const string name );		// Adds an output, if not present

	// conversion routines
	Blif *ToBlif(void) const;		// Converts the network to Blif
	Blif *ToBlif( const bool type ) const;		// Converts the network to Blif. type specifies the Blif type (false = r, true = f)

	// indexing
	void Reindex(void);				// creates the vector of nodes, for random access to nodes
	unsigned int GetIndex(const list<Node>::iterator ndi);	// returns index of a given node. If not indexed, performs reindexation
	list<Node>::iterator GetNodeByIndex( const unsigned int i );		// returns an iterator to a node with a given index

	// other
	void DerivePorts(void);				// Generates PIs and POs by analyzing the network
	list<string> FindVoidSignals(void);		// Returns a list of void (unfed) signals

};






//---------------------------------------------------------------------------
#endif
