//MUHAMMAD NAZRI IZZAT BIN HAMDAN A20EC0216
//RAJA MUHAMMAD HAFIZ BIN RAJA ALAUDIN SHAH A20EC0223
//1.23.2021
// Fahrenheit_to_celcius_converter_project.cpp : This file contains the 'main' function. Program execution begins and ends there.
//

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>

using namespace std;




//This function reads in a list of numbers from a text file and stores them into a onedimensional
//array.It receives the following parameters :
//a.The name of the text file to be read from
//b.An array to store the list of numbers read
//c.A variable to store the number of data read

void readFile(string text_file_name, double* fahrenheit_array, int fahrenheit_array_length) {

     // Create a text string, which is used to output the text file
     string myText;
     int counter = 0;

     // Read from the text file
     ifstream MyReadFile(text_file_name);

     if (MyReadFile.is_open())
     {
          // Use a while loop together with the getline() function to read the file line by line
          while (getline(MyReadFile, myText))
          {
               //read a line in string and convert to double, then store in array
               fahrenheit_array[counter] = std::stod(myText);
               counter ++;
          }

          // Close the file
          MyReadFile.close();
     }

     else cout << "Unable to open file";

     //cout << "count" << *count << endl;

     MyReadFile.close();
}


//This function computes the values of C. It receives the following parameters:
//a.An array that contains data F
//b.An array to store the calculated values of C
//c.The number of data

void computeC(double* fahrenheit_array, double* celcius_array, int fahrenheit_array_length) {

     //C = 5/9 x (F - 32)

     for (int i = 0; i < fahrenheit_array_length; i++)
          celcius_array[i] = 5.0 / 9.0 * (fahrenheit_array[i] - 32);

}


//This function computes the average of a list of numbers stored in an array.

double average(double* celcius_array , double fahrenheit_array_length) {

     double sum = 0.0;

     for (int i = 0; i < fahrenheit_array_length; i++)
          sum += celcius_array[i];


     return sum/fahrenheit_array_length;
}

//This function determines either temperature (C) is high or medium or low. This
//function will return ‘H’ if C ≥ 35, ‘M’ if C < 35 and C ≥ 20, and ‘L’ if C < 20.

char grade(double celcius) {

     char grade = 'X';
     if (celcius >= 35.0)
          grade = 'H';
     else if (celcius >= 20.0 && celcius < 35.0)
          grade = 'M';
     else if (celcius < 20.0)
          grade = 'L';

     return grade;
}


//This function prints the output file as in Figure 7. It receives the following parameters:
//a.An array that contains data F
//b.An array that contains data C
//c.The number of data

void writeFile(double* fahrenheit_array, double* celcius_array, int fahrenheit_array_length) {

     // Create a text file
     ofstream MyWriteFile("Fahrenheit_to_celcius_converter_output.txt");

     // Write to the file
     MyWriteFile << setw(15) << "C(Celcius)" << setw(15) << "F (Farenheit)" << setw(15) << "Description" << "\n";
     MyWriteFile << setw(15) << "==========" << setw(15) << "=============" << setw(15) << "===========" << "\n";

     for (int i = 0; i < fahrenheit_array_length; i++)
     {
         MyWriteFile << setw(15) << celcius_array[i]<< setw(15) << fahrenheit_array[i] << setw(15) << grade(celcius_array[i]) << "\n";
     }

     // Close the file
     MyWriteFile.close();

}


//For printing summary output onto the screen

void printSummary(double Average , double H_grade_count , double M_grade_count , double L_grade_count) {

     cout << "Average of the temperature : " << Average << endl;
     cout << "Number of high temperature : " << H_grade_count << endl;
     cout << "Number of medium temperature : " << M_grade_count << endl;
     cout << "Number of low temperature : " << L_grade_count << endl;

}

int fahrenheit_arrayLength() {

     // Create a text string, which is used to output the text file
     string myText;
     int count = 0;

     // Read from the text file
     ifstream MyReadFile("Fahrenheit_to_celcius_converter_input.txt");

     if (MyReadFile.is_open())
     {
          // Use a while loop together with the getline() function to read the file line by line
          while (getline(MyReadFile, myText))
          {
               //read a line and add in count
               count++;
          }

          // Close the file
          MyReadFile.close();
     }

     else cout << "Unable to open file";

     MyReadFile.close();

     return count;
}


int main()
{
     //It contains the actual number of lines in the file
     int fahrenheit_array_length = 0;

     //for average
     double Average = 0.0;

     //for counting the grades
     int H_grade_count = 0;
     int M_grade_count = 0;
     int L_grade_count = 0;

     fahrenheit_array_length = fahrenheit_arrayLength();

     double* fahrenheit_array = new double[fahrenheit_array_length];
     double* celcius_array = new double[fahrenheit_array_length];


     //initialize with 0.0
     for (int i = 0; i < fahrenheit_array_length; i++)
     {
          fahrenheit_array[i] = 0.0;
          celcius_array[i] = 0.0;
     }

     //read the file and fill the fahrenheit_array
     readFile("Fahrenheit_to_celcius_converter_input.txt", fahrenheit_array, fahrenheit_array_length);

     //read the file and fill the celcius_array
     computeC(fahrenheit_array, celcius_array, fahrenheit_array_length);

     //finds the verage of celcius_array
     Average = average(celcius_array , fahrenheit_array_length);

     for (int i = 0; i < fahrenheit_array_length; i++)
     {
          char Grade = grade(celcius_array[i]);

          if   (Grade == 'H')
               H_grade_count++;
          else if (Grade == 'M')
               M_grade_count++;
          else if (Grade == 'L')
               L_grade_count++;
     }

     //print the summary on the console screen
     printSummary(Average , H_grade_count , M_grade_count , L_grade_count);

     //for writin into the file
     writeFile(fahrenheit_array, celcius_array, fahrenheit_array_length);

     return 0;
}
