//**********************************************************************
//**********************************************************************
//	Projet      : Ulysse
//	Laboratoire : GREYC-ISMRA
//	Fichier     : loc.cc
//      Annee       : 1997          ,
//	Auteur      : Christophe GODEREAUX
//**********************************************************************
//**********************************************************************

#ifndef LOCCCC
#define LOCCCC


#include <iostream.h>
#include <strstream.h>
#include <fstream.h>
#include <stdio.h>
#include <string.h>
                      
#define NB_LOCUTION_MAX 200
#define LONGUEUR_LIGNE_MAX 1000
#define LONGUEUR_MOT_MAX 50

#define FINFIN "reuireprqw7437845jknre" // tres moche .
#include "util.cc"

char * lire_un_mot(const char *les_mots, char* entree)
{ 
    static char ligne[5000]="";
    static char *pligne=ligne;
    strcpy(entree,"");
//deb("entree");debn(entree);
//debn(ligne);
//debin(0);
//debn(pligne);
    if (strcmp(ligne,"")==0){
//debin(1);
      strcpy(ligne,les_mots); 
    }
//debin(2);
    if (strcmp(ligne,FINFIN)==0){
//debin(3);
        pligne=ligne;strcpy(ligne,"");return NULL;
    }
//debin(4);
//deb("entree");debn(entree);
    if (sscanf(pligne,"%s",entree)==-1 || strcmp(pligne,entree)==0){
	strcpy(ligne,FINFIN);
//deb("cas ou ");//debn(entree);
    }
    else {
//debin(5);
      pligne=strstr(pligne,entree);
      for(int i=0;entree[i] && (*pligne == entree[i++]);pligne++){
//debi(entree[i]);
//deb("ligne=");//deb(pligne);//debin(0); 
      }
//deb("fin");//debn(pligne);
      char tt[50];
      if (sscanf(pligne,"%s",tt)==-1) {
//debin(6);
	strcpy(ligne,FINFIN);
      }
    }
//debin(7);
  return entree;
}

class tablocution{
  char * tabloc[NB_LOCUTION_MAX];
  int nbloc;

  public:
    char *chemin;
    char *nom_fic;

    tablocution(){}
    tablocution(const char* f){this->init(".",f);}
    tablocution(const char* r,const char* f){this->init(r,f);}
    void init(const char*,const char*);
    int mots_debutent_locution(const char*,int&,int&);
    int mots_debutent_locution2(const char*,int&,int&);
    int recherche(const char*,int&,int&,int,int); //en fait retourne rien
    char * transfert(const char* ,char* );
};



void tablocution::init(const char * chemin0,const char* nomfichier0)
{  
  char mot[LONGUEUR_MOT_MAX];
  nbloc=0;
  char * nomfichier=new char [10+strlen(chemin0)+strlen(nomfichier0)];
  sprintf(nomfichier,"%s/%s",chemin0,nomfichier0);
  deb(nomfichier);deb(" : ");;
  ifstream fichier(nomfichier);
  if (!fichier.good()) {
    cerr<<"Tablocution init : Fichier "<<nomfichier<<" introuvable \n";
  }
  chemin=strdup(chemin0);
  nom_fic=strdup(nomfichier0);
  while (fichier.good()) {
    fichier.getline(mot,LONGUEUR_LIGNE_MAX);
//debi(nbloc);debn(mot);
    tabloc[nbloc++]=strdup(mot);
  }
  nbloc--;//je ne sais pas pourquoi la derniere ligne est lue 2 fois.
debi(nbloc);debn(" LOCUTIONS.");
  //delete(nomfichier);
}
   

int tablocution::mots_debutent_locution(const char* mots,int& loc_finale,int& loc_inclu_et_egal) 
{
  int longmots=strlen(mots);
  int i=0,nb=0;                   
  int egalite=0;
  
  do
  {  
//deb("a");
    if (strncmp(mots,tabloc[i],longmots) == 0){
//deb(tabloc[i]);
       nb++;
       egalite= egalite || (strlen(tabloc[i]) == longmots);
//debi(i);deb(" ");                                  
     } 
  } while (i++ < nbloc-1); 
//debn("c");
  loc_finale=(nb==1) && egalite;
  loc_inclu_et_egal=(nb>1) && egalite;
  return ((nb!=0) && !egalite);
}         
           
                    

int tablocution::mots_debutent_locution2(const char* mots,int& loc_finale,int& loc_inclu_et_egal) 
{
  int egalite=0;
  int nb=0;
  recherche(mots,egalite,nb,0,nbloc-1);
  loc_finale=(nb==1) && egalite;
  loc_inclu_et_egal=(nb>1) && egalite;
  return  ((nb!=0) && !egalite);
}         
           
                    

int tablocution::recherche(const char* mots,int& egalite,int& loc_inclu_et_egal,int g,int d) 
{
  int longmots=strlen(mots);
  int r;
//cout<<"g="<<g<<" d="<<d;cout.flush();
  if (d<g) return 0;
  else {
    r=(g+d)/2;
//cout<<" "<<(tabloc[r])<<" r="<<r<<'\n';
    if (strncmp(mots,tabloc[r],longmots) < 0)
      return recherche(mots,egalite,loc_inclu_et_egal,g,r-1);
    if (strncmp(mots,tabloc[r],longmots) > 0)
      return recherche(mots,egalite,loc_inclu_et_egal,r+1,d);
    if (strncmp(mots,tabloc[r],longmots) == 0){
      loc_inclu_et_egal++;
//cout<<" "<<(tabloc[r])<<" r="<<r<<'\n';
      if (strlen(tabloc[r]) != longmots)
        return recherche(mots,egalite,loc_inclu_et_egal,g,r-1);
      egalite=1;
      return recherche(mots,egalite,loc_inclu_et_egal,r+1,d);	
    }
  }
  return 0; // n'arrive jamais
}                    
                    

char * tablocution::transfert(const char* les_mots,char* sortie)
{
  char* buffer[30] ;
  int nb_mots_ds_buffer =0;
  int indice_buffer=0;
  int nb_ent=0;  
  int indice_ent=1;
  char entree[LONGUEUR_LIGNE_MAX];
  char valeur_ajoutee[LONGUEUR_LIGNE_MAX];
  char *mots = NULL;
  int loc_finale=0;
  int loc_inclus_et_egal=0;

do {
  mots = NULL;
  loc_finale=0;
  loc_inclus_et_egal=0;
  if (nb_mots_ds_buffer != 0) {
      nb_ent=nb_mots_ds_buffer; indice_ent=1;
      nb_mots_ds_buffer=0; indice_buffer=0;
  }
  do{
    do{
      if (nb_ent == 0){
	if (!lire_un_mot(les_mots,entree)){
//deb("nb_mots_ds_buffer =");debin(nb_mots_ds_buffer);
//deb("loc_inclus_et_egal =");debin(loc_inclus_et_egal);
//deb("loc_finale =");debin(loc_finale);
          for(int rr=0;rr<nb_mots_ds_buffer;rr++){
            strcat(sortie," ");
//deb("buffer[");debi(rr);debn( buffer[rr]);
            strcat(sortie,buffer[rr]);
	  }
	  //cout<<"entree="<<les_mots;
	  //cout<<"sortie="<<sortie<<'\n';
	  return sortie;
        }
        if (entree[strlen(entree)-1]=='.'){
          strncpy(entree,entree,strlen(entree)-1);
          entree[strlen(entree)-1]='\0';
        }
      } 
      else {
//deb("nb_ent=");debi(nb_ent);
         strcpy(entree,buffer[indice_ent++]);
         nb_ent--;
      }
      buffer[indice_buffer++]=strdup(entree);    
      nb_mots_ds_buffer++;
//deb("2");
      if (mots==NULL)
          mots=strdup(entree); 
      else { 
         sprintf(valeur_ajoutee,"%s_%s",mots,entree);
         mots=&valeur_ajoutee[0];
      }      
//deb("les mots sont :");debn(mots);
    } while (mots_debutent_locution(mots,loc_finale,
             loc_inclus_et_egal));    
    if ( loc_inclus_et_egal !=0 ){
       nb_mots_ds_buffer=1; indice_buffer=1;
       buffer[0]=strdup(mots);
//deb("une loc inclue et egale :");debn(buffer[0]);
    }
  } while ( loc_inclus_et_egal != 0 );

  if ( loc_finale !=0 ) {
     nb_mots_ds_buffer=0; indice_buffer=0;
     strcat(sortie," ");
     strcat(sortie,mots);
//deb("locution : ");
//     cout<<mots<<" ";cout.flush();

  }
  else {
     nb_mots_ds_buffer--; indice_buffer=0;
     strcat(sortie," ");
     strcat(sortie,buffer[0]);
  }            
}while (TRUE);                
  return sortie;
}




#endif
