/*************************************************************** 
	The GPDD Sensitivity Project (GPDD_Sens) 
 
	GPDD stands for "Graph-Pair Decision Diagram" 
 
Contributors: 
 
   CHEN, Weiwei			(MS 2007 graduate) 
   MENG, Xiaoxuan		(MS 2009 graduate) 
   ZENG, Mei			(MS 2010 graduate) 
   LI, Ji				(MS 2010 graduate) 
   MA, Diming			(MS 2011 graduate) 
 
   SHI, Guoyong 		(Prof)  shiguoyong@ic.sjtu.edu.cn 
 
   School of Microelectronics 
   Shanghai Jiao Tong University 
   (c) 2005 - 2010 
******************************************************************/ 

/* 
	ToGraph.h
	
 * The ToGraph class reads the input netlist and create an internal edge list.
 * After parsing, it writes the edge list to a graph file.
 *
 * 03-25-03, G.Shi
 */

#ifndef	TOGRAPH_H
#define	TOGRAPH_H

#include  <fstream>
#include  <vector>

#include	"utility.h"
#include	"gpdd_struct.h"
#include	"Analysis_AC.h"

//#include	"MOS.h"

/*// For storing a node.
struct Node_g
{
	int	 	num;		// Node_g number
	Node_g	*next;		// To form a linked list.
};
// At the moment I only use this Node_g List to sort the node numbers,
// and if necessary to renumber the nodes from 0 consecutively.

// For storing an edge.
struct Edge_g
{
	char	*name;		// Name of the edge
	Node_g	*node1;
	Node_g	*node2;		// Node number is stored in the node list
	int		type;
	char	*pname;		// Name of the pairing edge
	double	value;		// Value of the element
	char	*var_name;	// Variable name for the value (not used now)
	Edge_g	*next;		// Make a linked list
};*/

		
class ToGraph 
{

private:
	int		NumEdges;		// Num of edges in the graph.
	int		NumNodes;		// Num of nodes in the graph.
	int		NumMOSDevics;
	
	int		Nsrc;	// Num of indep srcs (only one allowed now)
	int		Nout;	// Num of outputs (only one allowed now)
	int		extra_nn;	// extra node number (-1, -2, ...)
	char		*title;	// netlist title
	
	Edge_g	*edge_list;		// Head of the edge list
	Edge_g	*cur_edge;		// Points to the current edge
	Edge_g	*src_edge;		// Points to the source edge
	Edge_g	*out_edge;		// Points to the output edge
	Node_g	*node_list;		// Head of the node list
	Node_g	*node_tail;		// Tail of the node list

	std::vector <Analysis_AC *>	AnalysisList;
	
//	MOS  *MOS_List;
//	MOS  *curr_MOS;
	
	std::ofstream	outFile;	// For output to a graph file.

public:
	ToGraph();
	~ToGraph();

	/* Methods for parsing the netlist. */
	void readNetlist(const char *filename);
	void writeGraph(const char *filename);  // Create a graph file.
	void getTitle(char *title) {this->title = CopyStr(title);}
	
	inline int		getNumEdges()  		{return NumEdges;}
	inline int		getNumNodes()  		{return NumNodes;}
	inline int		getNumMOSDevices()  {return NumMOSDevics;}
	
	inline Edge_g 	*getEdgeList()	{ return edge_list; }

	inline std::vector<Analysis_AC*> & GetAnalysisList() {return AnalysisList;};
	
//	inline MOS	*getMOSList() 	{ return MOS_List;}
//	void calMOSParameters();
	
	void parseRLC(char *name, char *n1, char *n2, 
					char *value, char *var_name);
	// Parse an independent source.
	void parseSRC(char *name, char *n1, char *n2, 
					char *dc_val, char *ac_val);
	// Parse an output control. br_name is the branch from which
	// the output current is measured.
	void parseOUT(char *name, char *n1, char *n2, char *br_name);
	// Parse a VCCS/VCVS branch.
	void parseVCXS(char *name, char *n1, char *n2, char *nc1, char *nc2,
					char *value, char *var_name);
	// Parse a CCCS/CCVS branch.
	void parseCCXS(char *name, char *n1, char *n2, char *Vname,
					char *value, char *var_name);

	void ParseDotAC( char *STEPTYPE, char *NP,  char *FSTART, char *FSTOP);


	void parseMOSFET(char *name, char *nd, char *ng, char *ns, char *nb,
					char *model, char *w, char *l);
private:
	/* Methods for accessing the Node_g List */
	Node_g *query_node(int node_num);
	void add_node(Node_g *node);
	// Renumber and count the nodes in the node_list.
	void renumber_nodes();

	/* Methods for accessing the Edge_g List */
	Edge_g *query_edge(char *edge_name);
	Edge_g *query_pair(char *pair_name); // query an edge with the pair_name
	void 	add_edge(Edge_g *edge);
	void 	add_edge_at_head(Edge_g *edge);
	
//	void add_mosfet(MOS* mosfet);
//	MOS *query_mosfet(char* name);
};

#endif

