/* File: driverli.c */
/* Time-stamp: "2002-05-20 18:53:54 calvanes" */
/* Scopo: driver per le funzioni per la manipolazione di liste */

#include <stdio.h>
#include <stdlib.h>

#define TRUE  1
#define FALSE 0
typedef int bool;

typedef int TipoElemLista;

struct nodoLista {
  TipoElemLista info;
  struct nodoLista *next;
};
typedef struct nodoLista NodoLista;
typedef NodoLista *TipoLista;


#include "liste.c"


bool UgualeElemento(TipoElemLista elem1, TipoElemLista elem2)
{
  return (elem1 == elem2);
}  /* UgualeElemento */

#include "listecon.c"


bool MinoreElemento(TipoElemLista elem1, TipoElemLista elem2)
{
  return (elem1 < elem2);
}  /* MinoreElemento */

#include "listeord.c"


/* Per provare le versioni ricorsive delle funzioni, includere al posto dei
   file liste.c, listecon.c e listeord.c il file listeric.c. */

/* #include "listeric.c" */

/* Per provare le versioni delle funzioni che utilizzano le procedure
   elementari sulle liste, includere al posto dei file liste.c, listecon.c
   e listeord.c il file listealt. */

/* #include "listealt.c" */


void ScriviElemento(FILE *fi, TipoElemLista elem)
{
  fprintf(fi, "%d\n", elem);
}  /* ScriviElemento */


int LeggiElemento(FILE *fi, TipoElemLista *pelem)
{
  int result;

  result = fscanf(fi, "%d", pelem);
  if (result == 0)                                      /* errore di lettura */
    return EOF;                    /* si forza la terminazione di LeggiLista */
  else
    return result;
}  /* LeggiElemento */

/* #include "listerw.c" */
#include "listeirw.c"


void StampaLista(TipoLista lis)
  /* Stampa la lista sullo schermo. */
{
  if (lis == NULL)
    printf("vuota\n");
  else {
    while (lis != NULL) {
      printf("%d ", lis->info);
      lis = lis->next;
    }
    putchar('\n');
  }
}  /* StampaLista */


int main(void)
{
  TipoLista lista;          /* lista usata nel programma */
  TipoElemLista elem;       /* elemento della lista */
  char scelta;              /* opzione del menu che e` stata scelta */
  char nomefile[256];       /* nome del file da leggere o scrivere */
  FILE *datafile;           /* file da leggere o scrivere */

  InitLista(&lista);        /* inizializza la lista */

  do {
    printf("Opzioni:\n");
    /* printf("0 Inizializza la lista                                \n"); */
    printf("1: Inserisci in testa                                  \n");
    printf("2: Inserisci in coda                                   \n");
    printf("-------------------------------------------------------\n");
    printf("3: Cancella primo elemento                             \n");
    printf("4: Cancella la prima occorrenza di un elemento         \n");
    printf("5: Cancella tutte le occorrenze di un elemento         \n");
    printf("6: Cancella tutta la lista                             \n");
    printf("-------------------------------------------------------\n");
    printf("7: Inverti la lista                                    \n");
    printf("-------------------------------------------------------\n");
    printf("8: Verifica se la lista e` vuota                       \n");
    printf("9: Elemento in testa                                   \n");
    printf("a: Verifica se un elemento compare nella lista         \n");
    printf("-------------------------------------------------------\n");
    printf("b: Inserisci in lista ordinata                         \n");
    printf("c: Cancella un elemento dalla lista ordinata           \n");
    printf("d: Verifica se un elemento compare nella lista ordinata\n");
    printf("-------------------------------------------------------\n");
    printf("e: Leggi lista da file                                 \n");
    printf("f: Scrivi lista su file                                \n");
    printf("-------------------------------------------------------\n");
    printf("Q: FINE                                                \n");
    printf("Lista = ");
    StampaLista(lista);
    printf("Scelta: ");
    scelta = getchar();
    printf("%c ", scelta);

    switch (scelta) {

    /* case '0':
         printf("(inizializzazione della lista)\n");
         InitLista(&lista);
         break;
    */

    case '1':
      printf("(inserimento in testa)\n");
      printf("Scrivere intero da inserire in testa: ");
      scanf("%d%*[^\n]", &elem);
      getchar();
      InserisciTestaLista(&lista, elem);
      break;

    case '2':
      printf("(inserimento in coda)\n");
      printf("Scrivere intero da inserire in coda: ");
      scanf("%d%*[^\n]", &elem);
      getchar();
      InserisciCodaLista(&lista, elem);
      break;

    case '3':
      printf("(cancellazione del primo elemento)\n");
      CancellaPrimoLista(&lista);
      break;

    case '4':
      printf("(cancellazione della prima occorrenza di un elemento)\n");
      printf("Scrivere elemento da cancellare: ");
      scanf("%d%*[^\n]", &elem);
      getchar();
      CancellaElementoLista(&lista, elem);
      break;

    case '5':
      printf("(cancellazione di tutte le occorrenze di un elemento)\n");
      printf("Scrivere elemento da cancellare: ");
      scanf("%d%*[^\n]", &elem);
      getchar();
      CancellaTuttiLista(&lista, elem);
      break;

    case '6':
      printf("(cancellazione di tutta la lista)\n");
      CancellaLista(&lista);
      break;

    case '7':
      printf("(inversione della lista)\n");
      InvertiLista(&lista);
      break;

    case '8':
      printf("(verifica se la lista e` vuota)\n");
      if (TestListaVuota(lista))
        printf("La lista e` vuota\n");
      else
        printf("La lista non e` vuota\n");
      break;

    case '9':
      printf("(elemento in testa alla lista)\n");
      TestaLista(lista, &elem);
      printf("L'elemento in testa alla lista e` %4d\n", elem);
      break;

    case 'a':
      printf("(verifica se un elemento compare nella lista)\n");
      printf("Scrivere elemento da cercare: ");
      scanf("%d%*[^\n]", &elem);
      getchar();
      if (EsisteInLista(lista, elem))
        printf("L'elemento %4d compare nella lista.\n", elem);
      else
        printf("L'elemento %4d non compare nella lista.\n", elem);
      break;

    case 'b':
      printf("(inserimento in lista ordinata)\n");
      printf("Scrivere intero da inserire: ");
      scanf("%d%*[^\n]", &elem);
      getchar();
      InserisciInListaOrdinata(&lista, elem);
      break;

    case 'c':
      printf("(cancellazione di un elemento da lista ordinata)\n");
      printf("Scrivere elemento da cancellare: ");
      scanf("%d%*[^\n]", &elem);
      getchar();
      CancellaElementoListaOrdinata(&lista, elem);
      break;

    case 'd':
      printf("(verifica se un elemento compare nella lista ordinata)\n");
      printf("Scrivere elemento da cercare: ");
      scanf("%d%*[^\n]", &elem);
      getchar();
      if (EsisteInListaOrdinata(lista, elem))
        printf("L'elemento %d compare nella lista.\n", elem);
      else
        printf("L'elemento %d non compare nella lista.\n", elem);
      break;

    case 'e':
      printf("(lettura della lista da file)\n");
      printf("Scrivi il nome del file di ingresso: ");
      scanf("%s", nomefile);

                                               /* verifica se il file esiste */
      datafile = fopen(nomefile, "r");
      if (datafile == NULL)                 /* errore in apertura in lettura */
        printf("Errore aprendo il file `%s' in lettura\n", nomefile);
      else {                                            /* apertura riuscita */
        CancellaLista(&lista);
        LeggiListaFile(datafile, &lista);
        fclose(datafile);
      }
      break;

    case 'f':
      printf("(scrittura della lista su file)\n");
      printf("Scrivi il nome del file di uscita: ");
      scanf("%s", nomefile);
      datafile = fopen(nomefile, "w");
      if (datafile == NULL)                            /* errore in apertura */
        printf("Errore aprendo il file `%s' in scrittura\n", nomefile);
      else {
        ScriviListaFile(datafile, lista);
        fclose(datafile);
      }
      break;
    }

    if (scelta >= 'a' && scelta <= 'g' || scelta >= '1' && scelta <= '9')
    {   /* scelta valida */
      if (scelta == 'e' || scelta == 'c' || scelta == 'b' ||
          scelta >= '1' && scelta <= '7')
      {   /* lista viene modificata */
        printf("\nLista = ");
        StampaLista(lista);
      }
      printf("\n[premi invio]\n");
      scelta = getchar();
    }
    else {
      if (scelta != ' ' && scelta != 'Q')
        printf("(non valida)");
      sleep(1);
      putchar('\n');
    }
  } while (scelta != 'Q');

  /* scelta non valida o fine */
  /* libera la memoria allocata per la lista */
  CancellaLista(&lista);
  return 0;
}  /* DriverListe */