/***********************************************************************
*
* Projet   : DilibPro
* Module   : Index
* Fichier  : IndexFast.c
* Auteur   : Ducloy
* Date     : 12/96
*
*************************************************************************/
#include "Index.h"
#include "IndexFast.h"
#include <stdio.h>
#include <stdlib.h>

IndexFl *IndexFlCreate(char *str,
		       int n,
		       int sizeKey,
		       int sizeElem)
{
  IndexFl *newIndexFl;
  newIndexFl=(IndexFl *)malloc(sizeof(IndexFl));
  newIndexFl->str=str;
  newIndexFl->nElem=n;
  newIndexFl->sizeElem=sizeElem;
  newIndexFl->sizeKey=sizeKey;
  return newIndexFl;
}

IndexFl *IndexFlCreateFromIndexFl(IndexFl *s1)
{
  IndexFl *newIndexFl;

  newIndexFl=(IndexFl *)malloc(sizeof(IndexFl));
     IndexFlCopy(newIndexFl,s1);
     return newIndexFl;
}

void IndexFlEdit(IndexFl *s1)
{
   printf("n=%d sK=%d sE=%d\n",s1->nElem, s1->sizeKey, s1->sizeElem);
     printf("str=%s\n",s1->str);
}

int IndexFlInternalAssocCount(IndexFl *s1, IndexFl *s2)
{
  int valCmp;
  if (s1->nElem<=0)return 0;
  if (s2->nElem<=0)return 0;
  if ((valCmp=IndexFlCarCmp(s1,s2))==0) 
    return 
      (IndexFlInternalAssocCount
       (IndexFlCdr(s1),IndexFlCdr(s2))
       +1);
  
  if (valCmp>0)
       return IndexFlInternalAssocCount(s1, IndexFlCdr(s2));
  else return IndexFlInternalAssocCount(IndexFlCdr(s1), s2);
}

/*                IndexFast               */

void IndexFastFree(IndexFast *i1)
{
  free(i1->listElem);
  free(i1);
}

/**
   Creates an @ref IndexFast from a line of an index file.

   @param s1 String to translate into an @ref IndexFast. @a s1 is a
	     line from an index file.

   @return an IndexFast built from @a s1
 */
IndexFast *IndexFastFromString(char *s1)
{
  IndexFast *newIndex;
  char *pointeur;
  char *debutListe;
  int sizeMark;
  int sizeRef;

  newIndex=(IndexFast *)malloc(sizeof(IndexFast));
  newIndex->buffer=s1;
  if(! (pointeur=strchr(s1,'<')))return NULL;
         /* -> <idx><xx(kw)>... */
 
  if(! (pointeur=strchr(pointeur,'>'))) return NULL;
         /* -> ><xx(kw)>... */
  newIndex->keyZone=pointeur+1;

  while((pointeur=strchr(pointeur,'<')))
    {
       pointeur++;
       if (strncmp(pointeur,"f>",2)==0)
	 { 
	   newIndex->endKeyZone=pointeur-1;
	   pointeur+=2;    /* -> 99..9</f> */
	   sscanf(pointeur, "%d", &(newIndex->f));
	   if (!(pointeur=strchr(pointeur,'<'))) return NULL;
           pointeur+=4;
	   /* -> <l><e> */
           if (!(pointeur=strchr(pointeur,'>'))) return NULL;
           /* -> ><e>... */
           pointeur++;
           /*  -> <e>... */
           if (!(debutListe=strchr(pointeur,'>'))) return NULL;
           debutListe++;
           sizeMark=debutListe-pointeur;
           if (!(pointeur=strchr(debutListe,'<'))) return NULL;
           sizeRef=pointeur-debutListe;
           newIndex->listElem=IndexFlCreate
              (debutListe
               ,newIndex->f
               ,sizeRef
               ,sizeRef+2*sizeMark+1);
	   return newIndex;
	 }
	     
     }
  return NULL;
}

void IndexFastPrintKeyZone(IndexFast *i1)
{
     i1->endKeyZone[0]='\0';
     printf ("%s", i1->keyZone);
     i1->endKeyZone[0]='<';
}

void IndexFastEdit(IndexFast *i1)
{
  printf ("record =%s\n", i1->buffer);
  printf ("key    =");
  IndexFastPrintKeyZone(i1);
  printf ("\n");
  printf ("f      =%d\n", i1->f);
  IndexFlEdit (i1->listElem);
}

/**
   
 */
IndexFast *IndexFastRead(Index *i1, char *k1)
{
  DamRecord *rec;
  IndexFast *newIndex;
  char *firstKeyBloc;
  char *hfdKeyBloc;
  char *recPath;
  if ((firstKeyBloc=StrSearchKeyLessEqual(i1->hidTable, k1)))
    {
      hfdKeyBloc=StrSearchValue(i1->hidTable);
      recPath=DamHfdGetPath(i1->hfd,hfdKeyBloc);
      if (DamHfdOpenPathCont(i1->hfd,recPath,i1->tagKey))
	{
	  rec=DamFileGetRecordCont(i1->hfd->damFile,k1);
	  newIndex=IndexFastFromString(rec->first->next->effectiveBeginField);
	  return newIndex;
	}
    }
  return NULL;
}
