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

#ifndef networkH
#define networkH
   
class Blif;

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<Signal> signals;		// list of signals
	hashtable<list<Signal>::iterator> signalnames;	// hashtable of signal names. Must be kept compatible with "signals"!

	vector<list<Node>::iterator> indexnodes;	// vector of nodes, if Network is indexed
	
	list<Signal>::iterator FindOrCreateSignal( const string &name );
	void AddNodeSignals( list<Node>::iterator ndi );	// creates signal entries for a new node
	bool DeleteSignal( const string &n );
	void Disconnect(void);	// Deletes the connections

	float GetNodeDelay( unsigned int fanin, unsigned int fanout );

  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);
	void SetModel( const string _model ) { model = _model; };
	list<Signal> *GetSignals(void);

	// info
	bool isPI( const string &name );		// is the signal a PI?
	bool isPO( const string &name );		// is the signal a PO?
	bool isConstant( const string &name );	// is the signal fed by a constant node?
	bool empty(void) const { return nodes.empty(); };
	pair<bool, list<Signal>::iterator> FindSignal( const string &n );
	bool IsSignalThere( const string &n );	// Does the signal with a given name exist in the network?

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

	// data manipulation
	list<Node>::iterator 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 signal 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
	float GetDelay(void);		// calculates the circuit delay
	float GetMinDelay(void);
	float GetAvgDelay(void);

	void GenerateSignals(void);		// Generates the signals structure

};






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