#include <stdio.h>
#include <sys/types.h>
#include <sys/times.h>

#define WRITECOLORS
#define STIB
#define NMAX 8400 			/* maximum number of vertices      */
#define INT 32                          /* length of computer word         */
#define edge(x,y) (graph[(x)][((y)-1)/INT + 1] & mask[(y)%INT])
#define MAX_NR_VERTICES		8400
#define MAX_NR_VERTICESdiv8	1050
#define BOOL	char

BOOL Bitmap[MAX_NR_VERTICES][MAX_NR_VERTICESdiv8];
char masks[ 8 ] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };

     /* variables for reading graphs  */ 
static unsigned
        graph[NMAX+1][(NMAX+1)/INT+1];  /* adj matrix bitmap of graph       */
static int mattype;                     /* type of graph                    */
static int N; 				/* number of vertices in graph      */
static int numcols; 			/* num of cols used for matrix gr   */
static double dens, maxdist, dens1, dens2,ExDens;
static double x_coord[NMAX+1],
              y_coord[NMAX+1];		/* arrays for x & y coords of geom  */



static unsigned mask[INT] =
   {1, 1<<31,1<<30,1<<29,1<<28,1<<27,1<<26,1<<25,
    1<<24,1<<23,1<<22,1<<21,1<<20,1<<19,1<<18,1<<17,
    1<<16,1<<15,1<<14,1<<13,1<<12,1<<11,1<<10,1<<9,
    1<<8,1<<7,1<<6,1<<5,1<<4,1<<3,1<<2,1<<1
   } ;

void read_instance();
FILE *inputfile, *outputfile, *fp, *fopen();

struct tms buffer; 			/* structure for timing              */
int utimer;
double utime;

main(argc,argv)
  int argc; 
  char *argv[]; {

  char outname[1000];

  setbuf(stdout, NULL);
  if (argc <  2) {
     printf("Usage: g2bin <graphfile>\n"); 
     exit(0); 
  }

  if ((inputfile = fopen(argv[1], "r")) == NULL) {
     printf("Input graph does not exist");
     exit(1);
  }

  read_instance(inputfile);

  if (argc == 2)
	sprintf(outname,"%s.b",argv[1]);
  else  sprintf(outname,"%s",argv[2]);

  printf("Putputfile = %s\n",outname);

  if ((outputfile = fopen(outname, "w")) == NULL) {
     printf("Cannot open output file %s",outname);
     exit(1);
  }

  write_graph(outputfile);
}

void read_instance(filename)
FILE *filename;
{
   int i,j;
   int width;
   double tempcost;

   fscanf(filename, "%d\n", &mattype);	/* read matrix type                 */
   fscanf(filename, "%d\n", &N);        /* read size of matrix              */

   if (mattype == 0 ){ 	                /* read density of graph            */
      fscanf(filename, "%lf\n", &dens);
   } 
   
   else if (mattype == 1){		/* read max dist. of geometric     */
      fscanf(filename, "%lf\n", &maxdist);
   }
   else if (mattype == 2) {		/* read main & sub densities       */
      fscanf(filename, "%lf\n", &dens1);
      fscanf(filename, "%lf\n", &dens2);
   }
   else if (mattype == 3) {             /* read num cols                    */
      fscanf(filename, "%d\n", &numcols);
      fscanf(filename, "%lf\n", &ExDens);
      fscanf(filename, "%lf\n", &dens);
   }

   width = N/INT + ((N%INT) != 0);      /* compute width                    */
   for (i = 1; i <= N; i++)		/* read adjacency matrix	   */
       for (j = 1; j <= width; j++) 
           fscanf(filename, "%u", &graph[i][j]);

   if (mattype == 1)                     /* read x-coord y-coord set        */
      for (i = 1; i <= N; ++i) {
          fscanf(filename, "%lf", &x_coord[i]);
          fscanf(filename, "%lf", &y_coord[i]);
      }

}

write_graph(fp)
FILE *fp;
{
	char Preamble[10000];
	int i,j;
	int edgecount = 0;


	for (i=1;i<=N;i++)
		for (j=1;j<i;j++)
			if (edge(i,j)) {
				edgecount++;
				set_edge(i-1,j-1,1);
			}

	sprintf(Preamble,"p edge %d %d\n",N,2*edgecount);
	
	fprintf(fp, "%d\n", strlen(Preamble));
	fprintf(fp, Preamble);
	
	for ( i = 0
		 ; i < N && fwrite(Bitmap[i], 1, (int)((i + 8)/8), fp)
		 ; i++ );
	
	fclose(fp);
}

set_edge(i,j,x )
register int i,j;
BOOL x;
{
	register int byte, bit, mask;
	
	bit  = 7 - (j & 0x00000007);
	byte = j >> 3;
	
	mask = masks[bit];
	if ( x == 1 ) Bitmap[i][byte] |= mask;
	else  Bitmap[i][byte] &= ~mask;
}
