
#ifndef GRAPH_H
#define GRAPH_H

#define MAX_N_NODES 512
#define MAX_N_PATHS 40000
#define MAX_N_LINKS 512
#define MAX_N_NODES_IN_GRAPH 65536
#define N_SHADOW 10


#define UNIVSTARTYEAR 1998


class Path {
public:
	int length;
	int addlater;
	int nodeArray[MAX_N_NODES];
	int timestamp;
	int year, month, day, hour, min;
	char attributes[5][64];
	unsigned int univtime;
	int dpid; // which distinct path is this?
	Path() { 
		int i;
		length = 0; addlater = 0; 
		for (i=0;i<5;i++) attributes[i][0] = '\0';
	};
	int FindNode(int n);
	int FindLink(int a, int b);
	void Print();

};

int nodesSame(Path *p1, Path *p2);

class Node {

public:
	int AS;
	int level;
	int maxlevel;
	float xcoord;
	int nlinks;
	int dfsflag;

	int linearX;
	int countedlevel;

	Node *templink;
	Node *links[MAX_N_LINKS];
	Node(int id) : linearX(-1) , countedlevel(0) { dfsflag = 0; xcoord = -1; level = -1; nlinks = 0; AS = id; templink = NULL; };
	void AddLink(Node *n);
	void Print();
	int SetLevel(int n);
	void Draw();
	void DrawYourself(int n);
	void RemoveTempLink();
	void PermanizeLink();
	void AddTempLink(Node *n);
	int DetectCycle();
	void InitDFS();

	int NumInLevel(int n);
	void SetLinearX(int *next);

};

class Graph {
public:
	int selectedPoint;
	int x,y;
	int root;
	int npaths;
	int peer1, peer2, peer3; // peers to watch
	char ipadd[32];
	Path *paths[MAX_N_PATHS];
	Node *nodes[MAX_N_NODES_IN_GRAPH];
	static int show_attrs;
	static float sep_fac; // separation factor in 3D text display
	static int sep_thres; // separation threshold in 3D text display

	int numanns[512];
	int pindices[512]; // for each time period, index back to first included path
	int maxnumanns;
	int allpaths[512]; // bit b of index i is set if in the ith time period, bth unique path is used
	int allpaths2[512]; // for unique paths 32 through 63
	int ndistinctpaths;
	Path distinctpaths[512];
	int tinter;
	int firstwritepath; // for highlight when user clicks on path text
	int highlightedpath; // for highlight when user clicks on path text
	int shadowpath; // for highlight when user clicks on path text
	int shadowpaths[N_SHADOW]; // for highlight when user clicks on path text

	float linearNodeColors[7][3];
	int maxlinearx;

	char *orthogonal_grid; // 1 if there is a node at this coordinate, 0 otherwise
	int *orthogonal_grid_AS;
	int orthox, orthoy;
	Graph *orthograph;

	Graph();
	void readMRT(char *fname);
	void MakeGraph(char *fname);
	void AddGraph(Graph *gptr);
	void ConstructGraph();
	void MakeCleanGraph(char *fname);
	void PrintPaths();
	void PrintGraph();
	void Draw();
	void DrawBackground(float st, float ft);
	void DrawTimeLine(int t);
	void DrawTimeDistinctPaths(int t);
	void DrawWindowDistinctPaths(int w, int p, int t);
	void DrawNewWinDistinctPaths(int s, int e);
	void DrawPathLengths(int s, int e);
	void DrawAnnPaths(int s, int e);
	void DrawOrthogonal(int p, int n);
	void DrawDiagonal(int p, int n);
	void DrawNodes(int n);
	void DrawCustomHighlightTopology();
	void DrawPathsInSlots(int s, int e);
	void DrawCrescent(float x1, float x2, float y, float h1, float h2);
	void DrawCircleSegment(float x1, float x2, float y, int cind1, int cind2);
	void DrawCylinder(float x1, float x2, float y);
	void DrawLinear();
	void DrawOtherPathsInSlots(int s, int e, Graph *gptr, int id);
	void DrawPath(int p);
	void DrawPrevPath(int p, float m);
	void DrawPathPtr(Path *pptr);
	void DrawBoxPath(int i, int n, float st, float frac, int vert);
	void WritePath(int i, int n, float st, float frac, int vert);
	void WritePaths(int slot, int t);
	void WriteDetailPaths(int tstart, int twin);
	int DetectCycle();
	void Init();
	void SelectPoint(int i, int j);
	void MovePoint(int i, int j);
	void AdvanceTime(int &t);

};

#endif

