/***************************************
*                                      *
*   Copyright (c) 1998 Jean-Eric Pin   *
*   All rights reserved.               *
*                                      *
*   TAB = 2 spaces                     *
*                                      *
***************************************/

/*-------------------------------------------------------------------
 * Mots.c    Jean-Eric Pin 31/03/97
 *-------------------------------------------------------------------
 */     

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include "FichierUnix.h"
#include "Globales.h"
#include "Main.h"
#include "Memoire.h"
#include "Mots.h"
#include "Utilitaires.h"
#if SYSTEME == MAC
  #include <unix.h>
#endif

extern unsigned short NbEtats, NbLettres, Longueur;
extern short TailleElement;
extern element *Generateurs, *TableDesValeurs;
extern unsigned long TailleTableDeHachage, TailleTableDeHachageMoinsUn; 
extern numero TailleMaxi;
extern char **Messages;

/************************************************************************
*                     
* EstEgalMots : Teste l'egalite  de deux  mots   
*                    
************************************************************************/

short EstEgalMots(element ex, element ey)
{
  Mot x, y;
  
  x = (Mot)ex;
  y = (Mot)ey;
  for (; *x == *y; x++, y++)
    ;
  return(x == NULL);    
}
  
/************************************
*  
*  ConcateneMots  
*  
************************************/

void ConcateneMots(Mot x, Mot y, Mot xy)
{
  while ((*xy++ = *x++))
    ;
  xy--;
  while ((*xy++ = *y++))
    ;
}

/************************************
*  
*  ProduitMots  
*  
************************************/

void ProduitMots(element ex, element ey, element exy)
{
  Mot x, y, xy;
  
  x = (Mot)ex;
  y = (Mot)ey;
  xy = (Mot)exy;
  while ((*xy++ = *x++))
    ;
  xy--;
  while ((*xy++ = *y++))
    ;
}

/************************************************************
*      
* HachageMots. 
*      
************************************************************/

unsigned long HachageMots(element ex)
{
  register unsigned long h;
  Mot x;
  
  h = 0;
  x = (Mot)ex;
  for (; x != NULL; x++)
    h = (h * NbLettres + *x) % TailleTableDeHachage;
  return(h);
}

/************************************************************
*      
* HachageSecondaireMots. 
*      
************************************************************/

unsigned long HachageSecondaireMots(element ex)
{
  register unsigned long h;
  Mot x;
  
  h = 0;
  x = (Mot)ex;
  for (; x != NULL; x++)
    h = (h * NbLettres + *x) % TailleTableDeHachageMoinsUn;
  return(1+h);  /* Il faut eviter la valeur 0 ! */
}

/********************************************************
*            
* FaireIdentiteMots : Initialisation de l'identite  
*            
********************************************************/

void FaireIdentiteMots(element x)
{
  x = NULL;  
}
  
/****************************************************
*
* SauvegardeMots. OK
*
****************************************************/

void SauvegardeMots(FILE *fichier)
{
  short q;
  lettre a;

  fprintf(fichier, "%8d %% Nombre d'etats\n", NbEtats);
  for (a = 0; a < NbLettres; a++)
  {
    for (q = 1; q <= NbEtats; q++)
      fprintf(fichier, "%d ", ((Mot)Generateurs[a])[q]);
    fprintf(fichier, "\n");
  }
}

/****************************************************
*
* LectureMots. OK
*
****************************************************/

void LectureMots(FILE *fichier)
{
  short q;
  lettre a;
  
  if (fscanf(fichier, "%hd %% Nombre d'etats", &NbEtats) != 1)
  {
    printf("scanf error\n");
    exit(1);
  }
  AlloueMemoireGenerateurs();
  for (a = 0; a < NbLettres; a++)
  {
    for (q = 1; q <= NbEtats; q++)
      if (fscanf(fichier, "%c", &((Mot)Generateurs[a])[q]) != 1)
      {
        printf("scanf error\n");
        exit(1);
      }
  }
}

/****************************************************
*
* EntreeMots. OK
*
****************************************************/

void EntreeMots(void)
{
  short q, n;
  lettre a;

  printf("%s ", Messages[M_Number_of_states]);    /* Nombre d'etats de l'automate ? */
  if (scanf("%hd", &NbEtats) != 1)
  {
    printf("scanf error\n");
    exit(1);
  }
  printf("\n");
  TailleElement = (1 + NbEtats) * sizeof(short);
  AlloueMemoireGenerateurs();
  for (a = 0; a < NbLettres; a++)
  {
    ((Mot)Generateurs[a])[0] = 0;
    for (q = 1; q <= NbEtats; q++)
    {
      do
      {
        printf("%d.%c = ",q, a + 97);
        if (scanf("%hd", &n) != 1)
        {
          printf("scanf error\n");
          exit(1);
        }
      }
      while (!((0 <= n) && (n <= NbEtats)));
      ((Mot)Generateurs[a])[q] = n;
    }
    printf("\n");
  }
}

/****************************************************
*
* SortieMots. Sortie d'un mot.
*
****************************************************/

void SortieMots(element ex)
{
  Mot x;

  x = (Mot)ex;
  if (NbLettres <= 26)
    for (; x != NULL; x++)
      printf("%c", *x + 'a');
}
    
/****************************************************
*
* AlloueMemoireEMot. OK
*
****************************************************/

/* element AlloueMemoireEMot(void)
{
  element Element;
  
  Element = (void *)ALLOC(lettre, 1 + Longueur); */    /* Un de plus, pour terminer par '\0' */
/*  if (Element == NULL)
  {
    printf("%s %s\n", Messages[M_Pb_memory], Messages[M_Pb_word]);  *//* Probleme lors de l'allocation memoire d'un mot */
/*    exit(1);
  }
  return(Element);
} */

/****************************************************
*
* LibereMemoireMots. OK
*
****************************************************/

/* void LibereMemoireEMot(element Element)
{
  free(Element);
} */