/*
 *        File: fiumi.c
 *
 *        Data: 21/10/2016
 *
 * Descrizione: Applicazione console per memorizzare
 *              alcune informazioni sui principali
 *              fiumi italiani.
 */


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

#define MAX_NOME_FIUME 15
#define MAX_NOME_NASCE 20
#define MAX_NOME_SFOCIA 20

#define MAX_FIUMI 15
#define NOME_ARCHIVIO "db-fiumi.bin"

struct fiume {
    char nome[MAX_NOME_FIUME + 1];
    int lunghezza; // [km]
    float portata; // [m^3/s]
    char nasce[MAX_NOME_NASCE + 1];
    char sfocia[MAX_NOME_SFOCIA + 1];
};

int carica_archivio(struct fiume vett[]) {
    // Legge i dati dei fiumi da un file binario e li
    // memorizza nel vettore 'vett'.
    // Restituisce il numero di fiumi letti oppure -1 in caso di errori.
    
    int n = 0;
    FILE *fp;
    
    if ((fp = fopen(NOME_ARCHIVIO, "rb")) == NULL)
        return -1;
        
    while (n < MAX_FIUMI && fread(&vett[n], sizeof(struct fiume), 1, fp) > 0)
        n++;
    
    fclose(fp);
    return n;
}

int salva_archivio(struct fiume vett[], int dim) {
    // Scrive il contenuto del vettore in un file binario
    // Restituisce il numero di fiumi scritti oppure -1 in caso di errori.

    FILE *fp;

    if ((fp = fopen(NOME_ARCHIVIO, "wb")) == NULL)
        return -1;

    for (int i = 0; i < dim; i++)
        fwrite(&vett[i], sizeof(struct fiume), 1, fp);

    fclose(fp);
    return dim;
}

void mostra_fiumi(struct fiume vett[], int dim) {
    int lung_riga = MAX_NOME_FIUME + MAX_NOME_NASCE + MAX_NOME_SFOCIA + 37;
    
    system("CLS"); // Pulisce lo schermo. Compatibile solo con Windows
    
    printf("FIUMI D'ITALIA\n");
    for (int i = 0; i < lung_riga; i++) printf("=");
    printf("\n");
    printf("%-*s %-15s %-15s %-*s %-*s\n", MAX_NOME_FIUME, "Nome", "Lunghezza (km)",
         "Portata (m^3/s)", MAX_NOME_NASCE, "Nasce",
         MAX_NOME_SFOCIA, "Sfocia");

    for (int i = 0; i < lung_riga; i++) printf("-");
    printf("\n");
    
    if (dim > 0) {
        for (int i = 0; i < dim; i++)
            printf("%-*s %10d %15.1f %-*s %-*s\n", MAX_NOME_FIUME, vett[i].nome,
            vett[i].lunghezza, vett[i].portata,
        MAX_NOME_NASCE, vett[i].nasce,
        MAX_NOME_SFOCIA, vett[i].sfocia);
    }
    else
        printf("<Archivio vuoto>\n");
    

    for (int i = 0; i < lung_riga; i++) printf("=");
    printf("\n");

}

int menu() {
    
    bool errore;
    int scelta;
    
    printf("\n\n");
    printf("\t1) Carica archivio\n");
    printf("\t2) Salva archivio\n");
    printf("\t3) Aggiungi fiume\n");
    printf("\t4) Elimina ultimo fiume\n");
    printf("\n\t0) Uscita\n");
    
    do {
        printf("\nScelta: ");
        scanf("%d", &scelta);
        
        errore = scelta < 0 || scelta > 4;
        if (errore == true)
            printf("Scelta non valida.\n");
    }
    while (errore == true);
    return scelta;
}

int aggiungi_fiume(struct fiume vett[], int dim) {
    
    if (dim == MAX_FIUMI)
        return dim;
        
    printf("\n\n");
    printf("Nome del nuovo fiume: ");
    fflush(stdin);
    gets(vett[dim].nome);
    printf("Lunghezza (km): ");
    scanf("%d", &vett[dim].lunghezza);
    printf("Portata (m^3/s): ");
    scanf("%f", &vett[dim].portata);
    printf("Luogo da cui nasce: ");
    fflush(stdin);
    gets(vett[dim].nasce);
    printf("Luogo in cui sfocia: ");
    fflush(stdin);
    gets(vett[dim].sfocia);
    
    return dim + 1;
}

int main( void ) {
    
    struct fiume tab_fiumi[MAX_FIUMI];
    int num_fiumi = 0;
    int comando;
    
    do {
        mostra_fiumi(tab_fiumi, num_fiumi);
        comando = menu();
        
        switch (comando) {
            case 1:
                if ((num_fiumi = carica_archivio(tab_fiumi)) == -1)
                    printf("Impossibile caricare l'archivio in memoria.\n");
                break;
            case 2:
                if (salva_archivio(tab_fiumi, num_fiumi) == -1)
                    printf("Impossibile salvare l'archivio su file.\n");
                break;
            case 3:
                num_fiumi = aggiungi_fiume(tab_fiumi, num_fiumi);
                break;
            case 4:
                if (num_fiumi > 0) num_fiumi--;
                break;
        }
    }
    while (comando > 0);
    
    return 0;

}