/***********************************************************************
*
* Projet   : DilibDam
* Module   : Assoc
* Fichier  : AssocFastWithIndex.c
* Auteur   : Ducloy
* Date     : 11/96
* $Id: AssocFastWithIndex.c,v 1.6 2004/01/22 17:10:04 parmentf Exp $
*
***********************************************************************/
/**
   @file

   @brief AssocFastWithIndex command

   @section AssocFastWithIndexSYNOPSIS SYNOPSIS

   @code
AssocFastWithIndex -h indexHfd [-i iTerm -j jTerm]
   @endcode

   @section AssocFastWithIndexDESCRIPTION DESCRIPTION

   This command (@p AssocFastWithIndex) is an association operator,
   between two terms of an @p indexHfd, @p iTerm and @p jTerm (or on
   standard input).

   @section AssocFastWithIndexOPTIONS OPTIONS
   
   @p -h gives the name of the @p indexHfd to use (without @p .hfd).

   @p -i gives one of the two terms to associate (optional, -j required)

   @p -j gives the second of the terms to associate (optional, -i required)


   @section AssocFastWithIndexEXAMPLES EXAMPLES

   To see how many times @p humour and @p indien co-occur in the BD
   database ($DILIB/Sample/BasicIrs/MiniBib/):

   @code
AssocFastWithIndex -h bd.mcl.i -i humour -j indien
   @endcode

   will return, in the BD 

   @code
<assoc><ti><kw>indien</kw><f>2</f></ti><tj><kw>humour</kw><f>2</f></tj><fij>0</fij></assoc>
   @endcode

   Or, using the standard input (with a tabulation between @p indien
   and @p humour):

   @code
AssocFastWithIndex -h bd.mcl.i
indien <TAB> humour
<assoc><ti><kw>indien</kw><f>2</f></ti><tj><kw>humour</kw><f>2</f></tj><fij>0</fij></assoc>
   @endcode

   @see AssocWithIndex

   @author &copy; INIST-CNRS
   @author Jacques DUCLOY
           <DilibMaster@inist.fr>
   @since  November 1996
   @return 0 if OK
   @return 1 otherwise.

*/

#include <stdio.h>  /* perror */
#include <stdlib.h> /* getopt */
#include <unistd.h> /* getopt */
#include "IndexFast.h"
#include "Index.h"
#include "Buffer.h"

/* void perror();*/

/**
   Prints the usage of the AssocFastWithIndex command.
 */
void usage()
{
  perror ("usage: AssocFastWithIndex -h hfdName [-i term1 -j term2]\n");
  exit(1);
}
Index  *hfd1; /**< Index of the first Hfd to associate */
Index  *hfd2; /**< Index of the second Hfd to associate */

/**
   Builds the association between the terms @a s1 and @a s2,
   respectively in @a hfd1 and @a hfd2.

   @param s1 first term of the association
   @param s2 second term of the association
 */
void buildAssoc(char *s1, char *s2)
{
  SgmlNode *n3;
  IndexFast *n1;
  IndexFast *n2;
  SgmlNode *t1;
  SgmlNode *t2;
  char bufNum[20];

  n3=SgmlCreateMark("assoc");
  if((n1=IndexFastRead(hfd1,s1)))
    {	
      if((n2=IndexFastRead(hfd2,s2)))
	{
	  SgmlAddSon(n3,t1=SgmlCreateMark("ti"));
	  SgmlAddSon(n3,t2=SgmlCreateMark("tj"));
	  SgmlAddSon(t1, SgmlCreateLeaf("kw",s1));
	  SgmlAddSon(t2, SgmlCreateLeaf("kw",s2));
	  sprintf(bufNum,"%d", n1->f);
          SgmlAddLast(t1, SgmlCreateLeaf("f",bufNum));
	  sprintf(bufNum,"%d", n2->f);
          SgmlAddLast(t2, SgmlCreateLeaf("f",bufNum));
	  sprintf(bufNum,"%d", IndexFastAssocCount(n1,n2));
          SgmlAddLast(n3,SgmlCreateLeaf("fij",bufNum));
	  SgmlPrint(n3);putchar('\n');
	  IndexFastFree(n2);
          
	}
      IndexFastFree(n1);
    }
  SgmlFree(n3);
}

/*    int getopt();*/
/**
   Main function of AssocFastWithIndex

   @warning this command associates a term from an index with another
   term from the same index Hfd.

   @see @ref AssocFastWithIndexSYNOPSIS
 */
int main(int argc, char **argv)
{
  extern char *optarg; /* for getopt() */

  int     cod_arg;
  int     flagHfd = 0;
  int    flagInput;
  char   *motI;
  char   *motJ;
  Buffer *buf1;
  char *line1;

  flagInput=1;

  while ((cod_arg = getopt(argc,argv,"h:i:j:nL"))!=EOF)
    {switch(cod_arg)
      {
      case 'h':
	if((hfd1=IndexOpenRead(optarg)))
	  {
	    hfd2=IndexOpenRead(optarg);
	    flagHfd=1;
	    break;
	  }
	else
	  {
	    perror("HFD not found\n");
	    usage();
	  }
	break;
      case 'n':
	flagInput=0;
	break;
      case 'i':
	motI=optarg;
	break;
      case 'j':
	if(!flagHfd) usage();
	motJ=optarg;
	buildAssoc(motI,motJ);
	break;
      default: usage();
	break;
      }
    }
  if(!flagHfd) usage();
  if (flagInput==1)
    {
      buf1=BufferCreate(132,132);
      while((line1=BufferGets(buf1)))
	{
	  char *line2;
	  char *endPair;
	  if ((line2 = strchr(line1,'\t')))
	    {
	      line2[0]='\0';
	      line2++;
	      if((endPair=strpbrk(line2,"\t\n"))) endPair[0]='\0';
	      buildAssoc(line1,line2);
	    }
	}
    }
  return 0;
}
