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

void usage(char *);
unsigned int validData(float, float, unsigned int);
void writeData(float, float, unsigned int, FILE*);

int
main(int argc, char **argv)
{
	/* dichiarazione, inizializzazione variabili */
	float d_ultimo, d_primo;
	unsigned int d_seq_att = 0;
	unsigned int invalid_data = 0;
	unsigned int misure_errate = 0;

	FILE *inDatafp;	/* file di dati in input del rilevatore e relativa estensione */
	char * inFilename;
	FILE *outDatafp;	/* file di output dei dati corretti e relativa estensione */
	char * outFilename;
	#define OUTPUT_EXT	".WOK"
	#define INPUT_EXT	".WD"
	#define EXTLEN 4

	/* il programma richiede il nome di un file sulla riga di comando */
	if (argc < 2) {
		usage(argv[0]);
		exit(EXIT_FAILURE);
	} else {
		if ((inFilename = (char *)malloc(strlen(argv[1] + EXTLEN + 1 + 2)))  != NULL) {

			(void)strcat(inFilename, argv[1]);
			(void)strcat(inFilename, INPUT_EXT);
		} else {
			printf("Impossibile allocare memoria\n");
			exit(EXIT_FAILURE);
		}
		
		if ((outFilename = (char *)malloc(strlen(argv[1] + EXTLEN + 1 + 2))) != NULL) {
			(void)strcat(outFilename, argv[1]);
			(void)strcat(outFilename, OUTPUT_EXT);
		} else {
			printf("Impossibile allocare memoria\n");
			exit(EXIT_FAILURE);
		}

	}

	/* apertura dei file di lavoro */
	if ((inDatafp = fopen(inFilename, "r")) == NULL) {
		printf("Errore nell'apertura del file: %s\n", inFilename);
		exit(EXIT_FAILURE);
	}
	
	if ((outDatafp = fopen(outFilename, "w")) == NULL) {
		printf("Errore nella creazione del file: %s\n", outFilename);
		exit(EXIT_FAILURE);
	}

	/* primo dato sempre corretto */
	fscanf(inDatafp, "%f", &d_primo);
	d_ultimo = d_primo;
	
	/* elabora tutti i valori in input */
	while (!feof(inDatafp)) {
		fscanf(inDatafp, "%f", &d_primo);

		if (validData(d_ultimo, d_primo, d_seq_att)) {
			writeData(d_ultimo, d_primo, d_seq_att, outDatafp);
			d_seq_att = 0;
			invalid_data = 0;
			d_ultimo = d_primo;

		} else {
			invalid_data++;
			d_seq_att++;
			misure_errate++;
		}
	}

	if (invalid_data) /* l'ultimo dato letto non era valido */
		writeData(d_ultimo, d_ultimo, d_seq_att, outDatafp);

	/* libera la memoria allocata */
	free(inFilename);
	free(outFilename);

	/* chiude i file */
	fclose(inDatafp);
	fclose(outDatafp);
	
	printf("Interpolate %u misure non attendibili\n", misure_errate);

	return 0;
}

void usage(char *nomeprg)
{

	printf("usage: %s <nome_file>\n", nomeprg);
}

unsigned int validData(float d_u, float d_c, unsigned int d_sa)
{

	float percentage = d_u /100.0 * (5* (d_sa + 1));
	
	if (abs(d_u - d_c) < percentage)
		return 1;
	else
		return 0;
}

void writeData(float d_u, float d_p, unsigned int d_sa, FILE *f)
{
	float d_interp;
	unsigned int i;
	
	fprintf(f, "%.3f\n", d_u);
	
	if (d_sa != 0) {
	    for (i = 1; i <= d_sa ; i++) {
		d_interp = d_u + (((i * (d_p - d_u)) / (d_sa + 1))) * 1.0;

		fprintf(f, "%.3f\n", d_interp);
	    }
	}

}
