/*-------------------------------------------------------------------------*
 *                          Tri.c  Source C                                * 
 *                          ~~~~~  ~~~~~~~~                                * 
 *                                                                         *
 *  Auteur     : Xavier Leclercq    pour "Le Petit Amiga illustré"         *
 *                                                                         *
 *  But du jeu : UTILISER LES STRUCTURES DE TYPE "LIST" DE L'exec.library  *
 *                                                                         *
 *-------------------------------------------------------------------------*/

#include <stdio.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>

#define  BOLD      "\x9b1;31;40m"
#define  ITALIC    "\x9b3;31;40m"
#define  SOULIGNE  "\x9b4;31;40m"
#define  INVERSE   "\x9b7;31;40m"
#define  NORMAL    "\x9b0;31;40m"
#define  COPYRIGHT "\xa9"

/*-------------------------------------------------------------------------*/
/* Structure d'un noeud personnel */

struct MonNoeud {
  struct Node LeNoeud;
  char   datas[80];
};

/*-------------------------------------------------------------------------*/
/* Variables globales */

FILE   *fp1 = NULL;
FILE   *fp2 = NULL;
char   Buffer[80];
struct MonNoeud *Noeud    = NULL;
struct MinList  *MaListe  = NULL;
struct MonNoeud *NoeudDeb = NULL;
struct MonNoeud *NoeudFin = NULL;
void   *AllocMem();
char   *Prem = "PREMIER"; 
char   *Dern = "DERNIER"; 

/*-------------------------------------------------------------------------*/
/* Libère un noeud */

LibereNoeud(Noeud)
register struct MonNoeud *Noeud;
{
 if (Noeud) FreeMem(Noeud,(long) sizeof(struct MonNoeud));
}

/*-------------------------------------------------------------------------*/
/* Libère chaque noeud de la liste */

LibereTout(MaListe)
register struct MinList *MaListe;
{
  register struct MonNoeud *Noeud;
  while (Noeud = (struct MonNoeud *) RemHead(MaListe)) {
   if ((strcmp(Noeud->LeNoeud.ln_Name,Prem) != 0 ) && 
       (strcmp(Noeud->LeNoeud.ln_Name,Dern) != 0 ))
      fputs(Noeud->datas,fp2);
   LibereNoeud(Noeud);
  }
}

/*-------------------------------------------------------------------------*/
/* Libère la liste */

LibereListe(MaListe)
register struct MinList *MaListe;
{
  if (MaListe) {
    if (MaListe->mlh_Head) LibereTout(MaListe);
    FreeMem(MaListe , (long) sizeof(struct MaListe));
  }  
}

/*-------------------------------------------------------------------------*/
AlloueTete()
{
 if (!(MaListe = AllocMem((long) 
     sizeof(struct MinList), MEMF_PUBLIC | MEMF_CLEAR ))) {
   puts("Je manque de mémoire pour initialiser la tête de liste !");
   OnSort(1);
 }
/* Initialise la tête de liste */
 NewList(MaListe);

 int i;

/* Alloue un noeud qui prendra la première place par ordre alphabétique */
/* = AAAAAA... Ajout comme premier élément de la liste : AddHead() */
 AlloueNoeud();
 for(i=0;i<80;Buffer[i++]='A');
 strcpy(Noeud->datas,Buffer);
 NoeudDeb = Noeud;
 Noeud->LeNoeud.ln_Name = Prem;
 AddHead(MaListe,Noeud);
 
/* Alloue un noeud qui prendra la dernière place par ordre alphabétique */
/* = zzzzzz... Ajout comme dernier élément de la liste : AddTail() */
 AlloueNoeud();
 for(i=0;i<80;Buffer[i++]='z');
 strcpy(Noeud->datas,Buffer);
 NoeudFin = Noeud;
 Noeud->LeNoeud.ln_Name = Dern;
 AddTail(MaListe,Noeud);
}
/*-------------------------------------------------------------------------*/
AlloueNoeud()
{
 if (!(Noeud = AllocMem((long) 
     sizeof(struct MonNoeud), MEMF_PUBLIC | MEMF_CLEAR ))) {
   puts("Je manque de mémoire pour initialiser un noeud de la liste !");
   OnSort(1);
 } 
 strcpy(Noeud->datas,Buffer);
}
/*-------------------------------------------------------------------------*/
OnSort(int n)
{
 LibereListe(MaListe);
 if (fp1) fclose(fp1);
 if (fp2) fclose(fp2);
 exit(n);
}
/*-------------------------------------------------------------------------*/
Tri()
{
 struct MonNoeud *Suivant;
 
 AlloueNoeud();

 Suivant = NoeudDeb; 
 while ( Suivant != NULL ) {
   if (strcmp(Noeud->datas,Suivant->datas) <= 0) {
     Insert(MaListe,Noeud,Suivant->LeNoeud.ln_Pred);
     break;
   } 
   else
     Suivant = Suivant->LeNoeud.ln_Succ; 
 }
}
/*-------------------------------------------------------------------------*/
main(int argc,char *argv[])
{
 if (argc > 2) {
   AlloueTete();
   if(!(ferror(fp1=fopen(argv[1],"r")))) {
     if(!(ferror(fp2=fopen(argv[2],"w")))) {
       fgets(Buffer,80,fp1);
       while(!feof(fp1)) {
         Buffer[0] = toupper(Buffer[0]);
         Tri();
         fgets(Buffer,80,fp1);
       }
       OnSort(0);
     }
     else {
       fclose(fp1);
       printf("Erreur d'ouverture du fichier %s\n",argv[2]);
     }
   }
   else
     printf("Erreur d'ouverture du fichier %s\n",argv[1]);
 }
 else {
   printf("%sTRI%s",BOLD,NORMAL);
   printf(" Auteur : %sXavier Leclercq%s\n"\
          "%s12 Vieux Chemin d'Ath B-7548"\
          " Warchin BELGIUM%s\n\n",BOLD,NORMAL,ITALIC,NORMAL);
   puts("USAGE : TRI <Fichier texte en entrée> <Fichier texte en sortie>\n");
 }
exit(0);
}
