////////////////////////////////////////////////////////////////////////////////
// School of Computing, Universiti Teknologi Malaysia
// SECJ1013- Programming Technique I
// Semester 1, 2020/2021
// ASSIGNMENT III
// 11 Jan 2021
// Pair information 
// Name: Felicia Chin Hui Fen
//     : Mohd Firdaus Bin Zamri
// Matrics No: A20EC0037
//           : A20EC0080
// Section: 01
//
////////////////////////////////////////////////////////////////////////////////

#include<iostream>
#include<cstdlib>
#include<fstream>
#include<iomanip>
#include<limits>

using namespace std;

#define MAXSTREAM numeric_limits<streamsize>::max()

//------------------------------------------------------------------------------------
// Function : readFile  
// Purpose  : To read inputs from a file consisting of the list of patient's name along 
//            with their weights and heights of the patient.
// Parameters:
//           name	   :  the array to hold the list of patient's names read from the file
//           weight    :  the array to hold the list of weights
//           height    :  the array to hold the list of heights
//           count     :  the number of patients read
//------------------------------------------------------------------------------------

// Task 1: Complete the definition of function "readFile"          (10 marks)

void readFile(char name[][20], double weight[], double height[], int &count)
{
	char nm[20];   // patient's name
	double wgt;    // patient's weight
	double hgt;    // patient's height

	ifstream inputFile; 

	//  complete these lines to open the input file, check the input file whether it is exist or not and display the error message (input validation).
	inputFile.open("input.txt");
	
	if (! inputFile.is_open())
	{
		cout << "ERROR: Cannot open file! Terminating!\n";
		exit (1);
	}

	count = 0;
	while (inputFile.getline (nm, 20, '\t'))
	{

		inputFile >> wgt; 
		inputFile >> hgt; 
		inputFile.ignore(MAXSTREAM, '\n');  //ignore newline

		// complete these lines to store the read data into arrays accordingly and close the open file.
		for (int i =0; i < 20 ; i++)	
		name[count][i] = nm[i] ;
		
		weight [count] = wgt;
		height [count] = hgt;
	

		count++; //increament of counter
	}
		
	inputFile.close(); // close the input file
	
}

//------------------------------------------------------------------------------------
// Function  : convertMeter
// Purpose   : To convert centimeter to meter
//
// Parameters:
//         	a  - the input array
//			b  - the array that holds the results of meter
//          n  - the size of array 
//
//------------------------------------------------------------------------------------

// Task 2 : Complete the definition of function convertMeter  (5 marks)

void convertMeter(double a[], double b[], int n)
{
	for (int i = 0; i<n; i++)
	{
		b[i] = a[i] / 100;
	}

}

//------------------------------------------------------------------------------------
// Function  : calculateBMI
// Purpose   : to calculate the elements of arrays x and y correspondingly using BMI formula, and puts the result into another array, z.
//             BMI formula: weight(kg) / (height(m) * height (m))
// Parameters:
//      		x,y  - the input arrays
//              z    - the array that holds the results of the calculation.
//------------------------------------------------------------------------------------
// Task 3 : Complete the defintion of function calculateBMI  (7 marks)

void calculateBMI(const double x[], const double y[], double z[], int n)
{
	
	for (int i = 0; i < n; i++)
	{
		z[i] = x[i] / (y[i] * y[i]);
	}

}

//------------------------------------------------------------------------------------
// Function  : average
// Purpose   : To calculate the average elements of an array.
//
// Parameters:
//         	a  - the array
//          n  - the size of array 
//
//  Return value:  the average of all the elements of the array
//------------------------------------------------------------------------------------

// Task 4 : Complete the definition of function average  (8 marks)

double average(const double a[], int n)
{
	double sum = 0, ave = 0; 
	
	for (int i=0; i < n; i++)
	{
		sum += a[i];
	}

	ave += (sum / n);
	
	return ave;
	
}



int main()
{
	char pName[10][20];  	// The list (array) of patient's names
	double pWeight[10]; 	// The list (array) of patient's weights
	double pHeight[10];  	// The list (array) of patient's heights in cm
	double pMeter[10];  	// The list (array) of patient's heights in meter  
	double pBMI[10]; 		// The list of BMI, i.e.,weight / (height x height)
	double aveWgt;    		// Total average weight for all patients
	int n;   				// The number of patients	

	
	
	// Task 5: Using all the functions defined above, write a function call, 
	//(a) to read file from the input file, (b) to convert meter, (c) to calculate BMI and (d) to calculate average of weights. (9 mark)
	readFile (pName,  pWeight,  pHeight, n);
	convertMeter(pHeight,  pMeter, n);
	calculateBMI(pWeight, pMeter,  pBMI, n);
	aveWgt = average(pWeight, n);
	

	
    // Task 6: Print the list of patient's names along with their weight, height in meter and the calculated BMI to the output file (output.txt). (16 marks)
	// You should open and close the output file, and use proper formatting output.

	cout << "Writing to the output file... " << endl << endl;
	
	ofstream outputFile;

	outputFile.open("output.txt"); //open the output file

	outputFile << left << setw(20) << "Name"
	<< setw(15) << "Weight(kg)"
	<< setw(15) << "Height(m)"
	<< setw(10) << "BMI" << endl << endl;;

	
	int num = 0; // counter
	while (num != n) //the loop end when num equal to number of patient, 6
	{	
		outputFile << left;
		outputFile << setw(20) << pName[num];
		outputFile << fixed << setprecision(2);
		outputFile << left << setw(15) << pWeight[num]
		<< setw(15) << pMeter[num] 
		<< setw(15) << pBMI[num] << endl;
	
		num ++; //increament of counter 
		
	}

	outputFile.close(); //close the output file
	

    // Task 7: Print the number of patients and the average weight of all patients to the program screen. (5 marks).
	cout << showpoint << fixed << setprecision (1);
	cout << "Number of patients : " << n << endl;
	cout << "Average weight     : " << aveWgt << endl;


	return 0;
}


//************************************************************************************************************
// Reflection by Felicia Chin Hui Fen                                                                        *
//																										     *
// First of all, I would like to thank my member, Mohd Firdaus Bin Zamri that assist me in this assignment.  *
// Furthermore, I would also like to thank my lecturer, Dr. Zuraini Binti Ali Shah for her patience in       *
// teaching us in this course. Through this assignment, I learnt how to format the input and output data.    *
// Moreover, I knew how to use file operation to open and close the file. I am able to connect the use of    *
// array that I learnt in previous chapter in this assignment.  I hope I would able to learn more new things *
// in this course and pass my exam with flying kite.                                                         *         
//************************************************************************************************************
