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

/*-------------------------------------------------------------------
 * 
 * FichierUnix.c  OK
 *
 *-------------------------------------------------------------------
 */ 

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include "Erreurs.h"
#include "Main.h"
#include "Espace.h"
#include "FichierUnix.h"
#include "Globales.h"
#include "Initialisation.h"
#include "Memoire.h"
#include "Utilitaires.h"
#if  SYSTEME == MAC
  #include <unix.h>
#endif

extern float Version;
extern unsigned long TailleMaxi, NbElements;
extern unsigned short NbLettres, TypeCalcul, TypeSemigroupe, SemigroupeRenverse, EtatInitial1,
                      InitiauxDejaSpecifies, FinauxDejaSpecifies, PartiePointee, MemoireAllouee;
extern unsigned long TailleTableDeHachage, TailleTableDeHachageMoinsUn, SortieLaTeX;
extern char **Messages; 
extern char DirExemples[255];
extern char DirLaTeX[255];
extern char NomFichier[255];
extern char NomFichierLaTeX[255];
extern Sauvegarde_ Sauvegarde;
extern Lecture_ LectureFichier;

/**************************************************
*
* ChoixNomFichier      
*
**************************************************/

void ChoixNomFichier()
{  
  char Nom[LONGUEUR_NOM];
  int erreur;

  printf("%s ", Messages[M_Give_name_file]);    /* printf("Donnez le nom du fichier : ");  */
  if (scanf("%s", Nom) == EOF)
  {
    erreur = errno;
    Erreur_scanf(erreur);
    printf("scanf error\n");
    exit(1);
  }
  strcpy(NomFichier, DirExemples);
  strcat(NomFichier, Nom);
  if (SortieLaTeX)
  {
    strcpy(NomFichierLaTeX, DirLaTeX);
    strcat(NomFichierLaTeX, Nom);    
    strcat(NomFichierLaTeX, ".tex");
  }
}

/**************************************************
*
* ChoixNomLaTeX      
*
**************************************************/

void ChoixNomLaTeX()
{  
  char NomLaTeX[LONGUEUR_NOM];
  int erreur;

  printf("%s ", Messages[M_Give_name_LaTeXfile]);    /* printf("Donnez le nom du fichier : ");  */
  if (scanf("%s", NomLaTeX) == EOF)
  {
    erreur = errno;
    Erreur_scanf(erreur);
    printf("scanf error: NomLaTeX\n");
    exit(1);
  }
  strcpy(NomFichierLaTeX, DirLaTeX);
  strcat(NomFichierLaTeX, NomLaTeX);    
  strcat(NomFichierLaTeX, ".tex");
}

/**************************************************
*
* Ouverture : Ouverture d'un fichier par fopen.      
*
**************************************************/

FILE *Ouverture(const char *Nom, const char *mode)
{  
  FILE *fichier;      /* Fichiers KR p.158 */
  int erreur;

  fichier = fopen(Nom, mode);
  if (fichier == 0)
  {
    erreur = errno;
    Erreur_fopen(erreur);
    printf("%s %s !\n", Messages[M_Pb_opening], Nom);    /* printf("Probleme a la creation de %s !\n", nom);  */
    return 0;
  }
  return(fichier);
}

/**************************************************
*
* Fermeture : Fermeture d'un fichier par fclose.      
*
**************************************************/

void Fermeture(FILE *fichier)
{
  int erreur;
  int retour = fclose(fichier);
  
  if (retour != 0)
  {
    erreur = errno;
    Erreur_fclose(erreur);
    printf("%s\n", Messages[M_Pb_closure]);    /* printf("Probleme a la fermeture d'un fichier !\n");  */
  }
}

/************************************
*
* DialogueSauvegardeFichier.      
*
************************************/

void DialogueSauvegardeFichier()
{
  FILE *fichier;      /* Fichiers KR p.158 */

  do
  {
    ChoixNomFichier();
    fichier = Ouverture(NomFichier, "w");
  }
  while (!fichier);
  EnTeteFichier(fichier);
  Sauvegarde(fichier);
  Fermeture(fichier);
}

/************************************
*
* EnTeteFichier.      
*
************************************/

void EnTeteFichier(FILE *fichier)
{
  int erreur;

  while (!fichier);
  if (fprintf(fichier, "%8f %% Version de Semigroupe\n", Version) < 0)
  {
    erreur = errno;
    printf("fprintf %8f %% Version de Semigroupe failed!\n", Version);
    Erreur_printf(erreur);
    return;
  }  
  if (fprintf(fichier, "%8lu %% Taille maximum\n", TailleMaxi) < 0)
  {
    erreur = errno;
    printf("fprintf %8lu %% Taille maximum failed!\n", TailleMaxi);
    Erreur_printf(erreur);
    return;
  }  
  if (fprintf(fichier, "%8d %% Type de calcul\n", TypeCalcul) < 0)
  {
    erreur = errno;
    printf("fprintf %8d %% Type de calcul failed!\n", TypeCalcul);
    Erreur_printf(erreur);
    return;
  }  
  if (fprintf(fichier, "%8d %% Type de semigroupe\n", TypeSemigroupe) < 0)
  {
    erreur = errno;
    printf("fprintf %8d %% Type de semigroupe failed!\n", TypeSemigroupe);
    Erreur_printf(erreur);
    return;
  }  
  if (fprintf(fichier, "%8d %% Partie pointee ?\n", PartiePointee) < 0)
  {
    erreur = errno;
    printf("fprintf %8d %% Partie pointee ? failed!\n", PartiePointee);
    Erreur_printf(erreur);
    return;
  }  
  if (PartiePointee)
  {
    if (fprintf(fichier, "%8d %% Initiaux specifies\n", InitiauxDejaSpecifies) < 0)
    {
      erreur = errno;
      printf("fprintf %8d %% Initiaux specifies failed!\n", InitiauxDejaSpecifies);
      Erreur_printf(erreur);
      return;
    }  
    if (fprintf(fichier, "%8d %% Finaux specifies\n", FinauxDejaSpecifies)< 0)
    {
      erreur = errno;
      printf("fprintf %8d %% Finaux specifies failed!\n", FinauxDejaSpecifies);
      Erreur_printf(erreur);
      return;
    }  
  }
  if (fprintf(fichier, "%8d %% Semigroupe renverse ?\n", SemigroupeRenverse) < 0)
  {
    erreur = errno;
    printf("fprintf %8d %% Semigroupe renverse failed!\n", SemigroupeRenverse);
    Erreur_printf(erreur);
    return;
  }  
  if (fprintf(fichier, "%8d %% Nombre de generateurs\n", NbLettres) < 0)
  {
    erreur = errno;
    printf("fprintf %8d %% Nombre de generateurs failed!\n", NbLettres);
    Erreur_printf(erreur);
    return;
  }  
}

/************************************
*
* EnTeteFichierLaTeX.      
*
************************************/

void EnTeteFichierLaTeX(FILE *fichier)
{
  int erreur;

  while (!fichier);
  if (fprintf(fichier, "\\documentclass[]{article}\n\n\\usepackage[]{amsmath, amssymb, tabularx}\n\n") < 0)
  {
    erreur = errno;
    printf("Error: writing on LaTeX file \n");
    Erreur_printf(erreur);
    return;
  }  
  if (fprintf(fichier, "\\include{MacrosJEP}\n\n\\begin{document}\n\n\\title{Example computed by Semigroupe}\n") < 0)
  {
    erreur = errno;
    printf("Error: writing on LaTeX file \n");
    Erreur_printf(erreur);
    return;
  }  
  if (fprintf(fichier, "\\author{a C programme written by Jean-Eric Pin}\n\\date{\\today}\n\\maketitle\n\n") < 0)
  {
    erreur = errno;
    printf("Error: writing on LaTeX file \n");
    Erreur_printf(erreur);
    return;
  }  
}

/************************************
*
* FinFichierLaTeX.      
*
************************************/

void FinFichierLaTeX(FILE *fichier)
{
  int erreur;

  while (!fichier);
  if (fprintf(fichier, "\n\\end{document}\n") < 0)
  {
    erreur = errno;
    printf("Error: writing on LaTeX file \n");
    Erreur_printf(erreur);
    return;
  }  
}

/************************************
*
* LectureExemple.      
*
************************************/

void LectureExemple(FILE *fichier)      /* Fichiers KR p.158 */
{
  char buffer[TAILLE_BUFFER];

  fgets(buffer, TAILLE_BUFFER, fichier);  /* Version ignoree pour l'instant */

  if (fscanf(fichier, "%lu %% Taille maximum", &TailleMaxi) != 1)
  {
    printf("scanf error: Taille maximum\n");
    exit(1);
  }
  if (fscanf(fichier, "%hu %% Type de calcul", &TypeCalcul) != 1)
  {
    printf("scanf error: Type de calcul\n");
    exit(1);
  }
  if (fscanf(fichier, "%hu %% Type de semigroupe", &TypeSemigroupe) != 1)
  {
    printf("scanf error: Type de semigroupe\n");
    exit(1);
  }
  if (fscanf(fichier, "%hu %% Partie pointee ?", &PartiePointee) != 1)
  {
    printf("scanf error: Partie pointee\n");
    exit(1);
  }
  if (PartiePointee)
  {
    if (fscanf(fichier, "%hu %% Initiaux specifies", &InitiauxDejaSpecifies) != 1)
    {
      printf("scanf error: Initiaux specifies\n");
      exit(1);
    }
    if (fscanf(fichier, "%hu %% Finaux specifies\n", &FinauxDejaSpecifies) != 1)
    {
      printf("scanf error: Finaux specifies\n");
      exit(1);
    }
  }
  if (fscanf(fichier, "%hu %% Semigroupe renverse ?", &SemigroupeRenverse) != 1)
  {
    printf("scanf error: Semigroupe renverse\n");
    exit(1);
  }
  if (fscanf(fichier, "%hu %% Nombre de generateurs", &NbLettres) != 1)
  {
    printf("scanf error: Nombre de generateurs\n");
    exit(1);
  }
  EtatInitial1 = (!PartiePointee) || (TypeSemigroupe == ParTransitions) || (TypeSemigroupe == ParTransitionsPartielles);
  Choix();
  LectureFichier(fichier);
  TailleTableDeHachage = EstimationTailleTableDeHachage(TailleMaxi + 1);
  TailleTableDeHachageMoinsUn = TailleTableDeHachage - 1;
  Fermeture(fichier);
}

/************************************
*
* ModificationFichier.      
*
************************************/

void ModificationFichier(FILE *fichier)      /* Fichiers KR p.158 */
{
  char buffer[TAILLE_BUFFER];
  long n;
  int erreur;

  fgets(buffer, TAILLE_BUFFER, fichier);
  n = ftell(fichier);
  rewind(fichier);
  fseek(fichier, n, SEEK_SET);
  if (fprintf(fichier, "%8lu %% Taille maximum\n", NbElements) < 0)
  {
    erreur = errno;
    printf("fprintf %8lu %% Taille maximum failed!\n", NbElements);
    Erreur_printf(erreur);
    return;
  }  
  Fermeture(fichier);
}