#include <stdio.h>
#include "util.h"
#include "strings.h"
#include "gmap.h"
#include "tree.h"
#include "bv.h"
#include "maps.h"
#include "table.h"

#include "tpmg.h"

VOID print_tree(fd,t)
    FILE * fd;
    TREE t;
    {
    LABEL l = t -> label;
    ARITY n = label_arities[l];
    ARITY i;
    if (n == 0) {
       fprintf(fd,"%s", (char *) g_unmap(string_map,l));
       return;
       }
    fprintf(fd,"(%s ", (char *) g_unmap(string_map,l));
    for (i = 0; i < n-1; i++) {
       print_tree(fd,KID(t,i));
       fprintf(fd," ");
       }
    print_tree(fd,KID(t,n-1));
    fprintf(fd,")");
    return;
    }

VOID print_1dtable(fd,a,vi) FILE * fd; LABEL a; UINT * vi;
   {
   REGISTER int i;
   REGISTER int size = (int) v_map_size(ai_info[a][0]->sai);
   int start,stop;

   fprintf(fd,"%8s ","Indexset");
   for (i = 0; i < option_columns; i++) {
       fprintf(fd,"%6d", i);
       }

   fprintf(fd, "\n");
   start = 0;
   stop = notMSmin(size,start + option_columns - 1);

   while (start <= size) {
       fprintf(fd,"%7d  ",start);
       for (i = start; i <= stop; i++) {
          if (i > 0) {
	       vi[0] = i;
               fprintf(fd, "%6d", tab_get(theta_a[a],vi));
	       }
	  else {
	       fprintf(fd, "%6s", "      ");
	       }
          }
       fprintf(fd,"\n");
       start = stop + 1;
       stop = notMSmin(size,start + option_columns - 1);
       }
   }

VOID print_2dtable(fd,a,vi) FILE * fd; LABEL a; UINT * vi;
   {
   int i,j;
   int nrows = v_map_size(ai_info[a][0]->sai);
   int ncols = v_map_size(ai_info[a][1]->sai);
   int row_start, row_stop, col_start, col_stop;
   
   col_start = 1;

   col_stop = notMSmin(col_start + option_columns - 1, ncols);
   while (col_start <= ncols) {
      /* Begin printing a series of pages for these columns */
      row_start = 1;
      row_stop = notMSmin(row_start + option_rows - 1, nrows);
      while (row_start <= nrows) {
         /* Print rows start-stop, cols start-stop on a page */
	 /* print first line */
	 fprintf(fd, "\n         ");
	 for (i = col_start; i <= col_stop; i++) {
	    fprintf(fd, "%6d",i);
	    }
	 fprintf(fd, "\n\n");
	 /* Print by rows */
	 for (i = row_start; i <= row_stop; i++) {
	    fprintf(fd, "%7d  ", i);
	    vi[0] = i;
	    for (j = col_start; j <= col_stop; j++) {
	       vi[1] = j;
               fprintf(fd, "%6d", tab_get(theta_a[a],vi));
	       }
	    fprintf(fd, "\n");
	    }
         row_start = row_stop + 1;
	 row_stop = notMSmin(row_start + option_rows - 1, nrows);
         }
      col_start = col_stop + 1;
      col_stop = notMSmin(col_start + option_columns - 1, ncols);
      }
   }

VOID print_table_internal(fd,a,vi,i,n) FILE * fd; LABEL a; UINT * vi; int i,n; {
    if (i == n) {
         print_coord(fd,0,n-1,vi); fprintf(fd," = %d\n",
					tab_get(theta_a[a],vi));
         }
    else {
         UINT j;
         for (j = 1; j <= v_map_size(ai_info[a][i]->sai); j++) {
	     vi[i] = j;
	     print_table_internal(fd,a,vi,i+1,n);
	     }
         }
    }

VOID print_table(fd,a) FILE * fd; LABEL a; {
    int n = (int) label_arities[a];
    COORD vi = tab_vect(tree_MAXARITY);
    if (n == 1) {
       print_1dtable(fd,a,vi);
       }
    else if (n == 2) {
       print_2dtable(fd,a,vi);
       }
    else print_table_internal(fd,a,vi,0,n);
    }

VOID print_coord(fd,i,n,v) FILE * fd; int i,n; UINT *v; {
    int j;
    fprintf(fd, "[");
    for (j = i; j < n; j++) fprintf(fd,"%d, ", v[j]);
    if (i<=n)  fprintf(fd, "%d", v[n]);
    fprintf(fd, "]");
    }

VOID print_t_map(fd,map) FILE * fd; GMAP map; {
   UINT i; 
   UINT n = g_map_size(map);
   fprintf(fd, "Tree map size is %d\n", n);
   for (i = 1; i <= n; i++) {
       fprintf(fd, "[%d]%d ", i, heights[i]);
       print_tree(fd, (TREE) g_unmap(map, i));
       fprintf(fd, "\n");
       if (i <= max_wildcard_index) {
          print_tree_set(fd, wc_subsumers[i]);
          }
       }
   }

VOID print_v_map(fd,map) FILE * fd; VMAP map; {
   UINT i; 
   UINT n = v_map_size(map);
   fprintf(fd, "Vector map size is %d\n", n);
   for (i = 1; i <= n; i++) {
       BV temp = v_unmap(map,i);
       fprintf(fd, "[%d]", i);
       print_tree_set(fd, temp);
       fprintf(fd, "\n");
       }
   }

VOID print_tree_set(fd, temp) FILE * fd; BV temp; {
       UINT j;
       for (j = 1; j <= pf_size; j++) {
           if (bv_in(temp,j)) {
	      fprintf(fd, "\t");
	      print_tree(fd,g_unmap(pf_map,j));
	      fprintf(fd, "\n");
	      }
           }
       }

VOID print_vo_map(fd,map) FILE * fd; VMAP map; {
   UINT i; 
   UINT n = v_map_size(map);
   fprintf(fd, "Vector map size is %d\n", n);
   for (i = 1; i <= n; i++) {
       BV temp = v_other(map,i).bv;
       UINT j;
       fprintf(fd, "[%d]\t", i);
       for (j = 1; j <= pf_size; j++) {
           if (bv_in(temp,j)) {
	      print_tree(fd,g_unmap(pf_map,j));
	      fprintf(fd, "\n\t");
	      }
           }
       fprintf(fd, "\n");
       }
   }

int notMSmin(int a, int b) {return (a > b) ? b : a ; }

VOID print_r_map(fd, ai) FILE * fd; LS ai; {
   REGISTER int i;
   REGISTER int ms_size = (int) v_map_size(matching_sets);
   REGISTER BV temp = bv_new();
   
   int start,stop;

   fprintf(fd,"%8s ","Matchset");
   for (i = 0; i < option_columns; i++) {
       fprintf(fd,"%6d", i);
       }

   fprintf(fd, "\n");
   start = 0;
   stop = notMSmin(ms_size,start + option_columns - 1);

   while (start <= ms_size) {
       fprintf(fd,"%7d  ",start);
       for (i = start; i <= stop; i++) {
          if (i > 0) {
               bv_andto(ai -> pair, v_other(matching_sets,i).bv, temp);
               fprintf(fd, "%6d", v_inmap(ai->sai,temp));
	       }
	  else {
	       fprintf(fd, "%6s", "      ");
	       }
          }
       fprintf(fd,"\n");
       start = stop + 1;
       stop = notMSmin(ms_size,start + option_columns - 1);
       }
   }

