program Studenti;
{esempio di gestione di un archivio studenti in memoria centrale}
const NumStud=2;
type Nat = 0..MaxInt;
     Index = 1..NumStud;
     Materie = (Lab2, ASD, MatDiscreta);
     Voto = 17..31;
     ListaEsami = array [Materie] of Voto;
     Data = record
            giorno:1..31;
            mese:1..12;
            anno:integer
            end;
     Studente = record
                   Nome:string;
                   Matricola:string;
                   Datanascita:Data;
                   Esami:ListaEsami
                end;
     Archivio = array [Index] of Studente;

var  CorsoA :Archivio;

procedure StampaMaterie(M:Materie);
{procedura di stampa per il tipo enumerato Materie}
begin
  case M of
    Lab2:write('Laboratorio2':14);
    ASD:write('ASD':14);
    MatDiscreta:write('MatDiscreta':14)
  end
end;{fine della procedura StampaMaterie}

procedure LeggiStudente (var S:Studente);
{procedura di lettura per il tipo record Studente}
var M:Materie;
begin
  with S do
    begin
      writeln('Inserisci il nome dello studente:');
      readln(Nome);
      writeln('Inserisci la matricola dello studente:');
      readln(Matricola);
      writeln('Inserisci la data di nascita dello studente (nel formato gg mm aa):');
      read(datanascita.giorno);
      read(datanascita.mese);
      readln(datanascita.anno);
      for M:=Lab2 to MatDiscreta do
        begin
           write('Inserisci il voto di ');
          StampaMaterie(M);
          write(':');
          readln(Esami[M])
        end
     end
end; {fine della procedura Leggi Studente}

procedure StampaStudente(S:Studente);
{procedura di stampa per il tipo record Studente}
var M:Materie;
begin
  with S do
  begin
    writeln('Nome : ':17, Nome);
    writeln('Matricola : ':17,Matricola);
    writeln('Data di Nascita : ':17, datanascita.giorno, '/', datanascita.mese, '/', datanascita.anno);
    writeln('Votazioni esami ');
    for M:=Lab2 to MatDiscreta do
       begin
         StampaMaterie(M);
         write(' : ');
         case (Esami[M]) of
           17: writeln('Da sostenere');
           31: writeln('30 e lode');
           else writeln(S.Esami[M])
         end
       end
    end
end; {fine della procedura StampaStudente}

procedure LeggiArchivio(var Corso:Archivio);
{procedura di lettura per il tipo array Archivio}
var I:Index;
begin
  writeln('Inserisci i voti con le seguenti modalita`:');
  writeln('Se l''esame deve essere sostenuto, inserire 17');
  writeln('Se il voto e` 30 e lode, inserire 31');
  writeln('altrimenti inserire il voto');
  for I:=1 to NumStud do
   begin
     writeln('Preparati ad inserire i dati del ', I, 'o studente');
     LeggiStudente(Corso[I]);
   end
end; {fine della procedura LeggiArchivio}



procedure scambiastu(var s1,s2:studente);
var temp:studente;
begin
   temp:=s1;
   s1:=s2;
   s2:=temp
end;

function findmin(myclass:archivio;inizio,fine:integer):integer;
var temp,i:integer;
begin
   temp:=inizio;
   for i:=inizio+1 to fine do
     begin
     if myclass[i].nome[1] < myclass[temp].nome[1] then
        temp:=i;
     end;
   findmin:=temp;
end;

function min_data(myclass:archivio;inizio,fine:integer):integer;
var temp,i:integer;
begin
   temp:=inizio;
   for i:=inizio+1 to fine do
     begin
     if myclass[i].datanascita.anno < myclass[temp].datanascita.anno then
        temp:=i
        else
     if myclass[i].datanascita.anno = myclass[temp].datanascita.anno then
        if myclass[i].datanascita.mese < myclass[temp].datanascita.mese then
        temp:=i else
                if myclass[i].datanascita.mese = myclass[temp].datanascita.mese then
                if myclass[i].datanascita.giorno < myclass[temp].datanascita.giorno then
                temp:=i
    end;
   min_data:=temp;
end;

procedure ordinastu(var myclass:archivio;nome_data:char);
var fill,min:integer;
begin
   for fill:=1 to numstud -1 do
     begin
     if nome_data='N' then
     min:=findmin(myclass,fill,numstud)
     else min:=min_data(myclass,fill,numstud);
     if min <>fill then scambiastu(myclass[min],myclass[fill])
     end
end;

procedure StampaArchivio(Corso:Archivio);
{procedura di Stampa del tipi array Archivio}
var I:Index; c: char;
begin
  writeln('Stampa dell''archivio studenti del corso C');
  writeln('Come li vuoi ordinati: per nome (N) o per data di nascita (D)?');
  readln(c);
  ordinastu(corso,c);
  for I:=1 to NumStud do
   begin
     writeln;
     StampaStudente(Corso[I]);
   end
end;{fine della procedura StampaArchivio}



begin {main}
   LeggiArchivio(CorsoA);
   StampaArchivio(CorsoA);
   readln;
end. {main}