/* incasso.c
 *
 * Ricerca e visualizzazione di un incasso giornaliero.
 */


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

#define MAX_INCASSI 1000
#define NOME_FILE "incassi.txt"

struct data {
    int giorno;
    int mese;
    int anno;
};

struct incasso {
    struct data data_incasso;
    float totale;
};

int leggi_incassi(char nome_file[], struct incasso vett[]) {
    FILE *fp;
    int dim = 0;
    
    if ((fp = fopen(nome_file, "r")) == NULL)
        return -1;

    while (fscanf(fp, "%d%d%d%f", &vett[dim].data_incasso.giorno, &vett[dim].data_incasso.mese,
        &vett[dim].data_incasso.anno, &vett[dim].totale) != EOF)
        
        dim++;
        
    fclose(fp);
    return dim;
}

bool data_valida(int g, int m, int a) {
    // Restituisce TRUE solo se i tre parametri di input rappresentano una data valida.
    
    int giorni_in_mese[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    
    // Per semplicita' si accettano solo anni compresi tra 1950 e 2050
    
    if (a < 1950 || a > 2050)
        return false; // Anno non valido
        
    if (m < 1 || m > 12)
        return false; // Mese non valido
        
    if (a % 4 == 0)
        giorni_in_mese[1] = 29; // Correzione del numero di giorni di febbraio
                                    // per gli anni bisestili

    if (g < 1 || g >giorni_in_mese[m-1])
        return false; // Giorno non valido
        
    return true;
}

int confronta_date(struct data d1, struct data d2) {
    
    // Funzione di confronto tra date rappresentate con numeri seriali
    // La funzione restituisce un numero intero:
    //
    // Negativo se d1 < d2
    // Uguale a zero se d1 = d2
    // Positivo se d1 > d2
    
    int seriale1, seriale2;
    
    seriale1 = d1.anno * 10000 + d1.mese * 100 + d1.giorno;
    seriale2 = d2.anno * 10000 + d2.mese * 100 + d2.giorno;
    
    return seriale1 - seriale2;
}

int ricerca_incasso(struct incasso vett[], int dim, int giorno, int mese, int anno) {
    int i_inf = 0;
    int i_sup = dim -1;
    int i_medio;
    struct data data_input; // Utile per la funzione di confronto tra date
    
    data_input.giorno = giorno;
    data_input.mese = mese;
    data_input.anno = anno;

    
    while (i_inf <= i_sup) {
        i_medio = (i_inf + i_sup) /2;
        int ris_confronto;
        
        ris_confronto = confronta_date(data_input, vett[i_medio].data_incasso);
        if (ris_confronto == 0)
            return i_medio;
        else if (ris_confronto < 0)
            i_sup = i_medio - 1;
        else
            i_inf = i_medio + 1;
    }

    return -1;
}

int main( void ) {
    struct incasso tab[MAX_INCASSI];
    int dim_tab;
    struct data d;
    int pos;
    
    dim_tab = leggi_incassi(NOME_FILE, tab);
    if (dim_tab < 0) {
        printf("Errore nell'elaborazione del file di input.\n");
        exit(1);
    }
    
    do {
        printf("Inserire giorno mese e anno dell'incasso da ricercare: ");
        scanf("%d%d%d", &d.giorno, &d.mese, &d.anno);
    }
    while (data_valida(d.giorno, d.mese, d.anno) == false);
    
    pos = ricerca_incasso(tab, dim_tab, d.giorno, d.mese, d.anno);
    
    if (pos < 0)
        printf("Nessun incasso registrato in questa data.\n");
    else
        printf("Incasso del %d/%d/%d: %.2f Euro\n", d.giorno, d.mese, d.anno, tab[pos].totale);

    return 0;
}