/*=====================================================================*/
/*(C) Copyright 1992-1999, Fred Hutchinson Cancer Research Center           */
/*        getblock.c  Extracts blocks from a blocks database           */
/*      USE: getblock family blocks_file cobbler_file map_file tree_file
                      proweb_file blk2pdb_file [prosite_dir]

	->start = ID   name; BLOCK.
		  AC   Block accession #
	->desc  = DE   description.
		  BL   block info.
		  sequences
	->end   = //                                                   */
/*---------------------------------------------------------------------*/
/*    8/5/92   J. Henikoff                                             */
/*    2/26/96  Looks for cobbler.pros sequence in blocks dir           */
/*    5/29/96  Looks for proweb.dat in blocks dir                      */
/*    5/30/96  Fix problem in get_cob() with lower case                */
/*    7/12/96  Fixed problem recognizing PDOC lines (PDOC00199)
      7/15/96  Modified proweb.dat format
      9/ 4/96  Added Version, read trees.dat
     11/ 6/96  Fixed bug in get_doc()
      3/ 6/97  Changes for Prints, separate args for each file
      7/31/97  Added map structures file
      5/ 8/98  Added blk2pdb.dat
      7/ 8/98  Added blinks.dat; links from individual blocks to ProDom
      9/ 7/98  Fixed problem finding prosite files
      7/ 1/99  Maps can start with ">" or "#MAP# "
     12/17/99  Longer AC; replaced get_cob() & get_tree() with get_fasta()
      5/20/00  Change IPR prefix to IPB and PS to BL (BlockFam)
      2/21/01  Added cyrca.dat  <<<<<INCOMPLETE>>>>
     10/ 4/02  Special fixes for Chrom entries
=======================================================================*/
#include "motifj.h"

/*		Routines from motmisc.c           */
void init_dbs();
int type_dbs();
struct split_name *split_names();

int get_blk();
void get_map();
void get_fasta();
void get_proweb();
void get_blinks();
void get_pdb();
void get_cyrca();
void get_prosite();
void get_doc();

char Version[12] = "  5/20/00.1";
char BlockFam[15];
/*======================================================================*/
int main(argc, argv)
int argc;
char *argv[];
{
   FILE *fblk, *fcob, *fweb, *flnk, *fmap, *ftre, *fdat, *fpdb, *fcyr, *fdoc;
   char blkfile[FNAMELEN], defname[FNAMELEN], cobfile[FNAMELEN];
   char prosite[FNAMELEN], webfile[FNAMELEN], mapfile[FNAMELEN];
   char treefile[FNAMELEN], pdbfile[FNAMELEN], lnkfile[FNAMELEN];
   char cyrfile[FNAMELEN];
   struct db_info *dbs[MAXDB];
   struct split_name *blksplit;
   int plen, done;

   if (argc < 3)
   {
      printf("GETBLOCK: (C) Copyright 1992-1999, ");
      printf("Fred Hutchinson Cancer Research Center\n");
      printf("Version %s\n", Version);
      printf("USAGE:  getblock AC blocks cobb maps trees proweb blinks blk2pdb cyrca ");
      printf("[prosite_dir]\n");
      printf("		AC = block accession (eg BL00094 or IPB001525)\n");
      printf("		blocks = name of blocks database file\n");
      printf("		cobb = name of cobbler database file\n");
      printf("		maps = name of map structure database file\n");
      printf("		trees = name of tree structure database file\n");
      printf("		proweb = name of Proweb database file\n");
      printf("		blinks = name of file of links to ProDom\n");
      printf("		blk2pdb = name of PDB cross-reference file\n");
      printf("		cyrca = name of CYRCA cross-reference file\n");
      printf("		prosite_dir = name of directory containing ");
      printf("prosite.dat and prosite.doc files\n");
   }
  
/*--------------------- Load DB format information ---------------------*/
   init_dbs(dbs);

/*------------------- arg 1:  Accession # ------------------------------*/
   if (argc > 1)
      strcpy(BlockFam, argv[1]);
   else
   {
      while(strlen(BlockFam) < MINAC)
      {
	 printf("\nEnter Block accession number: ");
	 gets(BlockFam);
      }
   }
   /*   Chop off any A-Z block designator at the end */
   /*   Can't do this for ChromDMT, etc  have to just truncate it  */
   plen = strlen(BlockFam);
   if (strncmp(BlockFam, "Chrom", 5) != 0)
   {
      done = NO;
      while (!done && plen >= MINAC)
      {
         if (isalpha(BlockFam[plen])) { BlockFam[plen] = '\0'; done = YES; }
         else { plen--; }
      }
   }
   else if (plen > 8)
   {  BlockFam[8] = '\0'; }
   /*  Change PS to BL and IPR to IPB  */
   if (toupper(BlockFam[0]) == 'P' && toupper(BlockFam[1]) == 'S')
   {   BlockFam[0] = 'B'; BlockFam[1] = 'L';     }
   else
   {
      if (toupper(BlockFam[0]) == 'I' && toupper(BlockFam[1]) == 'P' &&
          toupper( BlockFam[2]) == 'R')
      {   BlockFam[2] = 'B';  }
   }


/*------------------arg 2: blocks database name ----------------------*/
   if (argc > 2)
      strcpy(blkfile, argv[2]);
   else
   {
      strcpy(defname, "/howard/btest/bin/blocks.dat");
      printf("\nEnter name of Blocks database file [%s]:\n", defname);
      gets(blkfile);
      if (!strlen(blkfile))
	 strcpy(blkfile, defname);
   }
   if ( (fblk=fopen(blkfile, "r")) == NULL)
      printf("\nCannot open blocks database %s\n", blkfile);
   else
   {
      printf("\n%d blocks processed\n", get_blk(dbs, fblk) );
      fclose(fblk);
   }
   blksplit = split_names(blkfile);

   /*------------------arg 3: Cobbler file name ----------------------*/
   fcob = NULL;
   if (argc > 3)
      strcpy(cobfile, argv[3]);
   else
   {
      /*  Look for file "cobbler.pros" in the blocks db directory  */
      cobfile[0] = '\0';
      strncat(cobfile, blkfile, blksplit->dir_len);
      cobfile[blksplit->dir_len] = '\0';
      strcat(cobfile, "cobbler.pros");
   }
   if ( (fcob = fopen(cobfile, "r")) != NULL)
   {
      printf("\nCOBBLER sequence:\n");
      get_fasta(fcob);
      fclose(fcob);
   }
   printf("end cobbler\n");

   /*------------------arg 4: map file name ----------------------*/
   fmap = NULL;
   if (argc > 4)
      strcpy(mapfile, argv[4]);
   else
   {
      /*  Look for file "maps.dat" in the blocks db directory  */
      mapfile[0] = '\0';
      strncat(mapfile, blkfile, blksplit->dir_len);
      mapfile[blksplit->dir_len] = '\0';
      strcat(mapfile, "maps.dat");
   }
   if( (fmap = fopen(mapfile, "r")) != NULL)
   {
      get_map(fmap);
      fclose(fmap);
   }
   printf("end map\n");

   /*------------------arg 5: tree file name ----------------------*/
   ftre = NULL;
   if (argc > 5)
      strcpy(treefile, argv[5]);
   else
   {
      /*  Look for file "trees.dat" in the blocks db directory  */
      treefile[0] = '\0';
      strncat(treefile, blkfile, blksplit->dir_len);
      treefile[blksplit->dir_len] = '\0';
      strcat(treefile, "trees.dat");
   }
   if( (ftre = fopen(treefile, "r")) != NULL)
   {
      get_fasta(ftre);
      fclose(ftre);
   }
   printf("end tree\n");

   /*------------------arg 6: proweb file name ----------------------*/
   fweb = NULL;
   if (argc > 6)
      strcpy(webfile, argv[6]);
   else
   {
      /*  Look for file "proweb.dat" in the blocks db directory  */
      webfile[0] = '\0';
      strncat(webfile, blkfile, blksplit->dir_len);
      webfile[blksplit->dir_len] = '\0';
      strcat(webfile, "proweb.dat");
   }
   if ( (fweb = fopen(webfile, "r")) != NULL)
   {
      get_proweb(fweb);
      fclose(fweb);
   }
   printf("end proweb\n");

   /*------------------arg 7: blinks file name ----------------------*/
   flnk = NULL;
   if (argc > 7)
      strcpy(lnkfile, argv[7]);
   else
   {
      /*  Look for file "blinks.dat" in the blocks db directory  */
      lnkfile[0] = '\0';
      strncat(lnkfile, blkfile, blksplit->dir_len);
      lnkfile[blksplit->dir_len] = '\0';
      strcat(lnkfile, "blinks.dat");
   }
   if ( (flnk = fopen(lnkfile, "r")) != NULL)
   {
      get_blinks(flnk);
      fclose(flnk);
   }
   printf("end blinks\n");

   /*------------------arg 8: blk2pdb file name ----------------------*/
   fpdb = NULL;
   if (argc > 8)
      strcpy(pdbfile, argv[8]);
   else
   {
      /*  Look for file "trees.dat" in the blocks db directory  */
      pdbfile[0] = '\0';
      strncat(pdbfile, blkfile, blksplit->dir_len);
      pdbfile[blksplit->dir_len] = '\0';
      strcat(pdbfile, "blk2pdb.dat");
   }
   if( (fpdb = fopen(pdbfile, "r")) != NULL)
   {
      get_pdb(fpdb);
      fclose(fpdb);
   }
   printf("end pdb\n");

   /*------------------arg 9: cyrca file name ----------------------*/
   fcyr = NULL;
   if (argc > 9)
      strcpy(cyrfile, argv[9]);
   else
   {
      /*  Look for file "trees.dat" in the blocks db directory  */
      cyrfile[0] = '\0';
      strncat(cyrfile, blkfile, blksplit->dir_len);
      cyrfile[blksplit->dir_len] = '\0';
      strcat(cyrfile, "cyrca.dat");
   }
   if( (fcyr = fopen(cyrfile, "r")) != NULL)
   {
      get_cyrca(fcyr);
      fclose(fcyr);
   }
   printf("end cyrca\n");

   /*------------------arg 10: Prosite directory name --------------------*/
   fdat = fdoc = NULL;
   prosite[0] = '\0';
   if (argc > 10)
      strcpy(prosite, argv[10]);
/*
   else
   {
      strcpy(defname, "/howard/btest/bin/");
      printf("\nEnter Prosite directory [%s]:\n", defname);
      gets(prosite);
      if (!strlen(prosite))
	 strcpy(prosite, defname);
   }
*/
   if (strlen(prosite))
   {
      if (prosite[strlen(prosite)-1] != '/') strcat(prosite, "/");
      strcat(prosite, "prosite"); plen = strlen(prosite);
      strcat(prosite,".dat");
      if ( (fdat=fopen(prosite, "r")) == NULL)
         printf("\nCannot open prosite.dat file %s\n", prosite);
      else
      {
         prosite[plen] = '\0';
         strcat(prosite, ".doc");
         if ( (fdoc=fopen(prosite, "r")) == NULL)
            printf("\nCannot open prosite.doc file %s\n", prosite);
         printf("\n");
         get_prosite(dbs, fdat, fdoc);
         fclose(fdat);
         if (fdoc != NULL) fclose(fdoc);
      }
   }

/*--------------------------------------------------------------------*/
   printf("\n");
   exit(0);
}  /*  end of main */

/*======================================================================*/
int get_blk(dbs, fblk)
struct db_info *dbs[];
FILE *fblk;
{
   int i, nblk, db, goodpat, done, acdone, found;
   char line[MAXLINE], id[MAXLINE], fam[MAXLINE], ctemp[MAXLINE], *ptr;

   nblk = 0;
   acdone = done = found = NO;
   line[0] = '\0';
   db = type_dbs(fblk, dbs);

   if (db >= 0 && db < MAXDB)
   {
      do
      {
	 if (strncmp(line, dbs[db]->start, strlen(dbs[db]->start)) == 0)
	 {
	    fam[0] = '\0';  goodpat = NO;
	    strcpy(id, line);   /*  save this line */
	    if (fgets(line, MAXLINE, fblk) != NULL &&
		   strncmp(line, "AC   ", 5) == 0)
	    {
		strcpy(ctemp, &line[dbs[db]->title_offset]);
                ptr = strtok(ctemp, "; \n\r\t");
                if (ptr != NULL) strcpy(fam, ptr);
                i = strlen(fam); acdone = NO;
		/*   Strip off the block number to get family name */
                if (strncmp(BlockFam, "Chrom", 5) != 0)
                {
                   while(!acdone && i >= MINAC)
                   {
                      if (isalpha(fam[i])) {fam[i] = '\0'; acdone = YES; }
                      else {i--;}
                   }
                }
                else  /* just truncate Chrom entries */
                {  fam[8] = '\0';  }
/*printf("BlockFam=%s, fam=%s\n", BlockFam, fam); */
		if ( (strcasecmp(BlockFam, fam)) == 0 )
		{
		     goodpat = found = YES; nblk++;
		     printf("%s", id);      /* ID */
		     printf("%s", line);    /* AC */
		}
                else if (found == YES) done=YES;
		while(fgets(line, MAXLINE, fblk) != NULL &&
		     strncmp(line, dbs[db]->end, strlen(dbs[db]->end)) != 0 )
			if (goodpat) printf("%s", line);
		if (goodpat)
                {
		     printf("%s", line);   /*  //  */
                }
	     }   /*  now at end of AC */
	 }  /*  end of start of entry */
         else if (strlen(line) > 1 && strstr(line, "sparky") == NULL &&
                  strstr(line, "Steven") == NULL)
            printf("%s", line);
      }  while (!feof(fblk) && fgets(line, MAXLINE, fblk) != NULL && !done);
   }   /*  end of if db valid */
   printf("\n");

   return(nblk);
}  /* end of get_blk */

/*========================================================================
   proweb.dat entry:   PS00031 ! http: ... ! title
	One line per entry, don't assume it's sorted by AC
==========================================================================*/
void get_proweb(fweb)
FILE *fweb;
{
   char line[MAXLINE], *ptr;
   int nweb;

   nweb = 0;
   while(!feof(fweb) && fgets(line, MAXLINE, fweb) != NULL)
   {
      nweb++;
      if ( (strncasecmp(BlockFam, line, strlen(BlockFam) )) == 0 )
      {
/*         printf("%s", line); */
         ptr = strtok(line, "!"); 
         if (ptr != NULL) ptr = strtok(NULL, "\n\r");
         printf("%s\n", ptr);
      }
   }
}    /*  end of get_proweb */
/*========================================================================
  blinks.dat format:
	One line per entry, don't assume it's sorted by AC
==========================================================================*/
void get_blinks(flnk)
FILE *flnk;
{
   char line[MAXLINE];
   int nlnk;

   nlnk = 0;
   while(!feof(flnk) && fgets(line, MAXLINE, flnk) != NULL)
   {
      nlnk++;
      if ( (strncasecmp(BlockFam, line, strlen(BlockFam)) == 0 ) )
      {
         printf("%s", line); 
/*
         ptr = strtok(line, "!"); 
         if (ptr != NULL) ptr = strtok(NULL, "\n\r");
         printf("%s\n", ptr);
*/
      }
   }
}    /*  end of get_blinks */
/*========================================================================
	maps.dat format:

	#MAP# BL00011		or	>BL00011
	...
	//

==========================================================================*/
void get_map(fmap)
FILE *fmap;
{
   char line[MAXLINE];
   int nmap, done;

   nmap = 0;
   done = NO;
   while(!done && !feof(fmap) && fgets(line, MAXLINE, fmap) != NULL)
   {
      nmap++;
      /*   Just checking the number part of the name!    */
      if ( ( line[0] == '#' && 
             strncasecmp(BlockFam, line+6, strlen(BlockFam)) == 0 ) ||
           ( line[0] == '>' && 
             strncasecmp(BlockFam, line+1, strlen(BlockFam)) == 0 )    )
      {
         done = YES;
         do {
           printf("%s", line); 
           fgets(line, MAXLINE, fmap);
         } while (!feof(fmap) && line[0] != '#' && line[0] != '>');
      }
   }
}  /* end of get_map */

/*=====================================================================
    Use to get any fasta-style entry
=======================================================================*/
void get_fasta(fdat)
FILE *fdat;
{
   char line[MAXLINE];
   int  done;

   done = NO;
   while(!done && !feof(fdat) && fgets(line, MAXLINE, fdat) != NULL)
   {
      if ( line[0] == '>' && 
           strncasecmp(BlockFam, line+1, strlen(BlockFam)) == 0 )
      {
         done = YES;
         do {
           printf("%s", line); 
           fgets(line, MAXLINE, fdat);
         } while (!feof(fdat) && line[0] != '>');
      }
   }
}   /*  end of get_fasta  */

/*========================================================================
   blk2pdb.dat entry:  >BL00094 
			seqname	pdbs
==========================================================================*/
void get_pdb(fpdb)
FILE *fpdb;
{
   char line[MAXLINE];
   int npdb, done;

   npdb = 0;
   done = NO;
   while(!done && !feof(fpdb) && fgets(line, MAXLINE, fpdb) != NULL)
   {
      npdb++;
      if ( line[0] == '>' && 
           strncasecmp(BlockFam, line+1, strlen(BlockFam)) == 0 )
      {
         done = YES;
         do {
           printf("%s", line); 
           fgets(line, MAXLINE, fpdb);
         } while (!feof(fpdb) && line[0] != '>');
      }
   }
}  /* end of get_pdb */

/*========================================================================
   cyrca.dat entry:  BL00094 
==========================================================================*/
void get_cyrca(fcyr)
FILE *fcyr;
{
   char line[MAXLINE];
   int ncyr, done;

   ncyr = 0;
   done = NO;
   while(!done && !feof(fcyr) && fgets(line, MAXLINE, fcyr) != NULL)
   {
      ncyr++;
      if ( strncasecmp(BlockFam, line, strlen(BlockFam)) == 0 )
      {
         done = YES;
         printf("%s", line); 
      }
   }
}  /* end of get_cyrca */

/*======================================================================*/
void get_prosite(dbs, fdat, fdoc)
struct db_info *dbs[];
FILE *fdat, *fdoc;
{
   int  db, goodpat, done;
   char line[MAXLINE], id[MAXLINE], ac[MAXLINE];

   done = NO;
   line[0] = '\0';
   db = type_dbs(fdat, dbs);

   if (db >= 0 && db < MAXDB)
   {
      do
      {
	 if (strncmp(line, dbs[db]->start, strlen(dbs[db]->start)) == 0)
	 {
	    ac[0] = '\0';  goodpat = NO;
	    strcpy(id, line);   /*  save this line */
	    if (fgets(line, MAXLINE, fdat) != NULL &&
		   strncmp(line, "AC   ", 5) == 0)
	    {
		strcpy(ac, &line[dbs[db]->title_offset]); 
		ac[7] = '\0';
		if ( (strncmp(BlockFam+2, ac+2, 5)) == 0 )
		{
		     goodpat = YES;
		     printf("%s", id);      /* ID */
		     printf("%s", line);    /* AC */
		}
		while(fgets(line, MAXLINE, fdat) != NULL &&
		     strncmp(line, dbs[db]->end, strlen(dbs[db]->end)) != 0 )
			if (goodpat)
                        {
                            printf("%s", line);
                            if (fdoc != NULL && strncmp(line, "DO   ", 5)==0)
                               get_doc(fdoc, &line[dbs[db]->title_offset]);
                        }
		if (goodpat)
                {
		     printf("%s", line);   /*  //  */
                     done=YES;
                }
	     }   /*  now at end of AC */
	 }  /*  end of start of entry */
         else if (strlen(line) > 1) printf("%s", line);
      }  while (!feof(fdat) && fgets(line, MAXLINE, fdat) != NULL && !done);
   }   /*  end of if db valid */
   printf("\n");
}  /* end of get_prosite */
/*=======================================================================
     Documentation line starts with {PDOC00199} , ends with {END}
=========================================================================*/
void get_doc(fdoc, pdoc)
FILE *fdoc;
char *pdoc;
{
   int done;
   char line[MAXLINE];
   char ctemp[15];

   done=NO;
   if (strlen(pdoc) > 8) pdoc[9] = '\0';   /* PDOC????? */
   sprintf(ctemp, "{%s}", pdoc);
   while (!done && !feof(fdoc) && fgets(line, MAXLINE, fdoc) != NULL)
   {
      if (strncmp(ctemp, line, 11) == 0)
      {
         do
         {
            printf("%s", line);
         } while (!feof(fdoc) && fgets(line, MAXLINE, fdoc) != NULL &&
                  strncmp("{END}", line, 5) != 0);
         done=YES;
      }
   }
}   /*  end of get_doc */
