 /***************************************************************************/
 /*                                                                         */
 /*      Copyright (C) 1991, 1992  Daniel Sleator and Davy Temperley        */
 /*  See file "README" for information about commercial use of this system  */
 /*                                                                         */
 /***************************************************************************/

#include "header.c"

static int center[MAX_SENTENCE];
char * chosen_words[MAX_SENTENCE];

void set_centers(int print_word_0) {
    int i, len, tot;
    tot = 0;
    if (print_word_0) i=0; else i=1;
    for (; i<N_words; i++) {
	len = strlen(chosen_words[i]);
	center[i] = tot + (len/2);
	tot += len+1;
    }
}

/* the following are all for generating postscript */
static int link_heights[MAX_LINKS];
  /* tells the height of the links above the sentence */
static int row_starts[MAX_SENTENCE];
  /* the word beginning each row of the display */
static int N_rows;
  /* the number of rows */

void print_postscript_data(int print_word_0) {
    int link, i,j;
    int d;

    if (print_word_0) d=0; else d=1;

    i = 0;
    printf("[");
    for (j=d; j<N_words; j++) {
	if ((i%7 == 0) && (i>0)) printf("\n");
	i++;
	printf("(%s)",chosen_words[j]);
    }
    printf("]");
    printf("\n");

    printf("[");
    j = 0;
    for (link=0; link<N_links; link++) {
	if (print_word_0 || (pp_link_array[link].l != 0)) {
	    if ((j%5 == 0) && (j>0)) printf("\n");
	    j++;
	    printf("[%d %d %d",
	      pp_link_array[link].l-d, pp_link_array[link].r-d, link_heights[link]);
	    if (pp_link_array[link].lc->label < 0) {
		printf(" (%s)]", pp_link_array[link].name);
	    } else {
		printf(" ()]");
	    }
	}
    }
    printf("]");
    printf("\n");
    printf("[");
    for (j=0; j<N_rows; j++ ){
	printf("%d ", row_starts[j]);
    }
    printf("]\n");
}

void compute_chosen_words(void) {
/*
   This takes the current chosen_disjuncts array and uses it to
   compute the chosen_words array.  "I.xx" suffixes are eliminated.
*/
    int i, l;
    char * s, *t, *u;
    for (i=0; i<N_words; i++) {   /* get rid of those ugly ".Ixx" */
	t = chosen_disjuncts[i]->string;
	if (is_idiom_word(t)) {
	    l = strlen(t);
	    s = (char *) xalloc(l+1);
	    free_this_string_later(s, l+1);
	    strcpy(s,t);
	    for (u=s; *u != '.'; u++)
	      ;
	    *u = '\0';
	    chosen_words[i] = s;
	} else {
	    chosen_words[i] = t;
	}
    }
    if (wall_defined) {
	chosen_words[0] = WALL_DISPLAY;
    }
}


#define MAX_HEIGHT 30

static char picture[MAX_HEIGHT][MAX_LINE];
static char xpicture[MAX_HEIGHT][MAX_LINE];

void print_links_graphically(void) {
/* print the diagram using globals: pp_link_array[], N_links, chosen_words[] */

    int i, j, k, cl, cr, row, top_row, width, flag;
    char *t, *s;
    int show_wall, print_word_0, N_wall_connectors, suppressor_used;
    char connector[MAX_TOKEN_LENGTH];
    int line_len, link_length;

    N_wall_connectors = 0;
    if (wall_defined) {
	suppressor_used = FALSE;
	for (j=0; j<N_links; j++) {
	    if (pp_link_array[j].l == 0) {
		N_wall_connectors ++;
		if (strcmp(pp_link_array[j].lc->string,WALL_SUPPRESS)==0) {
		    suppressor_used = TRUE;
		}
	    }
	}
	show_wall = (!suppressor_used) || (N_wall_connectors > 1);
    } else {
	show_wall = FALSE;
    }
/*    show_wall = TRUE;*/ /*a kludge for writing the post-processing section */
    
    print_word_0 = (!wall_defined || show_wall);
    
    set_centers(print_word_0);
    line_len = center[N_words-1]+1;
    
    for (k=0; k<MAX_HEIGHT; k++) {
	for (j=0; j<line_len; j++) picture[k][j] = ' ';
	picture[k][line_len] = '\0';
    }
    top_row = 0;
    
    for (link_length = 1; link_length < N_words; link_length++) {
	for (j=0; j<N_links; j++) {
	    if (pp_link_array[j].l == -1) continue;
	    if ((pp_link_array[j].r - pp_link_array[j].l) != link_length)
	      continue;
	    if (!print_word_0 && (pp_link_array[j].l == 0)) continue;
	    /* gets rid of the irrelevant link to the wall */
	    
	    /* put it into the lowest position */
	    cl = center[pp_link_array[j].l];
	    cr = center[pp_link_array[j].r];
	    for (row=0; row < MAX_HEIGHT; row++) {
		for (k=cl+1; k<cr; k++) {
		    if (picture[row][k] != ' ') break;
		}
		if (k == cr) break;
	    }
	    /* we know it fits, so put it in this row */

	    link_heights[j] = row;
	    
	    if (2*row+2 > MAX_HEIGHT-1) {
		printf("The diagram is too high.\n");
		return;
	    }
	    if (row > top_row) top_row = row;
	    
	    picture[row][cl] = '+';
	    picture[row][cr] = '+';
	    for (k=cl+1; k<cr; k++) {
		picture[row][k] = '-';
	    }
	    s = pp_link_array[j].lc->string;
	    if (!isupper(*s)) {
		s = "";   /* Don't print fat link connector name */
	    }
	    strncpy(connector, s, MAX_TOKEN_LENGTH-1);
	    connector[MAX_TOKEN_LENGTH-1] = '\0';
	    k=0;
	    for (t=connector; isupper(*t); t++) k++; /* uppercase len of conn*/
	    if ((cl+cr-k)/2 + 1 <= cl) {
		t = picture[row] + cl + 1;
	    } else {
		t = picture[row] + (cl+cr-k)/2 + 1;
	    }
	    s = connector;
	    while(isupper(*s) && (*t == '-')) *t++ = *s++; 
	    /*   only prints the upper case letters of the connector */
	    /*		while((*s != '\0') && (*t == '-')) *t++ = *s++;  */
	    /* part of the connector may be wiped out -- too bad */
	    
	    /* now put in the | below this one, where needed */
	    for (k=0; k<row; k++) {
		if (picture[k][cl] == ' ') {
		    picture[k][cl] = '|';
		}
		if (picture[k][cr] == ' ') {
		    picture[k][cr] = '|';
		}
	    }
	}
    }
    
    /* we have the link picture, now put in the words and extra "|"s */
    
    s = xpicture[0];
    if (print_word_0) k = 0; else k = 1;
    for (; k<N_words; k++) {
	t = chosen_words[k];
	i=0;
	while(*t != '\0') {
	    *s++ = *t++;
	    i++;
	}
	*s++ = ' ';
    }
    *s = '\0';
    
    if (display_short) {
	for (k=0; picture[0][k] != '\0'; k++) {
	    if ((picture[0][k] == '+') || (picture[0][k] == '|')) {
		xpicture[1][k] = '|';
	    } else {
		xpicture[1][k] = ' ';
	    }
	}
	xpicture[1][k] = '\0';
	for (row=0; row <= top_row; row++) {
	    strcpy(xpicture[row+2],picture[row]);
	}
	top_row = top_row+2;
    } else {
	for (row=0; row <= top_row; row++) {
	    strcpy(xpicture[2*row+2],picture[row]);
	    for (k=0; picture[row][k] != '\0'; k++) {
		if ((picture[row][k] == '+') || (picture[row][k] == '|')) {
		    xpicture[2*row+1][k] = '|';
		} else {
		    xpicture[2*row+1][k] = ' ';
		}
	    }
	    xpicture[2*row+1][k] = '\0';
	}
	top_row = 2*top_row + 2;
    }
    
    /* we've built the picture, now print it out */
    
    if (print_word_0) i = 0; else i = 1;
    k = 0;
    N_rows = 0;
    row_starts[N_rows] = 0;
    N_rows++;
    while(i < N_words) {
	putchar('\n');
	width = 0;
	do {
	    width += strlen(chosen_words[i])+1;
	    i++;
	} while((i<N_words) &&
	      (width + strlen(chosen_words[i])+1 < screen_width));
	row_starts[N_rows] = i+1;    /* PS junk */
	if (i<N_words) N_rows++;     /* same */
	for (row = top_row; row >= 0; row--) {
	    flag = TRUE;
	    for (j=k;flag&&(j<k+width)&&(xpicture[row][j]!='\0'); j++){
		flag = flag && (xpicture[row][j] == ' ');
	    }
	    if (!flag) {
		for (j=k;(j<k+width)&&(xpicture[row][j]!='\0'); j++){
		    putchar(xpicture[row][j]);
		}
		putchar('\n');
	    }
	}
	putchar('\n');
	k += width;
    }
    if (display_postscript) print_postscript_data(print_word_0);
}

void print_disjunct_counts(void) {
    int i;
    int c;
    Disjunct *d;
    for (i=0; i<N_words; i++) {
	c = 0;
	for (d=sentence[i].d; d != NULL; d = d->next) {
	    c++;
	}
	printf("%s(%d) ",sentence[i].string, c);
    }
    printf("\n\n");
}

void print_expression_sizes(void) {
    X_node * x;
    int w, size;
    for (w=0; w<N_words; w++) {
	size = 0;
	for (x=sentence[w].x; x!=NULL; x = x->next) {
	    size += size_of_expression(x->exp);
	}
	printf("%s[%d] ",sentence[w].string, size);
    }
    printf("\n\n");
}

void print_all_word_disjuncts(void) {
    int i;
    for (i=0; i<N_words; i++) {
	print_disjunct_list(sentence[i].d);
    }
    printf("\n\n");
}

/* Print the sentence
   assumes w chars have already been printed on the current line  */
/*
void print_sentence(int w) {
    int i, width;
    width = w;
    if (wall_defined) i=1; else i=0;
    for (; i<N_words; i++) {
	if (width + strlen(sentence[i].string)+1 >= screen_width) {
	    printf("\n");
	    width=0;
	}
	printf("%s ", sentence[i].string);
	width += strlen(sentence[i].string)+1;
    }
    printf("\n");
}
*/

void print_sentence(int w) {
/* this version just prints it on one line.  */
    int i;
    if (wall_defined) i=1; else i=0;
    for (; i<N_words; i++) {
	printf("%s ", sentence[i].string);
    }
    printf("\n");
}
