/*=====================================================================*/
/*(C) Copyright 1991, Fred Hutchinson Cancer Research Center           */
/*        universa.c   Convert GENBANK, PIR or EMBL to universal format*/
/*    USE:  universa db_filename uni_filename                          */
/*    Universal format resembles FASTA type 0, but includes features to
      support GenePro format:
       1st line is title starting with ">" and ending with "$"
       Sequence starts on second line and ends with "*"                */
/*---------------------------------------------------------------------*/
/*   10/7/90   Changed EMBL $ to %                                     */
/*   10/13/90  db_info memory allocation changed.                      */
/*   10/29/90  Fixed bug with title when multiple description lines.   */
/*    1/10/91  Changed to filter out CRs for UNIX.                     */
/*   11/23/91  Comments & copyright. Changed to use motmisc.o          */
/* >>>>>>>>>>>>Blocks 5.0 and Blocks 6.0 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      8/11/93  Limit title line to MAXTITLE characters. 
		Still has $ and * for patmat.
   >>>>>>>>>>>>Blocks 6.2, 7.0, 7.2 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
     11/28/93  Problem missing fragments if word FRAGMENT past MAXTITLE
               characters
   >>>>>>>>>>>>Blocks 8.x, 9.x <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
     12/29/96  Put PROSITE group on title line if SwissProt db, dropped $
		at end of title. Added -s option for short title & no * at
                end of sequence (why is this still needed?)
      6/ 6/98  For EMBL format, put AC as well as ID on title line
      6/10/98  Never put * at end of sequence.
      1/27/99  No blank lines after sequences
      9/22/99  For EMBL format, put multiple ACs on title line;
		don't duplicate ID line (trembl)
=======================================================================*/

#include "motifj.h"

void init_dbs();              /* from motmisc */
int type_dbs();               /* from motmisc */
int convert();

/*======================================================================*/
void main(argc, argv)
int argc;
char *argv[];
{
   FILE *fin, *fout;
   char infile[50], outfile[50], defname[50], *ptr;
   struct db_info *dbs[MAXDB];
   int totseqs;
   int short_title;

   printf("UNIVERSA: (C) Copyright 1991,");
   printf(" Fred Hutchinson Cancer Research Center\n");
   if (argc < 2)
   {
      printf("USAGE:  universa db_file uni_file [-s]\n");
      printf("           db_file = input database (EMBL, GB, PIR)\n");
      printf("           uni_file = output file\n");
      printf("           -s flag => short title (no description)\n");
   }
   if (argc > 1)
      strcpy(infile, argv[1]);
   else
   {
      printf("\nEnter name of file to convert: ");
      gets(infile);
   }
   if ( (fin=fopen(infile, "r")) == NULL)
   {
      printf("\nCannot open file %s\n", infile);
      exit(-1);
   }
   if (argc > 2)
      strcpy(outfile, argv[2]);
   else
   {
      strcpy(defname, infile);
      ptr = strtok(defname, ".");  strcat(ptr, ".uni");
      printf("\nEnter name of output file [%s]: ", defname);
      gets(outfile);
      if (strlen(outfile) < 2)
	 strcpy(outfile, defname);
   }
   if ( (fout=fopen(outfile, "w+")) == NULL)
   {
      printf("\nCannot open file %s\n", outfile);
      exit(-1);
   }
   /* optional flag for short title  */
   short_title = NO;
   if (argc > 3 && strncmp(argv[3], "-s", 2) == 0) short_title = YES;

   init_dbs(dbs);

/*---------------------------------------------------------------------*/
   totseqs = convert(dbs, fin, fout, short_title);
   printf("\n%d sequences processed\n", totseqs);

   fclose(fin);  fclose(fout);
   exit(0);
}  /*  end of main */

/*======================================================================*/
int convert(dbs, fin, fout, short_title)
struct db_info *dbs[];
FILE *fin, *fout;
int short_title;
{
   int nseq, i, db, ilen, frag;
   char line[MAXLINE], title[MAXLINE], temp[MAXLINE], *ptr;
   char id[20], acc[MAXLINE], desc[MAXLINE], start[MAXLINE];

   nseq = 0;
   db = -1;
/*---------  Figure out what type of input file it is ------------------*/
   db = type_dbs(fin, dbs);
   if (db >= 0 && db < MAXDB)
   {
      printf("\nProcessing input file as %s", dbs[db]->type);
      do
      {
/*------------  Put together the title line ----------------------------*/
/*---- Collects all ->start and ->desc lines until the next ->seq line -*/
	 if (strncmp(line, dbs[db]->start, strlen(dbs[db]->start)) == 0)
	 {
	    nseq += 1;
            id[0] = acc[0] = start[0] = desc[0] = '\0';
	    ptr = strtok(&line[dbs[db]->title_offset], " ");
	    strcpy(start, ptr);
            if (strlen(ptr) > 19) ptr[19] = '\0';
	    strcpy(id, ptr);		/* save the id for later */
	    while(fgets(line, MAXLINE, fin) != NULL &&
	       strncmp(line, dbs[db]->seq, strlen(dbs[db]->seq)) != 0)
	    {
	       if (strncmp(line, dbs[db]->desc, strlen(dbs[db]->desc)) == 0 &&
                   !short_title &&
                   strlen(title) + strlen(line) < MAXLINE )
	       {
		  strcat(desc, &line[dbs[db]->title_offset]);
		  desc[strlen(desc)-2] = '\0';         /* get rid of CRLF */
	       } /* end of ->desc  */
	       if (strncmp(line, dbs[db]->acc, strlen(dbs[db]->acc)) == 0 &&
                   !short_title &&
                   strlen(title) + strlen(line) < MAXLINE )
	       {
		  strcat(acc, &line[dbs[db]->title_offset]);
		  acc[strlen(acc)-2] = '\0';         /* get rid of CRLF */
                  if (db == EMBL)
                  {
		     /*  AC   O87740; Q47256;  */
                     temp[0] = '\0';
                     ptr = strtok(acc, "; \n\r\t");
                     while (ptr != NULL)
                     {
                        if (strcmp(ptr, id) != 0)  /* don't repeat the id */
                        {
                           strcat(temp, "|");
			   strcat(temp, ptr);
                        }
		        ptr = strtok(NULL, "; \n\r\t");
                     }
                     strcpy(acc, temp);
                  }
	       } /* end of ->acc  */
               if (db == EMBL &&
	           (strncmp(line, "DR   PROSITE", 12) == 0) &&
                   (strlen(title) + 10 < MAXLINE)  )
	       {
                  strcpy(temp, title); strcat(temp, " | ");
                  strncat(temp, &line[14], 7);
                  temp[strlen(title)+10] = '\0';
                  strcpy(title, temp);
               }  /* end of PROSITE */
	    }   /*  end of descriptive stuff */

            /*--------------Put together the title--------------------*/
            if (acc) 
            {
               if (db == EMBL)  /* already has |; put id first */
               { sprintf(title, "%s%s %s\n", start, acc, desc); }
               else
               { sprintf(title, "%s|%s %s\n", acc, start, desc); }
            }
            else
            { sprintf(title, "%s %s\n", start, desc); }

            frag = NO;
            if (strstr(title, "FRAGMENT") != NULL ||
                strstr(title, "fragment") != NULL)   frag = YES;
	    if (strlen(title) >= MAXTITLE)
            {
                title[MAXTITLE] = '\0';
                /*  If "FRAGMENT" got chopped off, put it back  */
                if (frag && strstr(title, "FRAGMENT") == NULL &&
                        strstr(title, "fragment") == NULL)
                {
                   if (strlen(title) >= (MAXTITLE-11) ) 
                      title[MAXTITLE-11] = '\0';
                   strcat(title, " (FRAGMENT)");
                }
            }
	    fprintf(fout, ">%s\n", title);

/*------ Process the sequence ------------------------------------------*/
	    while(!feof(fin) && fgets(line, MAXLINE, fin) != NULL &&
	       strncmp(line, dbs[db]->end, strlen(dbs[db]->end)) != 0)
	    {
               for (i=0; i<strlen(line); i++)     /* change CR to space */
                  if (line[i] == CR)  line[i] = ' ';
	       fprintf(fout, &line[dbs[db]->seq_offset]);
	    }  /*  end of sequence */
/*            if (!short_title) fprintf(fout, "\n");   was "*\n" */
	 }  /*  end of start of entry */
      }  while (!feof(fin) && fgets(line, MAXLINE, fin) != NULL);

   }

   return(nseq);
}  /* end of convert */
