////////////////////////////////////////////////////////////////////////////////
// School of Computing, Universiti Teknologi Malaysia
// SECJ1013- Programming Technique I
// Semester 1, 2020/2021
// ASSIGNMENT III
// 11 Jan 2021
// Pair information 
// Name: Muhammad Aiman Bin Abdul Razak
// Matrics No: A20EC0082
// Section: 01
//
// Name: Muhammad Aiman Bin Abdul Razak
// Matrics No: A20EC0082
// Section: 01

// Name: Heong Yi Qing
// Matrics No: A20EC0043
// Section: 01

// Name: Chong Kah Wei
// Matrics No: A20EC0027
// 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"); //open the input file
	
	if (inputFile.fail()) //check whether the input file exist or not
	{
		cout<<"Error opening the file! Ending..."; //if input file doesn't exist, display error message
		exit(EXIT_FAILURE); // and end the program
	} 

	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++)    //read the name into array
		    name[count][i]=nm[i];
		
		weight[count]=wgt;         //read weight into array 
		height[count]=hgt;         //read height into array
		
		count++;                   
	}
	
	inputFile.close();             //close 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++)        //convert height from cm to m from array using loop
	{
		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++)        //calculate BMI from array using loop
	{
		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++)  //total up the weight
	{
		sum+=a[i];
	}
	
	ave=sum/n;              //calculate the average
	
	return ave;             //return value of average to the main function
}


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 output file
	
	outputFile<<"Name"<<setw(25)<<"Weight(kg)"<<setw(16)<<"Height(m)"<<setw(10)<<"BMI"<<endl<<endl; //set the desired format of each output to be displayed
	
	for (int i=0; i<n; i++) //display each output, using loop since it is array, set the format for output
	{
		outputFile<<setw(19)<<left<<pName[i];
		outputFile<<fixed<<setprecision(2);
		outputFile<<setw(17)<<left<<pWeight[i];
		outputFile<<setw(16)<<pMeter[i];
		outputFile<<pBMI[i]<<endl;
	}
	
	outputFile.close(); //close output file

    // Task 7: Print the number of patients and the average weight of all patients to the program screen. (5 marks).

    cout<<"Number of patients : "<<n<<endl; //print the number of patient which is n (pass address &count from the function)
    cout<<"Average weight     : "<<fixed<<setprecision(1)<<aveWgt;

	return 0;
}

/* --Reflection-- 
From this assignment, I have gained a better understanding in the topic Function, Input and Output, I/O File, Array and so on.
Since we have to use all our knowledge we learned from previous lesson, I have done a revision and some research 
to know more about the particular topics to accomplish this assignment with my group-mates. */


