/* This program is used for evaluating the output of key programs. It
takes two files as input.  Each one must consist of a series of lines
of key-name items (e.g. "C" or "F#m"), with the names separated by
spaces.  Each line may have up to 10 items. The program will go
through and compare the items in the files. It will simply output the
total number of differences. If any lines have different numbers of
items between the two programs (or if the number of lines differs),
the program will print an error and exit. If the first file contains a
pivot chord (notated with a slash, for example "Cm/G"), the program
will award .5 difference points if the second file's key for that
segment is the same as either of the keys indicated. If neither key is
the same it will award zero points. (The second file may not contain
pivot chords.)

The program does not recognize enharmonic identities: Ab and G# are
treated as different.

Blank lines in the input are ignored. Entries for different pieces may
be separated in the first file by a line starting with a ":" (followed
by a comment if desired). There must be at least one ":" at the
beginning of the first file. The program will then print out the
difference score for each entry, followed by the total for all the
entries. */

#include <stdio.h>
#include <string.h>

FILE *first_file;
FILE *second_file;
char line[100];
char m[200][11][8];
char n[200][11][8];
int firstline[200];

int m_numlines, n_numlines;
int m_numitems[200], n_numitems[200];
int itemtotal=0;

main(argc, argv)
int argc;
char *argv[];
{
  int x=0, line_no=0;
  first_file = fopen(argv[1], "r");
  if (fopen(argv[1], "r") == NULL) {
    printf("I can't open that file\n");
    exit(1);
  }
  
  while (fgets(line, sizeof(line), first_file) !=NULL) {            
    line_no++;
    if(line[0]=='\n') continue;
    if(line[0]==':') {
       firstline[x]=1;
       continue;
    }
    m_numitems[x] = (sscanf (line, "%s %s %s %s %s %s %s %s %s %s %s", 
		   m[x][0], m[x][1], m[x][2], m[x][3], m[x][4], m[x][5], m[x][6], m[x][7], m[x][8], m[x][9],
		   m[x][10]));
    /* printf("number of items on line %d = %d\n", line_no, m_numitems[x]);  */
    if (m_numitems==0) continue;         /* skip over blank lines */
    if (m_numitems[x]>10) {
      printf("Error: file 1: too many items on line %d\n", line_no);
      exit(1);
    }
    if (m_numitems[x]<=10) itemtotal=itemtotal+m_numitems[x];
    x++;
  }
  m_numlines=x;
  x=0;
  printf("Total number of items in file 1 = %d\n", itemtotal);

  second_file = fopen(argv[2], "r");
  if (fopen(argv[2], "r") == NULL) {
    printf("I can't open that file\n");
    exit(1);
  }

  line_no=0;
  while (fgets(line, sizeof(line), second_file) !=NULL) {            
    line_no++;
    if(line[0]=='\n') continue;
    n_numitems[x] = (sscanf (line, "%s %s %s %s %s %s %s %s %s %s %s",
		   n[x][0], n[x][1], n[x][2], n[x][3], n[x][4], n[x][5], n[x][6], n[x][7], n[x][8], n[x][9],
		   n[x][10]));
    if (n_numitems==0) continue;         /* skip over blank lines */
    if (n_numitems[x]>10) {
      printf("Error: file 2: too many items on line %d\n", line_no);
      exit(1);
    }
    /* printf("number of items on line %d = %d\n", line_no, n_numitems[x]);  */
    if(m_numitems[x]!=n_numitems[x]) {
      printf("Error: the number of items on line %d (file 2) differs between the two files\n", line_no);
      exit(1);
    }
    x++;
  }
  n_numlines=x;
  if (m_numlines!=n_numlines) {
    printf("Error: the number of lines in the two files is different\n");
    exit(1);
  }
  compare();
}

compare()
{
  int i, j, c, subc, halfmatch, entry=0, mod=0; 
  float t=0, total=0;
  char first_subitem[8], second_subitem[8];
  for(i=0; i<m_numlines; i++) {
    if (firstline[i]==1) {
      entry++;
      if(entry>1) {
	printf("differences for entry %d = %4.1f\n", entry-1, t);
	total=total+t;
	t=0;
      }
    }
    /* Here we count the modulations in the second file. First we compare the first item in the line to the last item
       in the previous line (if it's not the first line of an entry). Then we compare each subsequent item in the line to
       the previous item. */

    if (firstline[i]==0) {
      if(strcmp(n[i][0], n[i-1][m_numitems[i-1]-1]) !=0) mod++;
    }
    for(j=1; j<m_numitems[i]; j++) {
      if(strcmp(n[i][j], n[i][j-1]) !=0) mod++;
    }

    /* Now we compare items in the two files. */

    for(j=0; j<m_numitems[i]; j++) {
      halfmatch=0;
      if(strcmp(m[i][j], n[i][j]) !=0) {
	for(c=0; c<8; c++) {
	  if(m[i][j][c]=='/') {
	    /* printf("slash found in line %d, item %d\n", i, j); */
	    for (subc=0; subc<c; subc++) {
	      first_subitem[subc]=m[i][j][subc];
	    }
	    for (subc=c; subc<8; subc++) {
	      first_subitem[subc]='\0';
	    }
	    /* printf ("%s\n", first_subitem); */
	    if(strcmp(first_subitem, n[i][j])==0) halfmatch=1;

	    for (subc=0; subc<(8-c); subc++) {
	      second_subitem[subc]=m[i][j][c+1+subc];
	    }
	    /* printf ("%s\n", second_subitem); */
	    if(strcmp(second_subitem, n[i][j])==0) halfmatch=1;
	  }
	}
	if (halfmatch==1) t=t+0.5;
	else t++;
      }
    }
  }
  printf("differences for entry %d = %4.1f\n", entry, t);
  total=total+t;
  printf("Number of differences = %4.1f\n", total);
  printf("Proportion correct = %6.3f\n", ((double)itemtotal-total) / (double)itemtotal);
  printf("Number of modulations in second file = %d\n", mod);
}

