//File       :Long_program_assignment1.cpp
//Author     :Andre Long
//Due        :July 14, 2005
//Description:The purpose of this program is to demostrate a C program using Sequence Selection and Iteration
//            and to output the results to a report file using functions (modular design)

#include<iostream>
#include<iomanip>
#include<fstream>
#include<cstdlib>
#include<string>
#define TAXRATE .15;
using namespace std;

string getFullName();                    //Input functions
float getPay();
float getTotalHours(float* TotalHours);

float processRegularPay(float* TotalHours, float* payrate);       //Processing functions
float processOvertimePay(float* TotalHours, float* payrate);
float processGrossPay(float* TotalHours, float* payrate);
float processTaxAmount(float* TotalHours, float* payrate);
float processNetPay(float* TotalHours, float* payrate);

void display(int numberOfEmployees, string* fullnames, float* payrate, float* TotalHours,
			 float* grossPay, float* taxAmount, float* netPay);               //Output functions
void reportFile(fstream &, int numberOfEmployees, string* fullnames, float* payrate, float* TotalHours,
			 float* grossPay, float* taxAmount, float* netPay);

void sortedDisplay(fstream &reportOut, int numberOfEmployees, string* fullnames, float* payrate, float* TotalHours,
			 float* grossPay, float* taxAmount, float* netPay);


int main(void)
{
  
   char userAnswer;
   int numberOfEmployees;
   string* fullnames;
   float* payrate;
   float* TotalHours;
   float* regularPay;
   float* overtimePay;
   float* grossPay;
   float* taxAmount;
   float* netPay;


   fstream reportOut("Payroll Report.doc", ios::out | ios::app);
   if(!reportOut)
   {
      cout<<"Error with report"<<"\n";
	  exit(0);
   }

   cout<<"How many employees are there in this company? ";
   cin>>numberOfEmployees;

   fullnames = new string[numberOfEmployees];
   payrate = new float[numberOfEmployees];
   TotalHours = new float[numberOfEmployees];
   regularPay = new float[numberOfEmployees];
   overtimePay = new float[numberOfEmployees];
   grossPay = new float[numberOfEmployees];
   taxAmount = new float[numberOfEmployees];
   netPay = new float[numberOfEmployees];

   do
   {
	   for(int i=0; i<numberOfEmployees; i++)
	   {
			fullnames[i] = getFullName();
			payrate[i] = getPay();
			TotalHours[i] = getTotalHours(TotalHours);
			regularPay[i] = processRegularPay(&TotalHours[i], &payrate[i]);
			overtimePay[i] = processOvertimePay(&TotalHours[i], &payrate[i]);
			grossPay[i] = processGrossPay(&TotalHours[i], &payrate[i]);
			taxAmount[i] = processTaxAmount(&TotalHours[i], &payrate[i]);
			netPay[i] = processNetPay(&TotalHours[i], &payrate[i]);
	   }
      display(numberOfEmployees, fullnames, payrate, TotalHours, grossPay, taxAmount, netPay);
	  reportFile(reportOut, numberOfEmployees, fullnames, payrate, TotalHours, grossPay, taxAmount, netPay);
	  sortedDisplay(reportOut, numberOfEmployees, fullnames, payrate, TotalHours, grossPay, taxAmount, netPay);
      
	  cout<<"\n";
	  cout<<"Would you like to renter employees for a different company?"<<"\n";
	  cout<<"Y = yes or y = yes"<<"\n";
	  cin>>userAnswer;
   }
   while (userAnswer =='Y' || userAnswer =='y' );
   reportOut.close();
   return 0;

}

string getFullName()
{
   string first;
   string last;
   string punctuation = ", ";
   string FullName;

   cout<<"\n";
   cout<<"Enter employee's first name ";
   cin>>first;
   cout<<"\n";
   cout<<"Enter employee's last name ";
   cin>>last;

   FullName = last + punctuation + first;
   return FullName;
}
float getPay()
{
   float moneyValue;
   cout<<"Enter the pay rate for this employee ";
   cin>>moneyValue;
   return moneyValue;
}
float getTotalHours(float* TotalHours)
{
   float allHours;
   cout<<"Enter the total number of hours worked for this employee ";
   cin>>allHours;
   return allHours;
}

float processRegularPay(float* TotalHours, float* payrate)
{
   float regular_pay;
   if(*TotalHours<=40)
   {
      regular_pay = *TotalHours *( *payrate );
      return regular_pay;
   }
   else
   {
	   regular_pay = 40 *( *payrate );
	   return regular_pay;
   }
}
float processOvertimePay(float* TotalHours, float* payrate)
{
   float overtime_pay;
   overtime_pay = ( *TotalHours - 40 ) * (1.5 * (*payrate)  );
   return overtime_pay;
}
float processGrossPay(float* TotalHours, float* payrate)
{
   float gross_pay;
   if(*TotalHours > 40)
   { gross_pay = processRegularPay(TotalHours, payrate) + processOvertimePay(TotalHours, payrate); }
   else
   { gross_pay = processRegularPay(TotalHours, payrate) + 0; }
   return gross_pay;
}
float processTaxAmount(float* TotalHours, float* payrate)
{
   float tax_amount;
   tax_amount = processGrossPay(TotalHours,  payrate) * TAXRATE;
   return tax_amount;
}
float processNetPay(float* TotalHours, float* payrate)
{
   float net_pay;
   net_pay = (processGrossPay(TotalHours, payrate) - processTaxAmount(TotalHours, payrate) );
   return net_pay;
}

void display(int numberOfEmployees, string* fullnames, float* payrate, float* TotalHours,
			 float* grossPay, float* taxAmount, float* netPay )
{
cout<<"\n";
cout<<right<<"Employee"<<setw(15)<<"Pay"<<setw(15)<<"Hours"<<setw(15)<<"Gross"<<setw(10)<<"Tax"<<setw(10)<<"Net"<<"\n";
cout<<"Name"<<setw(20)<<"Rate"<<setw(15)<<"Worked"<<setw(12)<<"Pay"<<setw(15)<<"Amount"<<setw(7)<<"Pay"<<"\n";
cout<<"========"<<setw(16)<<"===="<<setw(15)<<"======"<<setw(14)<<"====="<<setw(13)<<"======"<<setw(10)<<"======"<<"\n";
cout<<"\n";
for(int i=0; i<numberOfEmployees; i++)
{
   cout<<left<<setw(20)<<fullnames[i]<<setprecision(2)<<fixed<<setw(13)<<payrate[i]<<setw(15)<<TotalHours[i]<<setw(12)<<grossPay[i]
       <<setw(10)<<taxAmount[i]<<setw(10)<<netPay[i]<<"\n";
}
}
void reportFile(fstream &reportOut, int numberOfEmployees, string* fullnames, float* payrate, float* TotalHours,
			 float* grossPay, float* taxAmount, float* netPay)
{
    reportOut<<"\n";
	reportOut<<right<<"Employee"<<setw(15)<<"Pay"<<setw(15)<<"Hours"<<setw(15)<<"Gross"<<setw(10)<<"Tax"<<setw(10)<<"Net"<<"\n";
	reportOut<<"Name"<<setw(20)<<"Rate"<<setw(15)<<"Worked"<<setw(12)<<"Pay"<<setw(15)<<"Amount"<<setw(7)<<"Pay"<<"\n";
	reportOut<<"========"<<setw(16)<<"===="<<setw(15)<<"======"<<setw(14)<<"====="<<setw(13)<<"======"<<setw(10)<<"======"<<"\n";
	reportOut<<"\n";
	for(int i=0; i<numberOfEmployees; i++)
	{
	reportOut<<left<<setw(20)<<fullnames[i]<<setprecision(2)<<fixed<<setw(13)<<payrate[i]<<setw(15)<<TotalHours[i]<<setw(12)<<grossPay[i]
		<<setw(10)<<taxAmount[i]<<setw(10)<<netPay[i]<<"\n";
	}
}

//This sorting function comes from the textbook "Starting Out With C++" by Tony Gaddis page 506
void sortedDisplay(fstream &reportOut, int numberOfEmployees, string* fullnames, float* payrate, 
				   float* TotalHours,  float* grossPay, float* taxAmount, float* netPay)
{
   cout<<"\n";
   cout<<"\n";
   int startScan;
   int maxIndex;
   string maxValue;
   string tempFullname;
   float tempPayrate;
   float tempTotalHours;
   float tempGrosspay;
   float tempTaxamount;
   float tempNetpay;

   for(startScan = 0; startScan < (numberOfEmployees -1); startScan++)
   {
      maxIndex = startScan;
      maxValue = fullnames[startScan];
	  tempPayrate = payrate[startScan];
	  tempTotalHours = TotalHours[startScan];
	  tempGrosspay = grossPay[startScan];
	  tempTaxamount = taxAmount[startScan];
	  tempNetpay = netPay[startScan];
	  for(int index = startScan + 1; index < numberOfEmployees; index++)
	  {
         if(fullnames[index] < maxValue)
		 {
            maxValue = fullnames[index];
			tempPayrate = payrate[index];
			tempTotalHours = TotalHours[index];
			tempGrosspay = grossPay[index];
			tempTaxamount = taxAmount[index];
			tempNetpay = netPay[index];
			maxIndex = index;
		 }

	  }//end 2nd for loop
	  fullnames[maxIndex] = fullnames[startScan];
	  payrate[maxIndex] = payrate[startScan];
	  TotalHours[maxIndex] = TotalHours[startScan];
	  grossPay[maxIndex] = grossPay[startScan];
	  taxAmount[maxIndex] = taxAmount[startScan];
	  netPay[maxIndex] = netPay[startScan];

	  fullnames[startScan] = maxValue;
	  payrate[startScan] = tempPayrate;
	  TotalHours[startScan] = tempTotalHours;
	  grossPay[startScan] = tempGrosspay;
	  taxAmount[startScan] = tempTaxamount;
	  netPay[startScan] = tempNetpay;
   }//end 1st for loop

cout<<"\n";
cout<<"                      Sorted        Payroll          List "<<"\n";
display(numberOfEmployees, fullnames, payrate, TotalHours, grossPay, taxAmount, netPay);
reportOut<<"\n";
reportOut<<"                      Sorted        Payroll          List "<<"\n";
reportFile(reportOut, numberOfEmployees, fullnames, payrate, TotalHours, grossPay, taxAmount, netPay);
	
	

}//end function