/*
 * Main program calling Shortest Path Selection Algorithm ...
 * Nov 7, 2002
 * by Turgay KORKMAZ *
 */

#include "common.h"


printTopology(t_link **G, int N)
{
    int u,v;
    
    for(u=0; u < N; u++){
	for(v=0; v < N; v++){
	    if(G[u][v].valid==1){
		printf("From node %d to node %d : \t c=%2.2f \n", u, v, G[u][v].c);
	    }
	}
    }
}



t_link **GenerateMeshTopology(int N)
{
    t_link **T;
    int i,j;
    int M;
    
    M = N*N;
    
    T =  (t_link **)create2DArray(M,M,sizeof(t_link));
    
    for(i=0; i < M; i++){
	for(j=0; j < M; j++){
	    T[i][j].valid = 0;
	}
    }
    /* Generate Mesh Topology N x N */
    for(i=0; i < M; i++){
	if(i%N!=N-1) T[i][i+1].valid=1;
	if(i%N) T[i][i-1].valid=1;
	if(i<N*(N-1)) T[i][i+N].valid=1;
	if(i>=N) T[i][i-N].valid=1;
    }
    return(T);
}


t_link **ReadSimpleTopologyFile(char *fname, int *N )
{
    FILE              *f;
    int                i,j;
    t_link           **T;
    char               cmd[256];
    int                nodeID;
    int                dest;
    double             cost1, cost2, cost3;

    if( (f=fopen(fname,"r")) == 0 ){
	fprintf(stderr,"Topology file can not be open\n");
	return(NULL);
    }
    if( fscanf(f,"Node: %ld", N) != 1){
	fprintf(stderr,"This is not a topology file\n");
	return(NULL);
    }
    
    T = (t_link **)create2DArray(*N,*N,sizeof(t_link));
    for(i=0; i < *N; i++){
	for(j=0; j < *N; j++){
	    T[i][j].valid = 0;
	}
    }
    while(!feof(f)){
	fscanf(f,"%s",cmd);
	// printf("---> %s\n",cmd);
	// Peer group Id is used for other prog but net files same, so just read it
	if(strcmp(cmd, "NodeID:")==0){
	    if( fscanf(f,"%ld", &nodeID) != 1){
		fprintf(stderr,"Error occured while reading NodeID \n");
		return(NULL);
	    }
	} else if(strcmp(cmd, "LinkTo:")==0){
	    if( fscanf(f,"%ld  %lf %lf %lf", &dest, &cost1, &cost2, &cost3 ) != 4){
		fprintf(stderr,"Error occured while reading Node %d's Links\n",nodeID);
		return(NULL);
	    }
	    T[nodeID][dest].c = cost1;
	    T[nodeID][dest].valid = 1;
	}
	strcpy(cmd,".");
    }
    fclose(f);
    return(T);
}


main (int argc, char **argv)
{
    
    char             filename[80];
    int              seed;
    
    t_link         **G;           // graph G
    int              N;           // number of Node;
    int              s, d;        // src dest
    int              i, j;

    int              *Pi;
    double           *D;
    
    G=NULL;
    
    if(argc == 1){
	N=5;
	G = GenerateMeshTopology(N);
	N = N * N;
    } else if(argc==2){
	sscanf(argv[1],"%s", filename);
	G = ReadSimpleTopologyFile(filename,  &N );
    } else {
	fprintf(stderr,"Usage: %s [filename]\n",argv[0]);
    }
    if(!G) exit(-1);

    srandom(1234);
    
    /* set the link weights/costs */
    for(i=0; i < N; i++) {
	for(j=0; j < N; j++){
	    if(G[i][j].valid == 1){
		G[i][j].c = ((double) random(0)/MAX_INT) * 50;
	    }
	}
    }
    
    
    Pi = (int *) create1DArray(N,sizeof(int));
    D  = (double *) create1DArray(N,sizeof(double));
    
    printTopology(G, N);
    
    //  MAIN LOOP START FROM HERE
    while(1){
	printf("\n\nWelcome to path computation program\n");
	printf("To exit enter -1, else enter source node s between [0 %d]= ",N-1); scanf("%d", &s);
	if((s<0)||(s>=N)) break;
	
	printf("Start computing the shortest path form s=%d to all other nodes using Dijkstra\n",s);
	dijkstra(G, N, s, D, Pi);
	printf("Shortest path computation is done at node s=%d\n\n", s);
	
	printf("\tTo print the routing table at s=%d enter -1, otherwise \n", s);
	printf("\tTo print the path from s=%d to any destination, enter destination d between [0 %d]= ",s, N-1);
	scanf("%d", &d);
	
	if ((d<0) || (d>=N)){
	    printRoutingTable(G, N, s, D, Pi);
	} else {
	    while((d>=0) && (d<N)){
		printPath(G,N,s,d,D,Pi);
		printf("\tTo print the path from s=%d to another destination, enter destination d in [0 %d]=\n",s, N-1);
		printf("\telse enter d as -1, d = ");
		scanf("%d", &d);
	    }
	}
    }
    
    free2DArray(G,N);
    free1DArray(D);
    free1DArray(Pi);
}

