{ File: driverli.pas }

{ Scopo: operazioni su liste collegate semplici:
         - driver per verificare il funzionamento delle operazioni contenute
           nei file LISTE.PAS,
                    LISTECON.PAS,
                    LISTEORD.PAS,
                    LISTERIC.PAS,
                    LISTEALT.PAS.
}

program DriverListe;

uses
  crt,  { per `readkey' e `delay' }
  dos;  { per `FindFirst', `SearchRec', `archive', `DosError' }

type
  TipoElemLista = integer;
  TipoLista       = ^TipoRecordLista;
  TipoRecordLista = record
                      info : TipoElemLista;
                      next : TipoLista
                    end;

{$I LISTE.PAS}

function UgualeElemento (elem1, elem2: TipoElemLista): boolean;
begin
  UgualeElemento := elem1 = elem2
end; { uguale_elemento }

{$I LISTECON.PAS}

function MinoreElemento (elem1, elem2: TipoElemLista): boolean;
begin
  MinoreElemento := elem1 < elem2
end; { MinoreElemento }

{$I LISTEORD.PAS}

{ Per provare le versioni ricorsive delle procedure, sostituire nelle righe in
  cui viene effettuata l'inclusione di LISTE.PAS, LISTECON.PAS e LISTEORD.PAS
  $I con SI e sostituire nella riga successiva SI con $I. }

{SI LISTERIC.PAS}

{ Per provare le versioni delle procedure che utilizzano le procedure
  elementari sulle liste, sostituire nelle righe in cui viene effettuata
  l'inclusione di LISTE.PAS, LISTECON.PAS e LISTEORD.PAS $I con SI e
  sostituire nella riga successiva SI con $I. }

{SI LISTEALT.PAS}

type
  TipoFileLista = Text;
  TipoNomeFile  = string;

procedure ScriviElemento (var fi: TipoFileLista;
                          elem: TipoElemLista);
begin
  writeln(fi, elem)
end; { ScriviElemento }

procedure LeggiElemento (var fi: TipoFileLista;
                         var elem: TipoElemLista);
begin
  readln(fi, elem)
end; { LeggiElemento }

function LetturaTerminata (var fi: TipoFileLista): boolean;
begin
  LetturaTerminata := eof(fi)
end; { LetturaTerminata }

{$I LISTERW.PAS}

procedure StampaLista(lis: TipoLista);
{ Stampa la lista sullo schermo. }
begin
  if lis = NIL then
    writeln('vuota')
  else
  begin
    while lis <> NIL do
    begin
      write(lis^.info:4);
      lis := lis^.next
    end;
    writeln
  end
end; { StampaLista }


var
  nome_file : TipoNomeFile;   { nome del fiel da leggere o scrivere }
  lista     : TipoLista;      { lista usata nel programma }
  elem      : TipoElemLista;  { elemento della lista }
  scelta    : char;           { opzione del menu che e` stata scelta }

  dir_info  : SearchRec;      { usata in `FindFirst' }

begin
  { inizializza la lista }
  InitLista(lista);

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

    case scelta of
    { '0' : begin
              writeln('(inizializzazione della lista)');
              InitLista(lista)
            end; }
      '1' : begin
              writeln('(inserimento in testa)');
              write('Scrivere intero da inserire in testa: ');
              readln(elem);
              InserisciTestaLista(lista, elem)
            end;
      '2' : begin
              writeln('(inserimento in coda)');
              write('Scrivere intero da inserire in coda: ');
              readln(elem);
              InserisciCodaLista(lista, elem)
            end;
      '3' : begin
              writeln('(cancellazione del primo elemento)');
              CancellaPrimoLista(lista)
            end;
      '4' : begin
              writeln('(cancellazione della prima occorrenza di un elemento)');
              write('Scrivere elemento da cancellare: ');
              readln(elem);
              CancellaElementoLista(lista, elem)
            end;
      '5' : begin
              writeln('(cancellazione di tutte le occorrenze di un elemento)');
              write('Scrivere elemento da cancellare: ');
              readln(elem);
              CancellaTuttiLista(lista, elem)
            end;
      '6' : begin
              writeln('(cancellazione di tutta la lista)');
              CancellaLista(lista)
            end;
      '7' : begin
              writeln('(inversione della lista)');
              InvertiLista(lista)
            end;
      '8' : begin
              writeln('(verifica se la lista e` vuota)');
              if TestListaVuota(lista) then
                writeln('La lista e` vuota')
              else
                writeln('La lista non e` vuota')
            end;
      '9' : begin
              writeln('(elemento in testa alla lista)');
              TestaLista(lista, elem);
              writeln('L''elemento in testa alla lista e` ', elem:4);
            end;
      'a' : begin
              writeln('(verifica se un elemento compare nella lista)');
              write('Scrivere elemento da cercare: ');
              readln(elem);
              if EsisteInLista(lista, elem) then
                writeln('L''elemento ', elem:4, ' compare nella lista.')
              else
                writeln('L''elemento ', elem:4, ' non compare nella lista.')
            end;
      'b' : begin
              writeln('(inserimento in lista ordinata)');
              write('Scrivere intero da inserire: ');
              readln(elem);
              InserisciInListaOrdinata(lista, elem)
            end;
      'c' : begin
              writeln('(cancellazione di un elemento da lista ordinata)');
              write('Scrivere elemento da cancellare: ');
              readln(elem);
              CancellaElementoListaOrdinata(lista, elem)
            end;
      'd' : begin
              writeln('(verifica se un elemento compare nella lista ordinata)');
              write('Scrivere elemento da cercare: ');
              readln(elem);
              if EsisteInListaOrdinata(lista, elem) then
                writeln('L''elemento ', elem:4, ' compare nella lista.')
              else
                writeln('L''elemento ', elem:4, ' non compare nella lista.')
            end;
      'e' : begin
              writeln('(lettura della lista da file)');
              write('Scrivi il nome del file di ingresso: ');
              readln(nome_file);

              { verifica se il file esiste }
              FindFirst(nome_file, archive, dir_info);
              if DosError = 0 then { il file esiste }
              begin
                CancellaLista(lista);
                LeggiLista(nome_file, lista)
              end
              else
                writeln('Il file `', nome_file, ''' non esiste')
            end;
      'f' : begin
              writeln('(scrittura della lista su file)');
              write('Scrivi il nome del file di uscita: ');
              readln(nome_file);
              ScriviLista(nome_file, lista)
            end;
    end;

    if scelta in ['1'..'9','a'..'g'] then { scelta valida }
    begin
      if scelta in ['1'..'7','b','c','e'] then { lista viene modificata }
      begin
        writeln;
        write('Lista = ');
        StampaLista(lista)
      end;
      writeln;
      writeln('[premi un tasto]');
      scelta := readkey
    end
    else  { scelta non valida o fine }
    begin
      if (not (scelta in ['Q',' '])) then
        write('(non valida)');
      delay(750);
      writeln
    end
  until scelta = 'Q';

  { libera la memoria allocata per la lista }
  CancellaLista(lista)
end. { DriverListe }