//
//
//  babysit.cc
//
//      AUTHOR: Russell Lowke
//         T.F: Francis Crick
//  CSCIE-s111: Unit Two, Main - question 11 [worth 9pts],  7/3/2002
//
//
// Description: Computes how much the babysitter should get paid
//
//       Usage: When prompted, key in start hour, start minute, end hour, end minute 
//
//      Method: five main methods used
//		        initialize() - init properties in object
//		    getStartAndEnd() - get the start and end times from user
//		       convertTime() - convert time to 24 hour
//		       calcPayment() - calculate payment
//		   printSittersPay() - print pay amount
//
//                ...for user input a special function is used
//              getInt()       - reads an integer from keyboard, checking for errors
//
		

#include <iostream>
#include <iomanip>

// constants for sitter payment brackets
const double  SIX_TIL_EIGHT = 2.40,
              EIGHT_TIL_MID = 2.10,
              PAST_MIDNIGHT = 2.90;


//
//  reads an integer from the keyboard,
//  uses error checking to ensure value is between minValue and maxValue
//
int getInt(char askStr[], int minValue, int maxValue)
{
	int mVar;
	
	while (1) { // ...while TRUE
	
		// ask query
		cout << askStr;
		cin >> mVar;
		
		if ( mVar >= minValue && mVar <= maxValue )
			break;  // input OK, break from loop
		else {
			cout << "Bad input: please enter a value between "
			     << minValue << " and " << maxValue << endl;
			cin.clear();
			cin.ignore(80, '\n');
		}
	}
	
	return mVar;
}

                     
class Babysitter
{
    private:
    
           int startHour,
               startMinute,
               endHour,
               endMinute,
               convEndHour,    // converted endHour
		       convStartHour;  // converted startHour
		       
        double moneyEarned,    // sum of money eraned
		       minRate;        // per minute rate

		       
    public:
    
    	  void initialize();
          void getStartAndEnd();
          void calcPayment();
          void convertTime();
		  void printSittersPay();
};


//
// initialize Babysitter properties
//
void Babysitter :: initialize()
{
    startHour     = 0;
    startMinute   = 0;
    endHour       = 0;
    endMinute     = 0;
    convEndHour   = 0;    // converted endHour
	convStartHour = 0;    // converted startHour 
    moneyEarned   = 0.0;  // sum of money eraned
	minRate       = 0.0;  // per minute rate   
}


//
//  get start and end times
//
void Babysitter :: getStartAndEnd()
{
	startHour   = getInt("At what HOUR did the baby-sitter start work? ", 6, 11);
    startMinute = getInt("At what MINUTE did the baby-sitter start work? ", 0, 59);

  	endHour     = getInt("At what HOUR did the baby-sitter finish working? ", 1, 12);
    endMinute   = getInt("At what MINUTE did the baby-sitter finish working? ", 0, 59);  
}


//
// Calculate payment
//
void Babysitter :: calcPayment()
{
	// calac hours at - six till eight rate
	for (int i = 6; i < 8; i++) {
		if (convStartHour <= i &&
			convEndHour-1 >= i)
		moneyEarned = moneyEarned + SIX_TIL_EIGHT;
	}
   
	// remove minutes lost starting past the hour
	if (convStartHour >= 6 && convStartHour <  8) {
		minRate     = SIX_TIL_EIGHT / 60.0;
		moneyEarned = moneyEarned - minRate * startMinute;
	}
   
	// add minutes gained ending past the hour
	if (convEndHour >= 6 && convEndHour <  8) {
		minRate     = SIX_TIL_EIGHT / 60.0;
		moneyEarned = moneyEarned + minRate * endMinute;
	}
   
	// calac hours at - eight till midnight
	for (int i = 8; i < 12; i++) {
		if (convStartHour <= i && convEndHour-1 >= i)
			moneyEarned = moneyEarned + EIGHT_TIL_MID;
	}
   
	// remove minutes lost starting past the hour
	if (convStartHour >= 8  && convStartHour <  12) {
		minRate     = EIGHT_TIL_MID / 60.0;
		moneyEarned = moneyEarned - minRate * startMinute;
	}
   
	// add minutes gained ending past the hour
	if (convEndHour >= 8 && convEndHour <  12) {
		minRate     = EIGHT_TIL_MID / 60.0;
		moneyEarned = moneyEarned + minRate * endMinute;
	}
   
	// calac hours at - past midnight
	for (int i = 12; i < 19; i++) {
		if (convStartHour <= i && convEndHour-1 >= i)
			moneyEarned = moneyEarned + PAST_MIDNIGHT;
	}
   
	// remove minutes lost starting past the hour
	if (convStartHour >= 12 && convStartHour <  19) {
		minRate     = PAST_MIDNIGHT / 60.0;
		moneyEarned = moneyEarned - minRate * startMinute;
	}
   
	// add minutes gained ending past the hour
	if (convEndHour >= 12 && convEndHour <  19) {
		minRate     = PAST_MIDNIGHT / 60.0;
		moneyEarned = moneyEarned + minRate * endMinute;
	}
}


//
//  convert time to a 'psudo' 24hour clock
//
void Babysitter :: convertTime()
{
    // convert endTime to psudo 24Hour time
	// 1 AM will be called 13, 2 AM will be called 14, etc
	convEndHour = endHour;
	if (endHour <= 6)
		convEndHour = convEndHour + 12;
	  
	// convert startHour to psudo 24Hour time
	// 1 AM will be called 13, 2 AM will be called 14, etc
	convStartHour = startHour;
	if (startHour < 6)
		convStartHour = convStartHour + 12;  
}


void Babysitter :: printSittersPay()
{
	cout << endl << endl << "Babysitters pay is: $";
	
	// set cout parameters
	cout.setf(ios::fixed);
	cout.setf(ios::showpoint);
	cout.precision(2);
	
	cout << moneyEarned;
	cout << endl;
}


void main()
{		       
	char tryAgain = 'Y';  // varible for "try again"
   
	Babysitter russ;

	// main loop
	do {
	  
		// program
		russ.initialize();       // init properties
		russ.getStartAndEnd();   // ask user start and end time
		russ.convertTime();      // convert time to 24 hour
		russ.calcPayment();      // calculate payment
		russ.printSittersPay();  // print the end pay
	   
		// Try again?
		cout << endl << "Want to try again? (y/n) ";
		cin >> tryAgain;
  
	} while (tryAgain == 'Y' || tryAgain == 'y');   
}
