/************************************************************************
*									*
*			output.c - V1.1 (10/01/94)			*
*									*
*		by    Chris Walshaw (C.Walshaw@gre.ac.uk)		*
*									*
* 	Copyright Chris Walshaw. Permission is granted to use and	*
*	copy provided that this copyright notice remains attached.	*
*	This code may not be sold.					*
*									*
************************************************************************/

#include <stdio.h>

FILE  *fopen(),*In,*Out,*Log;
char  fname[99];

void  article(s,t)
char  *s,*t;
{
  char  *i = s;
  while (*s != '\0' && *s++ != ',');
  if (*(s-1) == ',') {
    s += 1;
    while (*s != '\0')
      *t++ = *s++;
    if (*(t-1) != '\'')
      *t++ = ' ';
  }
  while (*i != '\0' && *i != ',')
    *t++ = *i++;
  *t = '\0';
}

void  detex(s,t)
char  *s,*t;
{
  while (*s != '\0') {
    *t++ = *s++;
    if (*s == '\\') {
      s += 2;
      if (*s == ' ')
        s += 1;
    }
  }
  *t = '\0';
}

char  *getsIn(s)
char  *s;
{
  if (fgets(s,999,In) == NULL) {
    return(NULL);
  } else {
    s[strlen(s)-1]='\0';
    return(s);
  }
}

int  range(first,last,input)
int  *first,*last;
char  **input;
{
  if (**input == '\0') {
    *first = 999;
    *last = 999;
    return(1);
  }
  if (**input == '-')
    *first = 1;
  else if (**input >= '0' && **input <= '9') {
    (void) sscanf(*input,"%d",first);
    while (**input >= '0' && **input <= '9')
      (*input)++;
  } else {
    return(0);
  }

  if (**input == '-') {
    (*input)++;
    if (**input == '\0')
      *last = 999;
    else if (**input >= '0' && **input <= '9') {
      (void) sscanf(*input,"%d",last);
      while (**input >= '0' && **input <= '9')
        (*input)++;
      if (**input == ',')
        (*input)++;
    } else
       return(0);
  } else if (**input == ',') {
    *last = *first;
    (*input)++;
  } else if (**input == '\0')
    *last = *first;
  else
    return(0);
  return(1);
}

void  fname_error(string)
char  *string;
{
  (void) printf("error in input file %s\n",string);
  (void) printf("abandoning file \"%s\"\n",fname);
  (void) fclose(In);
}

void  input_error()
{
  (void) printf("error in input format\n");
  (void) printf("abandoning file \"%s\"\n",fname);
  (void) fclose(In);
}

void  tex_header(Out)
FILE  *Out;
{

  (void) fprintf(Out,"\\input musicnft\n");
  (void) fprintf(Out,"\\input musictex\n");
  (void) fprintf(Out,"\\input musicvbm\n");
  (void) fprintf(Out,"\\input musictrp\n");
  (void) fprintf(Out,"\\input zmacros\n");
#ifdef MINE
  (void) fprintf(Out,"\\input dscgrphy\n");
#endif
  (void) fprintf(Out,"\\input header\n\n");
}

int  main(argc,argv)
int  argc;
char  **argv;
{
  int  ok = 0,t,c,first,last,x,d,logn=0,logn_total=0,log=0,log_total=0,trnsps=0;
  int  m;
  char  f = '\0',input[99],xfile[99],titles,ttl;
  char  dflt_meter[6],xnmbr[999],full_title[99],xline[999],title[20][99];
  char  source[99],cmpsr[99],notes[999],lmskp[99],meter[99],rhthm[99],tonic[99];
  char  origin,words[999],*pinput,area[99],znote[99],parts[99];
#ifdef MINE
  char  favrt[99];
#endif
  source[0] = '\0';

  Log = fopen("abc2mtex.log","w");

  if (argc == 2)
    f = argv[1][0];

  while (!ok) {
    if (f == '\0') {
      (void) printf("\nselect format:\n");
      (void) printf("\tx - xbook\n");
      (void) printf("\tm - music\n");
      (void) printf("\tt - music (transposable)\n");
      (void) printf("\ti - index\n");
      (void) printf("\tn - notes\n");
      (void) gets(input);
      f = input[0];
    }

    if (f == 't') {
      f = 'm';
      trnsps = 1;
    }

    if (f=='x' || f=='m' || f=='i' || f=='n')
      ok = 1;
    else {
      (void) printf("selection not recognised\n");
      f = '\0';
    }
  }

  if (f == 'x' || f == 'm') {
    Out = fopen("music.tex","w");
    tex_header(Out);
  } else if (f == 'i') {
    Out = fopen("index","w");
  } else if (f == 'n') {
    Out = fopen("notes","w");
  }

  do {
start:

    if (ok)
      ok = 0;
#ifndef MINE
    else {
      (void) fprintf(Log,"%s                                 ",xfile);
      (void) fprintf(Log,"                       %4d  %4d\n",logn,log);
    }
#endif
    logn_total += logn;
    logn = 0;
    log_total += log;
    log = 0;

    (void) printf("\nselect tunes: ");
    (void) gets(input);
    (void) printf("\n");

    if ((!strcmp(input,"q")) || (!strcmp(input,"quit")))
      input[0] = '\0';

    if (input[0] == '\\') {
      (void) fprintf(Out,"%s\n\n",input);
      goto start;
    }

    c = 0;
    while (c < 4)
      xfile[c++] = ' ';
    xfile[4] = '\0';

    c = 0;
    while (input[c] != ':' && input[c] != '\0') {
      xfile[c] = input[c];
      fname[c] = input[c];
      c += 1;
    }
    fname[c] = '\0';
    if (c > 4)
      xfile[c] = '\0';

    if (c > 0) {

      if (input[c] == '\0')
        (void) strcpy(&input[c],":-");
      else if (input[c] != ':') {
        input_error();
        goto start;
      }
      pinput = &input[c+1];

      if ((In = fopen(fname,"r")) == NULL) {
        (void) printf("file \"%s\" does not exist\n",fname);
        goto start;
      } else {
        if ((getsIn(dflt_meter)) == NULL ||
          (strncmp(dflt_meter,"M:",2)) != 0) {
          (void) printf("error in default meter\n");
          (void) printf("abandoning file \"%s\"\n",fname);
          (void) fclose(In);
          goto start;
        }

        if (!(range(&first,&last,&pinput))) {
          input_error();
          goto start;
        }

        x = 0;

        while ((getsIn(xnmbr)) != NULL) {

          if ((strncmp(xnmbr,"X:",2)) == 0) {
            (void) sscanf(&xnmbr[2],"%d",&x);

            if (x >= first && x <= last) {
              origin = xfile[1];
              ++logn;
              ++log;
              (void) getsIn(full_title);
              if ((strncmp(full_title,"T:",2)) != 0) {
                fname_error("title");
                goto start;
              }

              if (f == 'x' || f == 'm') {
                article(&full_title[2],title[0]);
                detex(title[0],full_title);
              } else {
                detex(&full_title[2],title[0]);
                article(title[0],full_title);
              }
              (void) printf(" processing \"%s%4d %s\"\n",xfile,x,full_title);

              d = 0;
              while (source[d] != '\0') source[d++] = '\0';
              d = 0;
#ifdef MINE
              favrt[0] = '\0';
#endif
              words[0] = '\0';
              cmpsr[0] = '\0';
              notes[0] = '\0';
              parts[0] = '\0';
              lmskp[0] = '\0';
              area[0] = '\0';
              znote[0] = '\0';
              titles = 1;
              (void) strcpy(meter,&dflt_meter[2]);
              (void) strcpy(rhthm,&xfile[2]);
              (void) getsIn(xline);

              while ((strncmp(xline,"K:",2)) != 0) {

                if ((strncmp(xline,"T:",2)) == 0) {
                  ++logn;
                  if (f == 'x' || f == 'm')
                    article(&xline[2],title[titles++]);
                  else
                    detex(&xline[2],title[titles++]);
#ifdef MINE
                } else if ((strncmp(xline,"F:",2)) == 0) {
                  (void) strcpy(favrt,&xline[2]);
                } else if ((strncmp(xline,"D:",2)) == 0) {
                  if (f == 'x' || f == 'm') {
                    if (d > 0)
                      d += strlen(strcpy(&source[d],", "));
                    xline[4] = '\0';
                    (void) sprintf(&source[d],"{\\%s}",&xline[2]);
                    d += 5;
                    if (xline[7] != '\0') {
                      d += strlen(strcpy(&source[d]," -- "));
                      d += strlen(strcpy(&source[d],&xline[7]));
                    }
                  } else {
                    if (d == 0)
                      source[d++] = ' ';
                    d += strlen(strncpy(&source[d],&xline[1],6));
                  }
                  source[d] = '\0';
#endif
                } else if ((strncmp(xline,"S:",2)) == 0) {
                  if (f == 'x' || f == 'm') {
                    if (d > 0)
                      d += strlen(strcpy(&source[d],", "));
                    d += strlen(strcpy(&source[d],&xline[2]));
                  }
                } else if ((strncmp(xline,"C:",2)) == 0) {
                  (void) strcpy(cmpsr,&xline[2]);
                } else if ((strncmp(xline,"A:",2)) == 0) {
                  (void) sprintf(area," (%s)",&xline[2]);
                } else if ((strncmp(xline,"N:",2)) == 0) {
                  (void) strcpy(notes,&xline[2]);
                } else if ((strncmp(xline,"P:",2)) == 0) {
                  (void) strcpy(parts,&xline[2]);
                } else if ((strncmp(xline,"W:",2)) == 0) {
                  (void) strcpy(words,&xline[2]);
                } else if ((strncmp(xline,"E:",2)) == 0) {
                  (void) strcpy(lmskp,&xline[2]);
                } else if ((strncmp(xline,"M:",2)) == 0) {
                  (void) strcpy(meter,&xline[2]);
                } else if ((strncmp(xline,"O:",2)) == 0) {
                  origin = xline[2];
                } else if ((strncmp(xline,"R:",2)) == 0) {
                  (void) strcpy(rhthm,&xline[2]);
                  if (rhthm[1] == '\0') {
                    rhthm[1] = ' ';
                    rhthm[2] = '\0';
                  }
                } else if ((strncmp(xline,"Z:",2)) == 0) {
                  (void) strcpy(znote,&xline[2]);
                } else if ((strncmp(xline,"I:",2)) == 0) {
                  /* Ignore it */;
                } else {
                  fname_error(title[0]);
                  goto start;
                }

                (void) getsIn(xline);
              }

              (void) strcpy(tonic,&xline[2]);

              if (f == 'x') {
                (void) fprintf(Out,"\\message{");
                for (m = 0; m < 10; ++m)
                  (void) fprintf(Out,"*");
                (void) fprintf(Out," %s ",full_title);
                for (m = 0; m < 67 - strlen(full_title); ++m)
                  (void) fprintf(Out,"*");
                (void) fprintf(Out,"}\n");
                if (znote[0] != '\0')
                  (void) fprintf(Out,"\\message{%s}\n",znote);
                (void) fprintf(Out,"\\line{\\hfil %d. %s",x,title[0]);
                if (source[0] != '\0')
                  (void) fprintf(Out," {\\it(%s)}",source);
                (void) fprintf(Out," \\hfil");
                if (cmpsr[0] != '\0')
                  (void) fprintf(Out," {\\eightsl %s}",cmpsr);
                if (area[0] != '\0')
                  (void) fprintf(Out," {\\eightsl%s}",area);
                (void) fprintf(Out,"}\\nobreak\n");
                if (notes[0] != '\0')
                  (void) fprintf(Out,"\\centerline{\\sevenrm %s}\\nobreak\n",notes);
                if (words[0] != '\0')
                  (void) fprintf(Out,"{\\sevenrm %s}\n\n",words);
                if (titles > 1) {
                  if (titles < 6)
                    (void) fprintf(Out,"\\centerline");
                  (void) fprintf(Out,"{\\sevenrm AKA");
                  for (ttl = 1; ttl < titles; ++ttl) {
                    (void) fprintf(Out," %s",title[ttl]);
                    if (ttl < titles-1)
                      (void) fprintf(Out,";");
                  }
                  (void) fprintf(Out,"}");
                  if (titles < 6)
                    (void) fprintf(Out,"\\nobreak\n");
                  else
                    (void) fprintf(Out,"\n\n");
                }
                if (parts[0] != '\0')
                  (void) fprintf(Out,"\\line{\\sevenrm Play %s\\hfil}\\nobreak\n",parts);

              } else if (f == 'm') {
                (void) fprintf(Out,"\\message{");
                for (m = 0; m < 10; ++m)
                  (void) fprintf(Out,"*");
                (void) fprintf(Out," %s ",full_title);
                for (m = 0; m < 67 - strlen(full_title); ++m)
                  (void) fprintf(Out,"*");
                (void) fprintf(Out,"}\n");
                (void) fprintf(Out,"\\line{\\hfil %s \\hfil",title[0]);
                if (cmpsr[0] != '\0')
                  (void) fprintf(Out," {\\eightsl %s}",cmpsr);
                if (area[0] != '\0')
                  (void) fprintf(Out," {\\eightsl%s}",area);
                (void) fprintf(Out,"}\\nobreak\n");

              } else if (f == 'i' && strlen(xfile) <= 4) {
                for (ttl = 0; ttl < titles; ++ttl) {
                  t = 0;
                  while (title[ttl][t++] != '\0')
                    if ((title[ttl][t-1] == ' ' || title[ttl][t-1] == '[' ||
                         title[ttl][t-1] == '-')
                        && title[ttl][t] >= 'a' && title[ttl][t] <= 'z')
                      title[ttl][t] = 'A' - 'a' + title[ttl][t];
#ifndef MINE
                  (void) fprintf(Out,"%s%4d %c %s %s%s%s\n",
                    xfile,x,origin,rhthm,title[ttl],area,source);
#else
                  if (titles == 1)
                    (void) fprintf(Out,"%s%4d   %c %s %s%s%s",
                      xfile,x,origin,rhthm,title[ttl],area,source);
                  else
                    (void) fprintf(Out,"%s%4d.1 %c %s %s%s%s",
                      xfile,x,origin,rhthm,title[ttl],area,source);
                  t = 0;
                  if (ttl == 0)
                    while (favrt[t] != '\0')
                      (void) fprintf(Out," {%c}",favrt[t++]);
                  (void) fprintf(Out,"\n");
#endif
                }

              } else if (f == 'i') {
                (void) printf("can't index %s - name > 4 characters\n",xfile);
                goto start;
              } else if (f == 'n') {
              }

              if (f == 'x' || f == 'm') {
                abc2tex(full_title,meter,tonic,lmskp,trnsps,Out);
                (void) fprintf(Out,"\n");
              } else
                while ((getsIn(xline)) != NULL && strlen(xline) != 0) {}
            }

            if (x == last && (!(range(&first,&last,&pinput)))) {
              input_error();
              goto start;
            }

          }

        }

        (void) printf("end of file \"%s\"\n",fname);
        (void) fclose(In);

      }
    }

  } while (input[0] != '\0');
  (void) printf("\n");
  if (f == 'x' || f == 'm')
    (void) fprintf(Out,"\\end\n");
  (void) fprintf(Log,"X                                            ");
  (void) fprintf(Log,"               %4d  %4d\n",logn_total,log_total);
  return(0);
}
