/*
Nome: Mario
Cognome: Montanari
Classe: 3AIN
Data: 09/05/2025

Definire una struttura di dati chiamata Persona, che contiene tre campi:
   - Nome (di tipo array di 20 caratteri);
   - Cognome (di tipo array di 20 caratteri);
   - Reddito (di tipo intero).

1) Visualizzare la dimensione del tipo Persona (aumentare di 1 la dimensione
   del campo nome e ricontrollare la dimensione del tipo Persona);
2) Creare una funzione per assegnare valore ai campi di una persona e
   scriverla su file binario;
3) Controllare il file con hexed.it;
4) Creare una funzione che legga da file e inserisca nei campi di una Persona;
5) Scrivere su file un array di 5 persone;
6) Leggere da file 5 persone e memorizzarle su un array
7) Copiare le struct dal file binario a un file di testo organizzando un record per riga

*/

#include <iostream>
#include <cstdlib>
#include <ctime>

#define SIZE 20

#define MAX_PERSONA 3

#define MIN_ALPHA 65
#define MAX_ALPHA 90

#define MIN_REDDITO 90000
#define MAX_REDDITO 15000

#define MIN_NOME 2
#define MAX_NOME 10

#define MIN_COGNOME 4
#define MAX_COGNOME 14

#define MAX_LINE 1000+1

using namespace std;

typedef struct {
	char nome[SIZE];
	char cognome[SIZE];
	int reddito;
} Persona;

typedef struct {
	char nome_prova[21];
	char cognome_prova[20];
	int reddito_prova;
} Persona_prova;

void riempiCampi(Persona persona[MAX_PERSONA], FILE * file) {
	for (int i = 0; i < MAX_PERSONA; i++) {
			
		char nome[SIZE];
		int casual = rand() % (MAX_NOME - MIN_NOME + 1) + MIN_NOME;
		for (int j = 0; j < casual; j++) {
			nome[j] = rand() % (MAX_ALPHA - MIN_ALPHA + 1) + MIN_ALPHA;
		}
		nome[casual] = '\0';
		strcpy(persona[i].nome, nome);
				
		char cognome[SIZE];
		casual = rand() % (MAX_COGNOME - MIN_COGNOME + 1) + MIN_COGNOME;
		for (int j = 0; j < casual; j++) {
			cognome[j] = rand() % (MAX_ALPHA - MIN_ALPHA + 1) + MIN_ALPHA;
		}
		cognome[casual] = '\0';
		strcpy(persona[i].cognome, cognome);
				
		int reddito = rand() % (MAX_REDDITO - MIN_REDDITO + 1) + MIN_REDDITO;
		persona[i].reddito = reddito;
				
		fwrite(&persona[i], sizeof(Persona), 1, file);
	}
}

void leggiCampi(Persona persona[MAX_PERSONA], FILE * file) {
	for (int i = 0; i < MAX_PERSONA; i++) {
		fread(&persona[i], sizeof(Persona), 1, file);
		
		cout << "Persona " << i + 1 << ":" << endl;
		cout << "   Nome: " << persona[i].nome << endl;
		cout << "   Cognome: " << persona[i].cognome << endl;
		cout << "   Reddito: " << persona[i].reddito << endl << endl;
	}
}

int main(void) {
	srand(time(NULL));
	
	cout << "sizeof(Persona): " << sizeof(Persona) << endl;
	cout << "sizeof(Persona_prova): " << sizeof(Persona_prova) << endl << endl;
	
	FILE * file_scritto = fopen("esercizio_3.bin", "wb");
	
	if (file_scritto != NULL) {
		Persona persona[MAX_PERSONA];
		
		riempiCampi(persona, file_scritto);
		
		fclose(file_scritto);
	} else {
		perror("Error");
	}
	
	FILE * file_letto = fopen("esercizio_3.bin", "rb");
	
	if (file_letto != NULL) {
		Persona persona[MAX_PERSONA];
		
		leggiCampi(persona, file_letto);
		
		FILE * file_copia = fopen("esercizio_3.txt", "wt");
				
		if (file_copia != NULL) {
			rewind(file_letto);
			
			Persona copia;
			
			while (fread(&copia, sizeof(Persona), 1, file_letto) == 1) {
				fprintf(file_copia, "%s %s %d\n", copia.nome, copia.cognome, copia.reddito);
			}
			
			fclose(file_copia);
		} else {
			perror("Error (destination)");
		}
		
		fclose(file_letto);
	} else {
		perror("Error (source)");
	}
	
	return 0;
}