/*========================================================================
   (C) Copyright 1995-2007 by Fred Hutchinson Cancer Research Center
	  lislis.c  Compares two .lis files
--------------------------------------------------------------------------
8/1/95  Modified to write a .lis file of sequences in 
        2nd but not in 1st file
1/3/06  Compare new Trembl names : Q9WUM8_MOUSE|Q9WUM8
2/14/07 Compare new Trembl names: P15143|P02F2_HUMAN == P02F2_HUMAN|P15143
=========================================================================*/
#include "motifj.h"
#include <sys/types.h>
/*
#include <sys/dir.h>
*/
#include <sys/time.h>


struct db_id *make_list();
void compare_lists();
int compare_names();

/*--------------  Routines from motmisc.obj --------------------------*/
int get_ids();
struct db_id *makedbid();

char Pros[FNAMELEN];

/*======================================================================*/
void main(argc, argv)
int argc;
char *argv[];
{
   char lisfile[FNAMELEN], lis2file[FNAMELEN];
   struct db_id *ids, *ids2;
   FILE *flis, *flis2;

   printf("\nLISLIS: (C) Copyright 1995-2007 by Fred Hutchinson Cancer");
   printf(" Research Center\n");
/*-------------  arg 1.  First .lis file ---------------------*/
   if (argc > 1)
      strcpy(lisfile, argv[1]);
   else
   {
      printf("\nEnter name of file containing first list of sequences: ");
      gets(lisfile);
   }
   if ( (flis=fopen(lisfile, "r")) == NULL)
   {
      printf("\nCannot open file %s\n", lisfile);
      exit(-1);
   }
   printf("Reading %s ... ", lisfile);
   ids = make_list(flis);

/*-------------  arg  2.  Second .lis file ---------------------*/
   if (argc > 2)
      strcpy(lis2file, argv[2]);
   else
   {
      printf("\nEnter name of file containing second list of sequences: ");
      gets(lis2file);
   }
   if ( (flis2=fopen(lis2file, "r")) == NULL)
   {
      printf("\nCannot open file %s\n", lis2file);
      exit(-1);
   }
   printf("Reading %s ... ", lis2file);
   ids2 = make_list(flis2);

   compare_lists(ids, ids2);

   exit(0);
}  /*  end of main */
/*====================================================================*/
struct db_id *make_list(flis)
FILE *flis;
{
   char title[MAXLINE], stemp[MAXLINE], *ptr;
   int nids;
   struct db_id *ids;

   ids = makedbid();
   nids = get_ids(flis, ids);
   fclose(flis);
   printf("%d sequences read\n", nids);
   return(ids);

}  /*  end of make_list */

/*======================================================================*/
void compare_lists(ids1, ids2)
struct db_id *ids1, *ids2;
{
   struct db_id *id1, *id2;
   int tot1, tot2, n1, n2;
   double per1, per2;

   id2 = ids2->next;
   while (id2 != NULL)
   {
      id1 = ids1->next;
      while (id1 != NULL && !id2->found)
      {
/*        if (strcmp(id1->entry, id2->entry) == 0)
*/
         if (compare_names(id1->entry, id2->entry) == 1)
         {   id2->found = 1; id1->found = 2;    }
         id1 = id1->next;
      }
      id2 = id2->next;
   }

   printf("Sequences in first list but not in second list:\n");
   n1 = tot1 = 0;
   id1 = ids1->next;
   while (id1 != NULL)
   {
      tot1++;
      if (!id1->found)
      { printf("%s\n", id1->entry); n1++; }
      id1 = id1->next;
   }
   per1 = 100.0 * (double) n1 / (double) tot1;
   printf("%d/%d sequences (%.2f) in first list but not in second list:\n", 
           n1, tot1, per1);

   printf("Sequences in second list but not in first list:\n");
   n2 = tot2 = 0;
   id2 = ids2->next;
   while (id2 != NULL)
   {
      tot2++;
      if (!id2->found)
      { printf("%s\n", id2->entry); n2++;  }
      id2 = id2->next;
   }
   per2 = 100.0 * (double) n2 / (double) tot2;
   printf("%d/%d sequences (%.2f) in second list but not in first list:\n", 
          n2, tot2, per2);

   printf("\n");
}  /* end of compare_lists */
/*======================================================================
	Compare two multi-part sequence names and return flag if
	any one of them matches
=======================================================================*/
int compare_names(name1, name2)
char *name1, *name2;
{
   int match, n2, i;
   char *ptr1, *ptr2, parts[10][12], ctemp1[120], ctemp2[120];

   match = 0;
  
   /* strtok modified the strings */
   strcpy(ctemp1, name1);
   strcpy(ctemp2, name2);

   /*  strtok only tracks one string at a time, so pre-process name2 */
   /*  max of 10 name parts, 12 chars in length each */
   n2 = 0;
   ptr2 = strtok(ctemp2, "|");
   while (ptr2 != NULL)
   {
      strcpy(parts[n2], ptr2);
      n2++;
      ptr2 = strtok(NULL, "|");
   }

   ptr1 = strtok(ctemp1, "|");
   while (ptr1 != NULL)
   { 
      for (i=0; i<n2; i++)
      {
         if (strcmp(ptr1, parts[i]) == 0) { match = 1; }
         else   /* match Q99XR5 and Q99XR5_STRP1, etc.  */
         {
            /* 1st 6 chars match; 7th char of one is '_'; other is 6 chars  */
            if ((strncmp(ptr1, parts[i], 6) == 0) &&
                ((strlen(ptr1) == 6 && strcspn(parts[i],"_") == 6) ||
                 (strlen(parts[i]) == 6 && strcspn(ptr1,"_") == 6) )) 
            {  match = 1; }
         }
      }
      ptr1 = strtok(NULL, "|");
   }

   /*	Use the longer name if they match */
   if (match==1 && strlen(name1) > strlen(name2))
   {   strcpy(name2, name1);  }
   
   return(match);

}  /* end of compare_names */
