/*
# proc: lookup_levenstein - given a word string, mfs structure of words or
# proc:                     phrases, determines which mfs entry is the best
# proc:                     match to the word using the Lenenstein Distance.
# proc: init_align_params - initializes the parameter structure controlling the
# proc:                     Levenstein Distance algorithm.
*/

#include <stdio.h>
#include <mfs.h>
#include <align.h>

#define DEF_SUB_PENALTY 1
#define DEF_DEL_PENALTY 1
#define DEF_INS_PENALTY 1

/*******************************************************************/
lookup_levenstein(word, phrases, winner, conf, alignment, alen)
char *word;
MFS *phrases;
int *winner, **alignment, *alen;
float *conf;
{
   int i, distance, talen, mindist, min_i;
   struct align_params_t a;
   int *talign;

   init_align_params(&a, 1, DEF_SUB_PENALTY, DEF_DEL_PENALTY, DEF_INS_PENALTY);
   talign = (int *)calloc(strlen(word)+MAXMFSLENGTH, sizeof(int));
   if(talign == NULL)
      syserr("lookup_levenstein", "calloc", "talign");

   (*alignment) = (int *)calloc(strlen(word)+MAXMFSLENGTH, sizeof(int));
   if((*alignment) == NULL)
      syserr("lookup_levenstein", "calloc", "alignment");

   mindist = ldv( word, phrases->values[0], &a, NULL, &talen, talign );
   min_i = 0;
   memcpy((*alignment), talign, talen * sizeof(int));
   (*alen) = talen;
   for(i = 1; i < phrases->num; i++){
      distance = ldv( word, phrases->values[i], &a, NULL, &talen, talign );
      if(distance < mindist){
         mindist = distance;
         min_i = i;
         memcpy((*alignment), talign, talen * sizeof(int));
         (*alen) = talen;
      }
   }
   free(a.subv);
   free(talign);
   *winner = min_i;
}

/*******************************************************************/
init_align_params(a, case_flag, sub_penalty, del_penalty, ins_penalty)
struct align_params_t *a;
int case_flag, sub_penalty, del_penalty, ins_penalty;
{
   int i, j;

   a->case_sensitive = case_flag;
   a->subv = (int *)calloc( 256 * 256, sizeof(int) );
   if(a->subv == NULL)
      syserr("init_align_params", "calloc", "a->subv");
   for ( i=0; i<256; i++ ) {
      a->delv[i] = del_penalty;
      a->insv[i] = ins_penalty;
      for ( j=0; j<256; j++ )
         a->subv[i*256+j] = sub_penalty;
   }
}
