{ File: esami.pas }

{ Scopo: uso di file di record }

program VotiEsami;
{ Gestisce un archivio di esami memorizzato su un file di record PASCAL.
  Le informazioni associate ad ogni esame sono:
    - materia
    - data in cui e` stato sostenuto (giorno, mese, anno)
    - voto
}

const
  MaxNumEsami = 35;

type
  TipoData  = record
                giorno : 1..31;
                mese   : 1..12;
                anno   : integer;
              end;

  TipoEsame = record
                materia : string[30];
                data    : TipoData;
                voto    : 1..31
              end;

  TipoEsami = record
                lista  : array [1..MaxNumEsami] of TipoEsame;
                numero : 0..MaxNumEsami;
              end;     

  TipoFileEsami = file of TipoEsame;

var
  ch        : char;      { scelta del menu }
  esami     : TipoEsami; { lista di esami e loro numero }


  procedure AggiungiEsame (var es: TipoEsami);
  begin { AggiungiEsame }
    with es do
      if numero = MaxNumEsami then
        writeln('ERRORE ! Raggiunto numero massimo')
      else
      begin
        numero := numero + 1;
        write('Nome ? ');
        readln(lista[numero].materia);
        write('Data (g,m,a) ? ');
        with lista[numero].data do readln(giorno, mese, anno);
        write('Voto ? ');
        readln(lista[numero].voto);
        writeln
      end
  end; { AggiungiEsame }


  procedure CancellaEsame (var es: TipoEsami);
  var
    canc,            { esame da cancellare }
    i    : integer;  { indice del ciclo per lo spostamento degli elementi
                       successivi a quello da cancellare }

  begin { CancellaEsame }
    if es.numero <> 0 then
    begin
      write('Quale esame vuoi cancellare ? [1..', es.numero, '] ');
      readln(canc);
      if (canc >= 1) and (canc <= es.numero) then
      begin
        es.numero := es.numero - 1;
        for i := canc to es.numero do
          es.lista[i] := es.lista[i+1];
      end
      else
        writeln('Scelta non valida.  Nessun esame cancellato')
    end
  end; { CancellaEsame }


  procedure VisualizzaEsami (es: TipoEsami);
  var
    i     : 0..MaxNumEsami; { indice per la scansione della lista di voti }
    somma : integer;        { somma dei voti }

  begin
    somma := 0;
    writeln('Num', 'Materia':22, 'Data':12, 'Voto':6);
    for i := 1 to es.numero do
      with es.lista[i] do
      begin
        writeln(i:3, materia:22,
                data.giorno:4, '/', data.mese:2, '/', data.anno:4,
                voto:6);
        somma := somma + voto
      end;
    writeln;
    if es.numero <> 0 then
    begin
      writeln('Media dei voti: ', somma/es.numero:6:2);
      writeln
    end
  end; { VisualizzaEsami }


  procedure LeggiEsami (var es: TipoEsami);
  var
    f         : TipoFileEsami;
    nome_file : string;

  begin { LeggiEsami }
    write('Nome del file dal quale leggere la lista di esami ? ');
    readln(nome_file);

    Assign(f, nome_file);
    Reset(f);

    es.numero := 0;
    while not eof(f) do
    begin
      es.numero := es.numero + 1;
      read(f, es.lista[es.numero])
    end;

    Close(f)
  end; { LeggiEsami }


  procedure SalvaEsami (es: TipoEsami);
  var
    f         : TipoFileEsami;
    nome_file : string;
    i         : 0..MaxNumEsami;

  begin { SalvaEsami }
    write('Nome del file sul quale salvare la lista di esami ? ');
    readln(nome_file);

    Assign(f, nome_file);    { apertura del file in scrittura }
    Rewrite(f);              { il precedente contenuto del file va` perso }

    for i := 1 to es.numero do
      write(f, es.lista[i]);

    Close(f)
  end; { SalvaEsami }


begin { VotiEsami }
  esami.numero := 0;
  repeat
    writeln;
    writeln('*** IMMETTI UN CARATTERE A SCELTA FRA I SEGUENTI ***');
    writeln('***** L: leggi una lista di esami da file');
    writeln('***** A: aggiungi un esame alla lista');
    writeln('***** C: cancella un esame alla lista');
    writeln('***** V: visualizza la lista di esami');
    writeln('***** S: salva la lista di esami su file');
    writeln('***** F: per terminare');
    writeln;
    readln(ch);
    case ch of
      'L', 'l' : LeggiEsami(esami);
      'A', 'a' : AggiungiEsame(esami);
      'C', 'c' : CancellaEsame(esami);
      'V', 'v' : VisualizzaEsami(esami);
      'S', 's' : SalvaEsami(esami);
    end; { case }
  until (ch = 'f') or (ch = 'F')
end. { VotiEsami }