//
//
//  Time.cc
//
//      AUTHOR: Russell Lowke
//         T.F: Francis Crick
//  CSCIE-s111: Unit Five, Main - question 2 [worth 13pts],  7/18/2002
//
// Description: Invent an appropriate class to represent time of day
//				in hours (0 to 23), and minutes.  
//				"time" objects represent times during a single day.
//
//       Usage: executing will print a schedule, starting at 9:30 AM
//
//     Methods:
//         operator+   - add +'ve or -'ve int to time val
//        operator<<   - print time values intelligently
//           Time ()   - constructor for Time class
//           ~Time()   - destructor for Time class
//         setTime()   - set a time, hours, and minutes
//      addMinutes()   - add minutes to a Time
//
//   printSchedule()   - print a schedule for the period starting at time start,
//            main()   - print schedule, starting at 9:30 AM
//
//		 Notes: function ensureValues() is in lib  Utils.cc
//


#include "Time.h"								// include header


//
//   Time class -  class to represent time of day in hours (0 to 23), and minutes.
//
class Time
{
	private :
	
    		int pHours;							// in stream for file
        	int	pMinutes;
		
      public:
       
                 Time(int h, int m); 			// constructor
                 ~Time();						// destructor
        	void printTime();					// output time val
        	void setTime(int h, int m);			// set hour and minute
        	void addMinutes(int m);
        	
			//
			//  add to time val to +'ve or -'ve int
			//
			friend Time operator+ (Time mt, int mInt)
			{
				mt.addMinutes(mInt);
				
				return ( mt );
			}
			
			//
			//  add +'ve or -'ve int to time val
			//
			friend Time operator+ (int mInt, Time mt)
			{
				mt.addMinutes(mInt);
				
				return ( mt );
			}
			
            //
            //  print time values intelligently
            //
      		friend ostream& operator<< (ostream& os, Time mt)
			{ 
				bool isAm;
				int mHour = mt.pHours;				// copy of hours

				if (mHour > 11) {					// Am or PM?
					isAm = false;
				} else {
					isAm = true;
				}
			
				if (mHour > 12) {					// past NOON?
					mHour -= 12;
				}

				if (mHour == 0 &&
				    mt.pMinutes == 0) {				// exception MIDNIGHT?
					os << "MIDNIGHT";
				} else if (mHour == 12 && 
						   mt.pMinutes == 0) {		// exception NOON?
					os << "NOON";
				} else {							// normal case.

					if (mHour == 0) {				// no zeroth hour
						mHour = 12;
					}

					os << mHour << ":";				// print hour
					
					if (mt.pMinutes < 10) {
						os << "0";					// extra 0
					}
					
					os << mt.pMinutes;				// print minutes
					
					if (isAm) {						// Am v PM
						os << " AM";
					} else {
						os << " PM";
					}
				}

				os << endl;

				return os;
			}
};


//
//  constructor for Time class
//
Time :: Time (int h, int m)
{
	setTime(h, m);
}


//
//  destructor for Time class
//  
Time :: ~Time()
{
}


//
//  set a time, hours, and minutes
//
void Time :: setTime(int h, int m)
{
	ensureValues("hours"  , h, 0, 23);			// ensure valid vars
	ensureValues("minutes", m, 0, 59);
	
	pHours   = h;
	pMinutes = m;
}


//
//  add minutes to a Time
//
void Time :: addMinutes(int m)
{
	pMinutes += m;
	
	// check addition limits
	while (pMinutes >= 60) {					// minute + limit
		pMinutes -= 60;
		pHours++;
		
		if (pHours == 24) {
			pHours = 0;							// loop hours
		}
	}
	
	// check subtraction limits
	while (pMinutes < 0) {						// minute - limit
		pMinutes += 60;
		pHours--;
		
		if (pHours == -1) {						// loop hours
			pHours = 23;
		}
	}
}


//
//  print a schedule for the period starting at time start,
//  with [numberOfappts] entries, [apptLength] minutes apart.
//
void printSchedule (Time start, int apptLength, int numberOfAppts)
{
	
	for (int i = 0; i < numberOfAppts; i++) {
		cout << start;
		cout << "____________________\n";
		start = start + apptLength;
	}
	
}


//
//	print schedule, starting at 9:30 AM
//
int main()
{
	printSchedule( Time(9, 30), 30, 7 );
	
	exit(0);
}