#include <stdio.h>
#include "util.h"
#include "table.h"

skip_to_eol(fd) FILE * fd;
{
  while(fgetc(fd) != '\n') ;
}

skip_prologue(fd) FILE * fd;
{
  while(fgetc(fd) != ' ') skip_to_eol(fd);
}

readn(fd) FILE * fd;
{
  int i,x;
  x = fscanf(fd,"%d",&i);
  if (x != 1) {
    fprintf(stderr,"READN failed to read an integer\n"); abort(1);
  }
  return i;
}

read_c_tables(fd) FILE * fd;
{
  int table_count;
  int dimension;
  int a_bounds[20];
  int * bounds = a_bounds;
  int i,j,k,l,m,n;
  int count;
  int totsize = 0;
  int avoided = 0;

  skip_prologue(fd);

  table_count = readn(fd);

  for (n = 0; n < table_count; n++)
    {
      /* Get past the node label */
      skip_to_eol(fd); skip_to_eol(fd);

      dimension = readn(fd);

      /* Skip the internal indices for the index map. */
      for (k = 0; k < dimension; k++)
	readn(fd);

      count = 1;
      for (k = 0; k < dimension; k++)
	{
	  bounds[k] = readn(fd);
	  count = count * bounds[k];
	}

      totsize += count;

      if (dimension != 2)
	{
	  for (k = 0; k < count; k++)
	    readn(fd);
	}
      else
	{
	  int * matrix = malloc (count * sizeof(int));
	  int nr = bounds[0];
	  int nc = bounds[1];
	  int constrows = 0;
	  int constcols = 0;
	  int fail;

	  /* read matrix */
	  for (i = 0; i < nr; i++)
	    for (j = 0; j < nc; j++)
	      {
		int elt = readn(fd);
		matrix[i * nc + j] = elt;
	      }

	  /* look for constant rows */
	  for (i = 0; i < nr; i++)
	    {
	      int trial = matrix[i * nc];
	      fail = 0;

	      for (j = 1; j < nc; j++)
		{
		  if (matrix[i * nc + j] != trial)
		    {
		      fail = 1;
		      break;
		    }
		}
	      if (!fail) constrows++;
	    }

	  /* look for constant columns */
	  for (j = 0; j < nc; j++)
	    {
	      int trial = matrix[j];
	      fail = 0;

	      for (i = 1; i < nc; i++)
		{
		  if (matrix[i * nc + j] != trial)
		    {
		      fail = 1;
		      break;
		    }
		}
	      if (!fail) constcols++;
	    }
	  printf("Found %d rows with length %d of constant values\n",
		 constrows, nc);

	  printf("Found %d cols with length %d of constant values\n",
		 constcols, nr);

	  {
	    int savings = nr * nc - (nr - constrows) * (nc - constcols);
	    printf("Matrix is %d smaller\n", savings);
	    avoided += savings;
	  }

	  /* look for constant columns */
	  
	  free (matrix);
	}
    }
  printf("Uncompressed size is %d, compressed size is %d\n",
	 totsize,
	 totsize - avoided);
}

stream(in,out) FILE * in, *out;
{
  int c = fgetc(in);
  while (c != EOF)
    {
      fputc(c,out);
      c = fgetc(in);
    }
}

#define CHECK_INPUT
main()
{
  read_c_tables(stdin);
#ifdef CHECK_INPUT
  printf("Remainder of input is:\n----\n");
  stream(stdin,stdout);
  printf("----\n");
#endif
}
