#ifndef READDATFILE_H
#define READDATFILE_H
#include <iostream>
#include <fstream>
#include <string>
#include <locale>
#include <malloc.h>
#include <assert.h>

typedef struct Graph{
	unsigned nnodes, nedges;
	unsigned *noutgoing, *nincoming, *srcsrc, *psrc, *edgessrcdst,*edgessrcwt;	
	unsigned *maxInDegree,*maxOutDegree;
	unsigned allocOnHost();
	unsigned deallocOnHost();
	void readGraph(char *fileName);
	void readFromDat(char *fileName);
	void progressPrint(unsigned,unsigned);
	// unsigned alloOnHost();
	// unsigned deallocOnHost();
}Graph;

unsigned Graph::allocOnHost() {
	edgessrcdst = (unsigned int *)malloc((nedges+1) * sizeof(unsigned int));	
	edgessrcwt = (unsigned *)malloc((nedges+1) * sizeof(unsigned));	
	psrc = (unsigned int *)calloc(nnodes+1, sizeof(unsigned int));	
	psrc[nnodes] = nedges;	
	noutgoing = (unsigned int *)calloc(nnodes, sizeof(unsigned int));	
	nincoming = (unsigned int *)calloc(nnodes, sizeof(unsigned int));
	srcsrc = (unsigned int *)malloc(nnodes * sizeof(unsigned int));

	maxOutDegree = (unsigned *)malloc(sizeof(unsigned));
	maxInDegree = (unsigned *)malloc(sizeof(unsigned));
	*maxOutDegree = 0;
	*maxInDegree = 0;

	//	memory = AllocatedOnHost;
	return 0;
}

//deallocate memory for graphs
unsigned Graph::deallocOnHost() {
	free(noutgoing);
	free(nincoming);
	free(srcsrc);
	free(psrc);
	free(edgessrcdst);
	free(edgessrcwt);

	free(maxOutDegree);
	free(maxInDegree);
	return 0;
}

void Graph::readFromDat(char *fileName){
	std::ifstream file ( fileName);
	if (file) {
		// get length of file:
		file.seekg (0, file.end);
		int length = file.tellg();
		file.seekg (0, file.beg);

		char * buffer = new char [length];

		// read data as a block:
		file.read (buffer,length);

		//close the file
		file.close();

		std::locale loc;
		int num = 0;
		long i= 0;
		for( ; i<220; ){
			nnodes = num;
			num = 0;
			// read number of edges and vertices
			while( isdigit(buffer[i],loc)){
				num = num * 10 + (buffer[i] - 48);
				i++;
			}
			i++;
			nedges = num;
		}
		// check format of the file
		assert( buffer[i] == 'a');
//		printf("nnodes=%d, nedges=%d.\n", nnodes, nedges);
                //memory allocation for arrays
		allocOnHost();
		int ii = 0, jj = 1, outgoing = 0;
		for( ;i<length; ){
			i = i + 2;
			num = 0;
			while( isdigit(buffer[i],loc)){
				num = num * 10 + (buffer[i] - 48);
				i++;
			}
			if( ii == 0 ){
                                ii = num;
				srcsrc[ ii] = num;
				psrc[ ii] = 1;
				//ii++;           
			}
			else if( srcsrc[ ii] != num ){
				noutgoing[ ii] = outgoing;
				outgoing = 0;
                                ii = num;
				srcsrc[ ii] = num;
				psrc[ ii] = jj;
				//ii++;
			}
			outgoing++;
			i++;
			num = 0;
			while( isdigit(buffer[i],loc)){
				num = num * 10 + (buffer[i] - 48);
				i++;
			}
			edgessrcdst[ jj] = num;
			i++;
			num = 0;
			while( isdigit(buffer[i],loc)){
				num = num * 10 + (buffer[i] - 48);
				i++;
			}
			edgessrcwt[ jj] = num;
			jj++;
			i++;
		}
		noutgoing[ii] = outgoing;
                for( ii=0; ii <nnodes; ii++){
                    if(srcsrc[ii] ==0){
                      srcsrc[ii] = ii;
                      psrc[ii] = psrc[ii+1];
                      noutgoing[ii] = 0;
                    }
                }

		delete[] buffer;
	}

}

void Graph::readGraph(char *fileName){
	readFromDat( fileName);

}

#endif
