/*   
  blDR.c:  blDR <blocks in> <sequence db> <blocks out>
           Read blocks, look up sequences in a file of sequences,
	   rewrite sequence names in blocks, write an output file
           for the DR line of Swiss-Prot:

DR   BLOCKS; BL00405; 43_KD_POSTSYNAPTIC.
Q13702
P12672
P09108
//
--------------------------------------------------------------------
 6/ 9/99 J.Henikoff
 6/ 9/03 Free up memory
====================================================================*/

#define BLDR_C_
#define EXTERN
#define MAXNAME 80	/* Maximum file name length */

#include "blocksprogs.h"

struct name_list 
{ 
  char name[MAXNAME];
  struct name_list *next;
};
void revise_names();

/*=======================================================================*/
/*
 * main
 */

int main(argc, argv)
     int argc;
     char *argv[];
{
   FILE *bfp, *sfp, *ofp;
   Block *block;
   int i;
   char bdbname[MAXNAME], sdbname[MAXNAME], outname[MAXNAME], ctemp[MAXNAME];
   char lastac[10];
   Sequence *seq;
   struct name_list *dbnames, *db, *new;

   ErrorLevelReport = 2;

   if (argc < 3)
   {
      printf("COPYRIGHT 1999, Fred Hutchinson Cancer Research Center\n");
      printf("blDR <blocks in> <sequences> <blocks out>\n");
   }
   /* ------------1st arg = blocks database -------------------------------*/
   if (argc > 1) strcpy(bdbname, argv[1]);
   else
   {
      printf("\nEnter name of blocks database: ");
      gets(bdbname);
   }
   if ( (bfp=fopen(bdbname, "r")) == NULL)
   {
      printf("\nCannot open file %s\n", bdbname);
      exit(-1);
   }
   /* ------------2nd arg = sequence database ---------------------*/
   if (argc > 2) strcpy(sdbname, argv[2]);
   else
   {
      printf("\nSequence database must be in fasta format:");
      printf("\nEnter name of sequence database: ");
      gets(sdbname);
   }
   if ( (sfp=fopen(sdbname, "r")) == NULL)
   {
      printf("\nCannot open file %s\n", sdbname);
      exit(-1);
   }
   /* ------------3rd arg = new blocks database ---------------------*/
   if (argc > 3) strcpy(outname, argv[3]);
   else
   {
      printf("\nEnter name of new blocks database: ");
      gets(outname);
   }
   if ( (ofp=fopen(outname, "w")) == NULL)
   {
      printf("\nCannot open file %s\n", outname);
      exit(-1);
   }

   /*------------------------------------------------------------------*/
   /* Make a list of all the database sequence names */
   dbnames = (struct name_list *) malloc (sizeof(struct name_list));
   dbnames->next = NULL;
   db = dbnames;
   while( (seq = read_a_sequence(sfp, FASTA, AA_SEQ)) != NULL)
   {
      if ((int) strlen(seq->name) > MAXNAME) { seq->name[MAXNAME] = '\0'; }
      new = (struct name_list *) malloc (sizeof(struct name_list));
      strcpy(new->name, seq->name);
      new->next = NULL;
      db->next = new;
      db = new;
      free_sequence(seq);
   }
   close(sfp);

   /*-----------------------------------------------------------------*/
   lastac[0] = '\0'; 
   while ((block = read_a_block(bfp)) != NULL)
   {
     strcpy(ctemp, block->ac); ctemp[7] = '\0';
     if (strcmp(lastac, ctemp) != 0)
     {
         revise_names(block, dbnames, TRUE);  /* DR output 1st block of fam */
         strcpy(lastac, ctemp);
     }
     else
     {
         revise_names(block, dbnames, FALSE);
     }
     output_block(block, ofp, INT_OUTPUT);
     free_block(block);
   }
   
   fclose(bfp); fclose(ofp);
   exit(0);

}  /* end of main */


/*=======================================================================
     Find ID in sequence database, which is assumed to have title lines:

	>ID|AC

     Then change names to from "ID" to "ID|AC" in block
*/
void revise_names(block, dbnames, drflag)
Block *block;
struct name_list *dbnames;
int drflag;
{
   int s, done;
   char ctemp[MAXNAME], *ptr;
   struct name_list *db;

   if (drflag)
   {
      strcpy(ctemp, block->ac); ctemp[7] = '\0';
      printf("DR   BLOCKS; %s; %s\n", ctemp, block->de);
   }

   /*  Compare each block seq name vs list of db seq names */
   for (s=0; s< block->num_sequences; s++)
   {
      done = 0;
      db = dbnames->next;
      while (!done && db != NULL)
      {
        strcpy(ctemp, db->name);
        ptr = strtok(ctemp, "|");
        if (ptr != NULL)  /* don't bother if no "|" in seq->name */
        {
           if (strcmp(block->sequences[s].name, ctemp) == 0)
           {
               /* only want ID|AC, not ID|AC|AC|...  */
               strcpy(block->sequences[s].name, db->name);
               done = 1;
               if (drflag)
               {
                  if (ptr != NULL)
                  { 
                     ptr = strtok(NULL, "\0");
                     if (ptr != NULL) printf("%s\n", ptr);
                     else { printf("%s\n", db->name); }
                  }
                  else { printf("%s\n", db->name); }
               }
           }
        }
        db = db->next;
      }  /* end of dbnames seq db */
   }   /* end of block seq s */

   if (drflag) printf("//\n");
}  /*end of revise_names */
