/* File: doping.c */
/* Time-stamp: "2002-06-04 19:29:31 calvanes" */
/* Scopo: esercizio di esame del 11/9/1998 */


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

/* Dichiarazioni di costanti e tipi */

#define NumAtleti       6
#define LungSigla       13


typedef char TipoSigla[LungSigla];   /* sigla di un farmaco */


struct Data {
  int giorno, mese, anno;
};
typedef struct Data TipoData;


struct Farmaco {
  TipoSigla sigla;
  TipoData data;
  struct Farmaco *next;
};
typedef struct Farmaco TipoFarmaco;

typedef TipoFarmaco *TipoListaFarmaci;


struct Atleta {
  int matricola;
  TipoListaFarmaci prescrizioni;         /* lista farmaci prescritti */
};
typedef struct Atleta TipoAtleta;

typedef TipoAtleta TipoArchivio[NumAtleti];


struct Doping {                          /* informazioni memorizzate su file */
  TipoSigla sigla;
  int ammesso;                           /* 0 = vietato,  1 = ammesso */
  TipoData data;                         /* data di divieto/ammissione */
};
typedef struct Doping TipoDoping;



/* Funzione che risolve il punto 3 */

TipoListaFarmaci farmaciAmmessi(char *nome_file)
  /* Restituisce la lista dei farmaci ammessi contenuti nel file nome_file.

     Formato dei dati sul file:

Z 0 01-07-98
X 1 01-01-98
S 1 30-06-98
Y 0 01-01-97
R 1 01-01-98

   */
{
  TipoListaFarmaci paux, lista_farmaci = NULL;
  TipoDoping doping;                        /* mantiene i dati letti da file */
  FILE *f;

  f = fopen(nome_file, "r");
  if (f == NULL) {
    fprintf(stderr, "Errore in apertura in lettura del file %s\n", nome_file);
    exit(1);
  }

  fscanf(f, "%s%d%d%*c%d%*c%d", doping.sigla, &doping.ammesso,
         &doping.data.giorno, &doping.data.mese, &doping.data.anno);
  while (!feof(f)) {
    if (doping.ammesso) {                           /* il farmaco e` ammesso */
      paux = malloc(sizeof(TipoFarmaco));
      strcpy(paux->sigla, doping.sigla);
      paux->data = doping.data;
      paux->next = lista_farmaci;
      lista_farmaci = paux;
    }
    fscanf(f, "%s%d%d%*c%d%*c%d", doping.sigla, &doping.ammesso,
           &doping.data.giorno, &doping.data.mese, &doping.data.anno);
  }

  fclose(f);
  return lista_farmaci;
}  /* farmaciAmmessi */



/* Funzioni che risolvono il punto 2 */

int dataNonAnteriore(TipoData data1, TipoData data2)
  /* Restituisce vero (1) se data1 e` una data non anteriore a data 2, e falso
     (0) altrimenti. */
{
  return (data1.anno > data2.anno ||
          (data1.anno == data2.anno &&
           (data1.mese > data2.mese ||
            (data1.mese == data2.mese && data1.giorno >= data2.giorno))));
}  /* NonAnterioreData */


void eliminaPrescrizione(TipoListaFarmaci *lista_farmaci, TipoDoping dop)
  /* Elimina da lista_farmaci le prescrizioni del farmaco specificato da dop,
     se la prescrizione e` avvenuta in data non anteriore a quella della data
     specificata in dop. */
{
  TipoListaFarmaci paux;

  if (*lista_farmaci != NULL) {
    eliminaPrescrizione(&(*lista_farmaci)->next, dop);
    if (!strcmp((*lista_farmaci)->sigla, dop.sigla) &&
        dataNonAnteriore((*lista_farmaci)->data, dop.data)) {
      paux = *lista_farmaci;
      *lista_farmaci = (*lista_farmaci)->next;
      free(paux);
    }
  }
}  /* eliminaPrescrizione */


void eliminaPrescrizioniVietate(TipoArchivio archivio, char *nome_file)
  /* Elimina dall'archivio tutte le prescrizioni dei farmaci che sono stati
     prescritti in data non anteriore a quella del divieto specificato nel file
     nome_file.

     Formato dei dati sul file:

Z 0 01-07-98
X 1 01-01-98
S 1 30-06-98
Y 0 01-01-97
R 1 01-01-98

  */
{
  FILE *f;
  TipoDoping doping;
  int i;

  f = fopen(nome_file, "r");
  if (f == NULL) {
    fprintf(stderr, "Errore in apertura in lettura del file %s\n", nome_file);
    exit(1);
  }

  fscanf(f, "%s%d%d%*c%d%*c%d", doping.sigla, &doping.ammesso,
         &doping.data.giorno, &doping.data.mese, &doping.data.anno);

  while (!feof(f)) {
    if (!doping.ammesso) {                          /* il farmaco e` vietato */

      /* Questa stampa non e` richiesta dalla specifica */
      printf("Da eliminare: %s %d-%d-%d\n", doping.sigla,
             doping.data.giorno, doping.data.mese, doping.data.anno);

      for (i = 0; i < NumAtleti; i++)
        eliminaPrescrizione(&archivio[i].prescrizioni, doping);
    }
    fscanf(f, "%s%d%d%*c%d%*c%d", doping.sigla, &doping.ammesso,
           &doping.data.giorno, &doping.data.mese, &doping.data.anno);
  }

  fclose(f);
}  /* eliminaPrescrizioniVietate */



/* funzioni ausiliarie per la verifica del programma */

void leggiArchivio(TipoArchivio archivio, char *nome_file)
  /* Legge da file le informazioni contenute in un archivio e costruisce
     l'archivio in memoria centrale.

     Formato dei dati sul file (con numero di righe pari a NumAtleti):

12 2 Z 31/7/98 Y 30/3/97
5  0
39 1 Z 30/6/98
21 0
16 0
87 2 T 31/8/98 Z 1/7/98

  */
{
  FILE *f;
  int i, numfarmaci;
  TipoListaFarmaci paux;

  f = fopen(nome_file, "r");
  if (f == NULL) {
    fprintf(stderr, "Errore in apertura in lettura del file %s\n", nome_file);
    exit(1);
  }

  for (i = 0; i < NumAtleti; i++) {
    fscanf(f, "%d%d", &archivio[i].matricola, &numfarmaci);
    archivio[i].prescrizioni = NULL;
    for (; numfarmaci > 0; numfarmaci--) {
      paux = malloc(sizeof(TipoFarmaco));
      fscanf(f, "%s%d%*c%d%*c%d", paux->sigla, &paux->data.giorno,
             &paux->data.mese, &paux->data.anno);
      paux->next = archivio[i].prescrizioni;
      archivio[i].prescrizioni = paux;
    }
  }

  fclose(f);
}


void stampaArchivio(TipoArchivio archivio)
{
  int i;
  TipoListaFarmaci paux;

  for (i = 0; i < NumAtleti; i++) {
    printf("%2d: ", archivio[i].matricola);
    paux = archivio[i].prescrizioni;
    while (paux != NULL) {
      printf("  %s %02d-%02d-%02d |", paux->sigla, paux->data.giorno,
             paux->data.mese, paux->data.anno);
      paux = paux->next;
    }
    printf("\n");
  }
}


void stampaLista(TipoListaFarmaci farmaci)
{
  while (farmaci != NULL) {
    printf("%s %02d-%02d-%02d\n", farmaci->sigla,
           farmaci->data.giorno,
           farmaci->data.mese,
           farmaci->data.anno);
    farmaci = farmaci->next;
  }
}



/* Programma principale */

int main(void)
{
  TipoListaFarmaci farmaci = NULL;
  TipoArchivio archivio;

  leggiArchivio(archivio, "prescriz.dat");
  printf("Archivio prima dell'aggiornamento:\n");
  stampaArchivio(archivio);

  putchar('\n');
  eliminaPrescrizioniVietate(archivio, "farmaci.dat");
  printf("\nArchivio dopo l'aggiornamento:\n");
  stampaArchivio(archivio);

  farmaci = farmaciAmmessi("farmaci.dat");
  printf("\nLista dei farmaci ammessi:\n");
  stampaLista(farmaci);

  return 0;
}